From a3f31973995ac655616f7c1254d2094000cb233b Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Mon, 18 Nov 2019 16:34:57 +0100 Subject: [PATCH 1/3] Also consider XmlType as triggering the JAXB inclusion XmlRootElement is optional so we need to trigger the JAXB inclusion with XmlType too. --- .../jaxb/deployment/JaxbProcessor.java | 30 +++++++++---------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/JaxbProcessor.java b/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/JaxbProcessor.java index 4716f953db71e..16122a3651d69 100644 --- a/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/JaxbProcessor.java +++ b/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/JaxbProcessor.java @@ -5,7 +5,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; -import java.util.Collection; import java.util.List; import java.util.stream.Stream; @@ -61,6 +60,7 @@ import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem; class JaxbProcessor { + private static final List> JAXB_REFLECTIVE_CLASSES = Arrays.asList( XmlAccessOrder.class, XmlAccessorType.class, @@ -107,7 +107,7 @@ class JaxbProcessor { private static final DotName XML_SCHEMA = DotName.createSimple(XmlSchema.class.getName()); private static final DotName XML_JAVA_TYPE_ADAPTER = DotName.createSimple(XmlJavaTypeAdapter.class.getName()); - private static final List REGISTER_TYPE_FOR_REFLECTION_ANNOTATIONS = Arrays.asList(XML_TYPE, XML_REGISTRY); + private static final List JAXB_ROOT_ANNOTATIONS = Arrays.asList(XML_ROOT_ELEMENT, XML_TYPE, XML_REGISTRY); @Inject BuildProducer reflectiveClass; @@ -128,26 +128,24 @@ void process(BuildProducer nativeImageProps, IndexView index = combinedIndexBuildItem.getIndex(); - Collection xmlRootElementInstances = index.getAnnotations(XML_ROOT_ELEMENT); - for (AnnotationInstance xmlRootElementInstance : xmlRootElementInstances) { - addReflectiveClass(true, true, xmlRootElementInstance.target().asClass().name().toString()); - } - if (xmlRootElementInstances.isEmpty() && - fileRoots.isEmpty()) { - return; - } - // Register classes for reflection based on JAXB annotations - for (DotName registerTypeAnnotation : REGISTER_TYPE_FOR_REFLECTION_ANNOTATIONS) { - for (AnnotationInstance registerTypeForReflectionAnnotationInstance : index - .getAnnotations(registerTypeAnnotation)) { - if (registerTypeForReflectionAnnotationInstance.target().kind() == Kind.CLASS) { + boolean jaxbRootAnnotationsDetected = false; + + for (DotName jaxbRootAnnotation : JAXB_ROOT_ANNOTATIONS) { + for (AnnotationInstance jaxbRootAnnotationInstance : index + .getAnnotations(jaxbRootAnnotation)) { + if (jaxbRootAnnotationInstance.target().kind() == Kind.CLASS) { addReflectiveClass(true, true, - registerTypeForReflectionAnnotationInstance.target().asClass().name().toString()); + jaxbRootAnnotationInstance.target().asClass().name().toString()); + jaxbRootAnnotationsDetected = true; } } } + if (!jaxbRootAnnotationsDetected && fileRoots.isEmpty()) { + return; + } + // Register package-infos for reflection for (AnnotationInstance xmlSchemaInstance : index.getAnnotations(XML_SCHEMA)) { if (xmlSchemaInstance.target().kind() == Kind.CLASS) { From daec663d06ff028133127243d4afeefec40a3ee6 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Mon, 18 Nov 2019 16:36:06 +0100 Subject: [PATCH 2/3] Remove the substitution for LocatableAnnotation and register proxies This implementation is important and used by JAXB. We just need to register proxies for the combinations of JAXB annotations and Locatable. --- .../jaxb/deployment/JaxbProcessor.java | 20 +++++++++++--- .../jaxb/runtime/graal/JAXBSubstitutions.java | 27 ------------------- 2 files changed, 17 insertions(+), 30 deletions(-) diff --git a/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/JaxbProcessor.java b/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/JaxbProcessor.java index 16122a3651d69..0392dd5074205 100644 --- a/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/JaxbProcessor.java +++ b/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/JaxbProcessor.java @@ -2,6 +2,7 @@ import java.io.IOError; import java.io.IOException; +import java.lang.annotation.Annotation; import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; @@ -48,10 +49,13 @@ import org.jboss.jandex.DotName; import org.jboss.jandex.IndexView; +import com.sun.xml.bind.v2.model.annotation.Locatable; + import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.builditem.ApplicationArchivesBuildItem; import io.quarkus.deployment.builditem.CombinedIndexBuildItem; +import io.quarkus.deployment.builditem.nativeimage.NativeImageProxyDefinitionBuildItem; import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem; import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBundleBuildItem; import io.quarkus.deployment.builditem.nativeimage.NativeImageSystemPropertyBuildItem; @@ -61,8 +65,7 @@ class JaxbProcessor { - private static final List> JAXB_REFLECTIVE_CLASSES = Arrays.asList( - XmlAccessOrder.class, + private static final List> JAXB_ANNOTATIONS = Arrays.asList( XmlAccessorType.class, XmlAnyAttribute.class, XmlAnyElement.class, @@ -95,6 +98,9 @@ class JaxbProcessor { XmlJavaTypeAdapter.class, XmlJavaTypeAdapters.class); + private static final List> JAXB_REFLECTIVE_CLASSES = Arrays.asList( + XmlAccessOrder.class); + private static final List JAXB_SERIALIZERS = Arrays.asList( "html", "text", @@ -123,6 +129,7 @@ class JaxbProcessor { @BuildStep void process(BuildProducer nativeImageProps, BuildProducer providerItem, + BuildProducer proxyDefinitions, CombinedIndexBuildItem combinedIndexBuildItem, List fileRoots) { @@ -176,7 +183,14 @@ void process(BuildProducer nativeImageProps, JAXB_REFLECTIVE_CLASSES.stream() .map(Class::getName) - .forEach(clazz -> addReflectiveClass(true, false, clazz)); + .forEach(className -> addReflectiveClass(true, false, className)); + + JAXB_ANNOTATIONS.stream() + .map(Class::getName) + .forEach(className -> { + proxyDefinitions.produce(new NativeImageProxyDefinitionBuildItem(className, Locatable.class.getName())); + addReflectiveClass(true, false, className); + }); JAXB_SERIALIZERS.stream() .map(s -> "com/sun/org/apache/xml/internal/serializer/output_" + s + ".properties") diff --git a/extensions/jaxb/runtime/src/main/java/io/quarkus/jaxb/runtime/graal/JAXBSubstitutions.java b/extensions/jaxb/runtime/src/main/java/io/quarkus/jaxb/runtime/graal/JAXBSubstitutions.java index 2d171bda8ceea..4d8e405ece072 100644 --- a/extensions/jaxb/runtime/src/main/java/io/quarkus/jaxb/runtime/graal/JAXBSubstitutions.java +++ b/extensions/jaxb/runtime/src/main/java/io/quarkus/jaxb/runtime/graal/JAXBSubstitutions.java @@ -8,33 +8,6 @@ import com.oracle.svm.core.annotate.Substitute; import com.oracle.svm.core.annotate.TargetClass; -@TargetClass(className = "com.sun.xml.bind.v2.model.annotation.LocatableAnnotation", onlyWith = Target_com_sun_xml_bind_v2_model_annotation_LocatableAnnotation.Selector.class) -final class Target_com_sun_xml_bind_v2_model_annotation_LocatableAnnotation { - - @Substitute - public static A create(A annotation, Locatable parentSourcePos) { - return annotation; - } - - @TargetClass(className = "com.sun.xml.bind.v2.model.annotation.Locatable", onlyWith = Target_com_sun_xml_bind_v2_model_annotation_LocatableAnnotation.Selector.class) - static final class Locatable { - - } - - static final class Selector implements BooleanSupplier { - - @Override - public boolean getAsBoolean() { - try { - Class.forName("com.sun.xml.bind.v2.model.annotation.LocatableAnnotation"); - return true; - } catch (ClassNotFoundException e) { - return false; - } - } - } -} - @TargetClass(className = "com.sun.xml.bind.v2.model.nav.ReflectionNavigator", onlyWith = Target_com_sun_xml_bind_v2_model_nav_ReflectionNavigator.Selector.class) final class Target_com_sun_xml_bind_v2_model_nav_ReflectionNavigator { From be94bd7e6660b0f96536b2e83299d1ad453e1fa3 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Mon, 18 Nov 2019 16:42:52 +0100 Subject: [PATCH 3/3] Register W3CDomHandler if we have a @XmlAnyElement annotation --- .../main/java/io/quarkus/jaxb/deployment/JaxbProcessor.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/JaxbProcessor.java b/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/JaxbProcessor.java index 0392dd5074205..722aeb05b54bb 100644 --- a/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/JaxbProcessor.java +++ b/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/JaxbProcessor.java @@ -112,6 +112,7 @@ class JaxbProcessor { private static final DotName XML_REGISTRY = DotName.createSimple(XmlRegistry.class.getName()); private static final DotName XML_SCHEMA = DotName.createSimple(XmlSchema.class.getName()); private static final DotName XML_JAVA_TYPE_ADAPTER = DotName.createSimple(XmlJavaTypeAdapter.class.getName()); + private static final DotName XML_ANY_ELEMENT = DotName.createSimple(XmlAnyElement.class.getName()); private static final List JAXB_ROOT_ANNOTATIONS = Arrays.asList(XML_ROOT_ELEMENT, XML_TYPE, XML_REGISTRY); @@ -181,6 +182,10 @@ void process(BuildProducer nativeImageProps, nativeImageProps .produce(new NativeImageSystemPropertyBuildItem("com.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize", "true")); + if (!index.getAnnotations(XML_ANY_ELEMENT).isEmpty()) { + addReflectiveClass(false, false, "javax.xml.bind.annotation.W3CDomHandler"); + } + JAXB_REFLECTIVE_CLASSES.stream() .map(Class::getName) .forEach(className -> addReflectiveClass(true, false, className));