diff --git a/contribs/scala/jersey-lift/pom.xml b/contribs/scala/jersey-lift/pom.xml index 46b45673d..aecf69c02 100644 --- a/contribs/scala/jersey-lift/pom.xml +++ b/contribs/scala/jersey-lift/pom.xml @@ -153,7 +153,7 @@ net.liftweb - lift-webkit + lift-mapper_2.11 ${lift.version} diff --git a/contribs/scala/jersey-scala/pom.xml b/contribs/scala/jersey-scala/pom.xml index 88d15aa76..31c689c63 100644 --- a/contribs/scala/jersey-scala/pom.xml +++ b/contribs/scala/jersey-scala/pom.xml @@ -167,7 +167,7 @@ org.scala-tools maven-scala-plugin - 2.10.1 + 2.15.2 diff --git a/contribs/scala/pom.xml b/contribs/scala/pom.xml index 26e1067e5..bc810faf6 100644 --- a/contribs/scala/pom.xml +++ b/contribs/scala/pom.xml @@ -58,8 +58,8 @@ 6.1.19 - 1.1-M7 - 2.7.5 + 2.6 + 2.11.5 @@ -77,7 +77,7 @@ org.scala-tools maven-scala-plugin - 2.10.1 + 2.15.2 @@ -93,7 +93,6 @@ -deprecation - -Xno-varargs-conversion ${scala.version} diff --git a/contribs/wadl-resourcedoc-doclet/src/main/java/com/sun/jersey/wadl/resourcedoc/DocProcessor.java b/contribs/wadl-resourcedoc-doclet/src/main/java/com/sun/jersey/wadl/resourcedoc/DocProcessor.java index b6c205d32..b18f477a6 100644 --- a/contribs/wadl-resourcedoc-doclet/src/main/java/com/sun/jersey/wadl/resourcedoc/DocProcessor.java +++ b/contribs/wadl-resourcedoc-doclet/src/main/java/com/sun/jersey/wadl/resourcedoc/DocProcessor.java @@ -87,7 +87,7 @@ public interface DocProcessor { void processClassDoc( ClassDoc classDoc, ClassDocType classDocType ); /** - * Process the provided methodDoc and add your custom information to the methodDocType.
+ * Process the provided methodDoc and add your custom information to the methodDocType.
* Use e.g. {@link MethodDocType#getAny()} to store custom elements. * @param methodDoc the {@link MethodDoc} representing the docs of your method. * @param methodDocType the related {@link MethodDocType} that will later be processed by the {@link WadlGenerator}s. diff --git a/jersey-core/src/main/java/com/sun/jersey/core/spi/component/ioc/IoCComponentProviderFactory.java b/jersey-core/src/main/java/com/sun/jersey/core/spi/component/ioc/IoCComponentProviderFactory.java index 321570dbd..4638450f8 100644 --- a/jersey-core/src/main/java/com/sun/jersey/core/spi/component/ioc/IoCComponentProviderFactory.java +++ b/jersey-core/src/main/java/com/sun/jersey/core/spi/component/ioc/IoCComponentProviderFactory.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) 2010-2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development @@ -58,7 +58,7 @@ * If the component is not supported then a null value may be returned and the * runtime will manage the component. *

- * Specializations of {@link IoCComponentProvider} must be returned by the + * Specializations of {@link IoCComponentProvider} must be returned by the * getComponentProvider methods that declare the boundary of * responsibility, between the runtime and the underlying IoC framework, * for management of a component. @@ -77,7 +77,7 @@ * component is fully managed by the runtime but when an instance is created * the underlying IoC framework is deferred to for creating a proxy of the * component instance. - * + * * @author Paul.Sandoz@Sun.Com */ public interface IoCComponentProviderFactory extends ComponentProviderFactory { diff --git a/jersey-core/src/main/java/com/sun/jersey/core/spi/component/ioc/IoCProviderFactory.java b/jersey-core/src/main/java/com/sun/jersey/core/spi/component/ioc/IoCProviderFactory.java index 4f648cccf..2e3336c5e 100644 --- a/jersey-core/src/main/java/com/sun/jersey/core/spi/component/ioc/IoCProviderFactory.java +++ b/jersey-core/src/main/java/com/sun/jersey/core/spi/component/ioc/IoCProviderFactory.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) 2010-2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development @@ -44,8 +44,12 @@ import com.sun.jersey.core.spi.component.ComponentProvider; import com.sun.jersey.core.spi.component.ComponentScope; import com.sun.jersey.core.spi.component.ProviderFactory; +import com.sun.jersey.core.util.PriorityUtil; import com.sun.jersey.spi.inject.InjectableProviderContext; + import java.lang.reflect.InvocationTargetException; + +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.logging.Level; @@ -53,13 +57,29 @@ /** * An extension of {@link ProviderFactory} that defers to an * {@link IoCComponentProviderFactory}. - * - * @author Paul.Sandoz@Sun.Com + * + * All registered provider factory implementations are being polled + * so that a single {@link IoCComponentProvider} instance could be selected + * for each component. + * + * @author Paul Sandoz (paul.sandoz at oracle.com) */ public class IoCProviderFactory extends ProviderFactory { + + /* + The following would be added to the class javadoc if the priority annotation + was part of public API: + + Polling order is specified by priority value + set on individual provider factories. The factory that has the highest + priority value is polled first. Priority value is set using + {@link Priority} annotation. + */ private final List factories; /** + * Create a new provider factory based + * on given context and factory. * * @param ipc the injectable provider context. * @param icpf the IoC component provider factory. @@ -71,6 +91,7 @@ public IoCProviderFactory( } /** + * Create a new provider factory based on given context and factories. * * @param ipc the injectable provider context. * @param factories the list of IoC component provider factory. @@ -79,7 +100,9 @@ public IoCProviderFactory( InjectableProviderContext ipc, List factories) { super(ipc); - this.factories = factories; + List myFactories = new ArrayList(factories); + Collections.sort(myFactories, PriorityUtil.INSTANCE_COMPARATOR); + this.factories = Collections.unmodifiableList(myFactories); } @Override @@ -123,7 +146,7 @@ private static class InstantiatedSingleton implements ComponentProvider, Destroy private final Object o; private final IoCDestroyable destroyable; - + private final ComponentDestructor cd; InstantiatedSingleton(InjectableProviderContext ipc, @@ -131,7 +154,7 @@ private static class InstantiatedSingleton implements ComponentProvider, Destroy Class c) { this.destroyable = (iicp instanceof IoCDestroyable) ? (IoCDestroyable) iicp : null; - + o = iicp.getInstance(); this.cd = (destroyable == null) ? new ComponentDestructor(c) : null; @@ -210,7 +233,7 @@ private static class ProxiedSingletonWrapper implements ComponentProvider, Destr this.destroyable = (cp instanceof Destroyable) ? (Destroyable) cp : null; - + Object o = cp.getInstance(); this.proxy = ipcp.proxy(o); if (!this.proxy.getClass().isAssignableFrom(o.getClass())) diff --git a/jersey-core/src/main/java/com/sun/jersey/core/util/Priority.java b/jersey-core/src/main/java/com/sun/jersey/core/util/Priority.java new file mode 100644 index 000000000..49a0aa265 --- /dev/null +++ b/jersey-core/src/main/java/com/sun/jersey/core/util/Priority.java @@ -0,0 +1,68 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * http://glassfish.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package com.sun.jersey.core.util; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static java.lang.annotation.ElementType.TYPE; + + +/** + * Priority annotation can be applied to provider classes + * to indicate in what order the providers should be polled. + * Concrete usage must be defined by individual provider specification. + * + * Introduced to help control component factory ordering. + * + * @author Jakub Podlesak (jakub.podlesak at oracle.com) + */ +@Target(value=TYPE) +@Retention(value=RUNTIME) +public @interface Priority { + + /** + * The priority value. + * + * @return priority value to be used for annotated element. + */ + public int value(); +} \ No newline at end of file diff --git a/jersey-core/src/main/java/com/sun/jersey/core/util/PriorityUtil.java b/jersey-core/src/main/java/com/sun/jersey/core/util/PriorityUtil.java new file mode 100644 index 000000000..c29a9dd1f --- /dev/null +++ b/jersey-core/src/main/java/com/sun/jersey/core/util/PriorityUtil.java @@ -0,0 +1,96 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * http://glassfish.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package com.sun.jersey.core.util; + +import java.util.Comparator; + +/** + * Utility code for work with {@link Priority} annotated types. + * + * @author Jakub Podlesak (jakub.podlesak at oracle.com) + */ +public class PriorityUtil { + + /** + * Default priority value for factory types that do not have + * their priority set explicitly using {@link Priority} annotation. + */ + public static final int DEFAULT_PRIORITY = 100; + + /** + * Convenience comparator instance. + */ + public static final InstanceComparator INSTANCE_COMPARATOR = new InstanceComparator(); + + /** + * Comparator for instances of types annotated with Priority + * annotation. + */ + public static final class InstanceComparator implements Comparator { + + @Override + public int compare(Object o1, Object o2) { + return priorityOf(o2) - priorityOf(o1); + } + + private int priorityOf(Object o) { + final Priority priorityAnnotation = o.getClass().getAnnotation(Priority.class); + return priorityAnnotation == null ? DEFAULT_PRIORITY : priorityAnnotation.value(); + } + } + + /** + * Comparator for types annotated with Priority + * annotation. + */ + public static class TypeComparator implements Comparator> { + + @Override + public int compare(Class o1, Class o2) { + return priorityOf(o2) - priorityOf(o1); + } + + private int priorityOf(Class o) { + final Priority priorityAnnotation = o.getAnnotation(Priority.class); + return priorityAnnotation == null ? DEFAULT_PRIORITY : priorityAnnotation.value(); + } + } +} \ No newline at end of file diff --git a/jersey-core/src/test/java/com/sun/jersey/core/util/PriorityTest.java b/jersey-core/src/test/java/com/sun/jersey/core/util/PriorityTest.java new file mode 100644 index 000000000..8c81069a9 --- /dev/null +++ b/jersey-core/src/test/java/com/sun/jersey/core/util/PriorityTest.java @@ -0,0 +1,133 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * http://glassfish.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package com.sun.jersey.core.util; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.junit.Test; + +import junit.framework.Assert; + +/** + * Test priority annotation usage on types and instances. + * + * @author Jakub Podlesak (jakub.podlesak at oracle.com) + */ +public class PriorityTest { + + public static final int D_MINUS_200 = PriorityUtil.DEFAULT_PRIORITY - 200; + public static final int D_PLUS_300 = PriorityUtil.DEFAULT_PRIORITY + 300; + public static final int D_PLUS_400 = PriorityUtil.DEFAULT_PRIORITY + 400; + + public PriorityTest() { + } + + public static interface Base { + int getPriority(); + } + + @Priority(D_MINUS_200) + public static class A implements Base { + + @Override + public int getPriority() { + return D_MINUS_200; + } + } + + public static class B implements Base { + + @Override + public int getPriority() { + return PriorityUtil.DEFAULT_PRIORITY; + } + } + + @Priority(D_PLUS_300) + public static class C implements Base { + + @Override + public int getPriority() { + return D_PLUS_300; + } + } + + @Priority(D_PLUS_400) + public static class D implements Base { + + @Override + public int getPriority() { + return D_PLUS_400; + } + } + + /** + * Test the priority comparator. + */ + @Test + public void testOrdering() { + + Base a = new A(); + Base b = new B(); + Base c = new C(); + Base d = new D(); + + List l1 = new ArrayList(); + + l1.add(d); + l1.add(c); + l1.add(b); + l1.add(a); + + for (int i=0; i<20; i++) { + Collections.shuffle(l1); + Collections.sort(l1, PriorityUtil.INSTANCE_COMPARATOR); + int p = Integer.MAX_VALUE; + for (Base e : l1) { + if (e.getPriority() > p) { + Assert.fail("Wrong order of list " + l1); + } + p = e.getPriority(); + } + } + } +} diff --git a/jersey-server/src/main/java/com/sun/jersey/server/impl/component/IoCResourceFactory.java b/jersey-server/src/main/java/com/sun/jersey/server/impl/component/IoCResourceFactory.java index ae82972cf..a52dcd8bb 100644 --- a/jersey-server/src/main/java/com/sun/jersey/server/impl/component/IoCResourceFactory.java +++ b/jersey-server/src/main/java/com/sun/jersey/server/impl/component/IoCResourceFactory.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) 2010-2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development @@ -48,25 +48,33 @@ import com.sun.jersey.core.spi.component.ioc.IoCManagedComponentProvider; import com.sun.jersey.core.spi.component.ComponentScope; import com.sun.jersey.core.spi.component.ioc.IoCFullyManagedComponentProvider; +import com.sun.jersey.core.util.PriorityUtil; import com.sun.jersey.server.impl.inject.ServerInjectableProviderContext; import com.sun.jersey.server.spi.component.ResourceComponentInjector; import com.sun.jersey.server.spi.component.ResourceComponentProvider; import com.sun.jersey.server.spi.component.ResourceComponentProviderFactory; + +import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** + * Factory for individual JAX-RS resources. * - * @author Paul.Sandoz@Sun.Com + * @author Paul Sandoz (paul.sandoz at oracle.com) */ public class IoCResourceFactory extends ResourceFactory { + private final List factories; - + public IoCResourceFactory( ResourceConfig config, ServerInjectableProviderContext ipc, List factories) { super(config, ipc); - this.factories = factories; + List myFactories = new ArrayList(factories); + Collections.sort(myFactories, PriorityUtil.INSTANCE_COMPARATOR); + this.factories = Collections.unmodifiableList(myFactories); } @Override @@ -124,12 +132,12 @@ public Object getInstance() { public void destroy() { } } - + private static class PerRequestWrapper implements ResourceComponentProvider { private final ServerInjectableProviderContext ipc; private final IoCManagedComponentProvider imcp; private ResourceComponentInjector rci; - + PerRequestWrapper(ServerInjectableProviderContext ipc, IoCManagedComponentProvider imcp) { this.ipc = ipc; this.imcp = imcp; diff --git a/jersey-servlet/src/main/java/com/sun/jersey/server/impl/ejb/EJBComponentProviderFactory.java b/jersey-servlet/src/main/java/com/sun/jersey/server/impl/ejb/EJBComponentProviderFactory.java index 1a3512860..eb05946ed 100644 --- a/jersey-servlet/src/main/java/com/sun/jersey/server/impl/ejb/EJBComponentProviderFactory.java +++ b/jersey-servlet/src/main/java/com/sun/jersey/server/impl/ejb/EJBComponentProviderFactory.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) 2010-2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development @@ -47,6 +47,7 @@ import com.sun.jersey.core.spi.component.ioc.IoCComponentProvider; import com.sun.jersey.core.spi.component.ioc.IoCComponentProviderFactory; import com.sun.jersey.core.spi.component.ioc.IoCFullyManagedComponentProvider; +import com.sun.jersey.core.util.Priority; import java.util.logging.Level; import java.util.logging.Logger; import javax.ejb.Singleton; @@ -55,13 +56,16 @@ import javax.naming.NamingException; /** + * Component provider factory that implements EJB support + * for GlassFish container. * - * @author Paul.Sandoz@Sun.Com + * @author Paul Sandoz (paul.sandoz at oracle.com) */ +@Priority(300) final class EJBComponentProviderFactory implements IoCComponentProviderFactory, IoCComponentProcessorFactoryInitializer { - + private static final Logger LOGGER = Logger.getLogger( EJBComponentProviderFactory.class.getName()); @@ -72,7 +76,7 @@ public EJBComponentProviderFactory(EJBInjectionInterceptor interceptor) { } // IoCComponentProviderFactory - + public IoCComponentProvider getComponentProvider(Class c) { return getComponentProvider(null, c); } @@ -154,9 +158,9 @@ public Object getInstance() { return o; } } - + // IoCComponentProcessorFactoryInitializer - + public void init(IoCComponentProcessorFactory cpf) { interceptor.setFactory(cpf); } diff --git a/jersey-servlet/src/main/java/com/sun/jersey/spi/container/servlet/ServletContainer.java b/jersey-servlet/src/main/java/com/sun/jersey/spi/container/servlet/ServletContainer.java index 9fe54dfc4..8dca6ee03 100644 --- a/jersey-servlet/src/main/java/com/sun/jersey/spi/container/servlet/ServletContainer.java +++ b/jersey-servlet/src/main/java/com/sun/jersey/spi/container/servlet/ServletContainer.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development @@ -267,6 +267,24 @@ public class ServletContainer extends HttpServlet implements Filter { public static final String PROPERTY_FILTER_CONTEXT_PATH = "com.sun.jersey.config.feature.FilterContextPath"; + /** + * If set to true then the internal Jersey CDI component provider + * will be used for managed bean types, + * that are not annotated with {@link ManagedBean} annotation (neither with any other + * bean defining annotation) and CDI bean manager + * evaluates them as dependent scoped beans. + *

+ * This feature is only applicable when CDI processing is enabled, + * i.e. when beans.xml file is present. + *

+ * This feature is an alternative to adding {@link ManagedBean} annotation + * to managed bean types directly. + *

+ * The default value is false. + */ + public static final String FEATURE_ALLOW_RAW_MANAGED_BEANS + = "com.sun.jersey.config.feature.AllowRawManagedBeans"; + /** * A helper class for creating an injectable provider that supports * {@link Context} with a type and constant value. diff --git a/samples/spring-annotations/pom.xml b/samples/spring-annotations/pom.xml index 7cead48d2..83d847949 100644 --- a/samples/spring-annotations/pom.xml +++ b/samples/spring-annotations/pom.xml @@ -106,6 +106,15 @@ 1.7.0 + + aspectjrt-jdk8 + + 1.8 + + + 1.8.0 + + xdk