Skip to content

Commit

Permalink
Merge pull request #5568 from gsmet/fix-jaxb-no-root-element
Browse files Browse the repository at this point in the history
Fix various JAXB issues
  • Loading branch information
gsmet authored Nov 19, 2019
2 parents 2d28a0c + be94bd7 commit a366ccd
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

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;
import java.util.Collection;
import java.util.List;
import java.util.stream.Stream;

Expand Down Expand Up @@ -49,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;
Expand All @@ -61,8 +64,8 @@
import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem;

class JaxbProcessor {
private static final List<Class<?>> JAXB_REFLECTIVE_CLASSES = Arrays.asList(
XmlAccessOrder.class,

private static final List<Class<? extends Annotation>> JAXB_ANNOTATIONS = Arrays.asList(
XmlAccessorType.class,
XmlAnyAttribute.class,
XmlAnyElement.class,
Expand Down Expand Up @@ -95,6 +98,9 @@ class JaxbProcessor {
XmlJavaTypeAdapter.class,
XmlJavaTypeAdapters.class);

private static final List<Class<?>> JAXB_REFLECTIVE_CLASSES = Arrays.asList(
XmlAccessOrder.class);

private static final List<String> JAXB_SERIALIZERS = Arrays.asList(
"html",
"text",
Expand All @@ -106,8 +112,9 @@ 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<DotName> REGISTER_TYPE_FOR_REFLECTION_ANNOTATIONS = Arrays.asList(XML_TYPE, XML_REGISTRY);
private static final List<DotName> JAXB_ROOT_ANNOTATIONS = Arrays.asList(XML_ROOT_ELEMENT, XML_TYPE, XML_REGISTRY);

@Inject
BuildProducer<ReflectiveClassBuildItem> reflectiveClass;
Expand All @@ -123,31 +130,30 @@ class JaxbProcessor {
@BuildStep
void process(BuildProducer<NativeImageSystemPropertyBuildItem> nativeImageProps,
BuildProducer<ServiceProviderBuildItem> providerItem,
BuildProducer<NativeImageProxyDefinitionBuildItem> proxyDefinitions,
CombinedIndexBuildItem combinedIndexBuildItem,
List<JaxbFileRootBuildItem> fileRoots) {

IndexView index = combinedIndexBuildItem.getIndex();

Collection<AnnotationInstance> 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) {
Expand Down Expand Up @@ -176,9 +182,20 @@ void process(BuildProducer<NativeImageSystemPropertyBuildItem> 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(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")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 extends Annotation> 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 {

Expand Down

0 comments on commit a366ccd

Please sign in to comment.