Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix JAXB unmarshalling error when compiling to native #37643

Merged
merged 1 commit into from
Jan 12, 2024

Conversation

rysurd
Copy link
Contributor

@rysurd rysurd commented Dec 10, 2023

Fix #36479

The root cause was that not all classes annotated with Jaxb annotations were marked for reflection when using native compilation, in case there we have fields that are declared in parent classes. The fix made was to replace the ReflectiveClassBuildItem from JaxbProcessor with ReflectiveHierarchyBuildItem in order to mark inherited fields for native compilation.

There is a warning throw stating that some classes are not indexed via Jandex. If anyone know how to fix this don't hesitate to tell me ! I have added the jandex maven plugins as documented in the Quarkus doc but it changes nothing. For instance :

[WARNING] [io.quarkus.deployment.steps.ReflectiveHierarchyStep] Unable to properly register the hierarchy of the following classes for reflection as they are not in the Jandex index:
        - com.sun.istack.FinalArrayList (source: JaxbProcessor > jakarta.xml.bind.annotation.XmlAccessorType)
        - com.sun.org.apache.xerces.internal.impl.dv.xs.SchemaDVFactoryImpl (source: JaxbProcessor > com.sun.org.apache.xerces.internal.impl.dv.xs.SchemaDVFactoryImpl)
        - com.sun.org.apache.xpath.internal.functions.FuncNot (source: JaxbProcessor > com.sun.org.apache.xpath.internal.functions.FuncNot)
        - com.sun.xml.internal.stream.XMLInputFactoryImpl (source: JaxbProcessor > com.sun.xml.internal.stream.XMLInputFactoryImpl)
        - com.sun.xml.internal.stream.XMLOutputFactoryImpl (source: JaxbProcessor > com.sun.xml.internal.stream.XMLOutputFactoryImpl)
        - jakarta.activation.MimeType (source: JaxbProcessor > jakarta.xml.bind.annotation.XmlAccessorType)
        - javax.xml.namespace.QName (source: JaxbProcessor > jakarta.xml.bind.annotation.XmlAccessorType)
        - org.glassfish.jaxb.core.v2.model.annotation.AnnotationReader (source: JaxbProcessor > jakarta.xml.bind.annotation.XmlAccessorType)
        - org.glassfish.jaxb.core.v2.model.annotation.Locatable (source: JaxbProcessor > jakarta.xml.bind.annotation.XmlAccessorType)
        - org.glassfish.jaxb.core.v2.model.core.Adapter (source: JaxbProcessor > jakarta.xml.bind.annotation.XmlAccessorType)
        - org.glassfish.jaxb.core.v2.model.core.BuiltinLeafInfo (source: JaxbProcessor > jakarta.xml.bind.annotation.XmlAccessorType)
        - org.glassfish.jaxb.core.v2.model.core.ClassInfo (source: JaxbProcessor > jakarta.xml.bind.annotation.XmlAccessorType)
        - org.glassfish.jaxb.core.v2.model.core.Element (source: JaxbProcessor > jakarta.xml.bind.annotation.XmlAccessorType)
        - org.glassfish.jaxb.core.v2.model.core.ElementInfo (source: JaxbProcessor > jakarta.xml.bind.annotation.XmlAccessorType)
        - org.glassfish.jaxb.core.v2.model.core.ElementPropertyInfo (source: JaxbProcessor > jakarta.xml.bind.annotation.XmlAccessorType)
        - org.glassfish.jaxb.core.v2.model.core.EnumLeafInfo (source: JaxbProcessor > jakarta.xml.bind.annotation.XmlAccessorType)
        - org.glassfish.jaxb.core.v2.model.core.ErrorHandler (source: JaxbProcessor > jakarta.xml.bind.annotation.XmlAccessorType)
        - org.glassfish.jaxb.core.v2.model.core.ID (source: JaxbProcessor > jakarta.xml.bind.annotation.XmlAccessorType)
        - org.glassfish.jaxb.core.v2.model.core.NonElement (source: JaxbProcessor > jakarta.xml.bind.annotation.XmlAccessorType)
        - org.glassfish.jaxb.core.v2.model.core.PropertyInfo (source: JaxbProcessor > jakarta.xml.bind.annotation.XmlAccessorType)
        - org.glassfish.jaxb.core.v2.model.core.PropertyKind (source: JaxbProcessor > jakarta.xml.bind.annotation.XmlAccessorType)
        - org.glassfish.jaxb.core.v2.model.core.TypeInfo (source: JaxbProcessor > jakarta.xml.bind.annotation.XmlAccessorType)
        - org.glassfish.jaxb.core.v2.model.core.TypeInfoSet (source: JaxbProcessor > jakarta.xml.bind.annotation.XmlAccessorType)
        - org.glassfish.jaxb.core.v2.model.core.WildcardMode (source: JaxbProcessor > jakarta.xml.bind.annotation.XmlAccessorType)
        - org.glassfish.jaxb.core.v2.model.nav.Navigator (source: JaxbProcessor > jakarta.xml.bind.annotation.XmlAccessorType)
        - org.glassfish.jaxb.core.v2.runtime.IllegalAnnotationException (source: JaxbProcessor > jakarta.xml.bind.annotation.XmlAccessorType)
        - org.glassfish.jaxb.core.v2.runtime.Location (source: JaxbProcessor > jakarta.xml.bind.annotation.XmlAccessorType)
        - org.glassfish.jaxb.core.v2.runtime.RuntimeUtil$ToStringAdapter (source: JaxbProcessor > org.glassfish.jaxb.core.v2.runtime.RuntimeUtil$ToStringAdapter)
        - org.xml.sax.Locator (source: JaxbProcessor > jakarta.xml.bind.annotation.XmlAccessorType)
Consider adding them to the index either by creating a Jandex index for your dependency via the Maven plugin, an empty META-INF/beans.xml or quarkus.index-dependency properties.

@rysurd
Copy link
Contributor Author

rysurd commented Dec 10, 2023

@gsmet @zakkak Hello ! I have opened the PR for the jaxb unmarshalling error. I included an integration test which reproduce the same issue and check if it works or not.

Copy link
Member

@gsmet gsmet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for having a look at this. I think we need to be more careful about when we use the hierachy feature: it should only be used on domain classes that will be serialized with JAXB, not on everything that was declared for reflection.
That's why you end up with all these warnings.

You can have a closer look if you want or I can have a look if you prefer, let me know.

In any case, it's nice to have a test case as we will be able to test that everything is fine if we make adjustments.

Comment on lines 239 to 245
String className = xmlJavaTypeAdapterInstance.value().asClass().name().toString();
Type jandexType = Type.create(DotName.createSimple(className), Type.Kind.CLASS);
reflectiveClass.produce(new ReflectiveHierarchyBuildItem.Builder()
.type(jandexType)
.index(index)
.source(getClass().getSimpleName() + " > " + jandexType.name().toString())
.build());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My guess is that this change should be reverted and that's probably what causes the warnings.

@@ -274,7 +288,7 @@ void ignoreWarnings(BuildProducer<ReflectiveHierarchyIgnoreWarningBuildItem> ign
void registerClasses(
BuildProducer<NativeImageSystemPropertyBuildItem> nativeImageProps,
BuildProducer<ServiceProviderBuildItem> providerItem,
BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
BuildProducer<ReflectiveHierarchyBuildItem> reflectiveClass,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My guess is that this change should be reverted and that's probably what causes the warnings.

private void addReflectiveClass(BuildProducer<ReflectiveClassBuildItem> reflectiveClass, boolean methods, boolean fields,
String... className) {
reflectiveClass.produce(new ReflectiveClassBuildItem(methods, fields, className));
private void addReflectiveClass(BuildProducer<ReflectiveHierarchyBuildItem> reflectiveClass, boolean methods,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The call sites of this method would have to checked. I'm really not sure it makes sense to replace it in all cases (and might not even be necessary depending on when it's called).

Comment on lines 73 to 85
<!-- The entity classes needs to be indexed -->
<plugin>
<groupId>io.smallrye</groupId>
<artifactId>jandex-maven-plugin</artifactId>
<executions>
<execution>
<id>make-index</id>
<goals>
<goal>jandex</goal>
</goals>
</execution>
</executions>
</plugin>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed? The entity classes should be in the app, not in the extension, shouldn't they?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was an attempt to resolve the jandex issue but I think that's not the way to go indeed.

@rysurd rysurd force-pushed the ISSUES-36479 branch 3 times, most recently from 53c1424 to 9266f7f Compare December 12, 2023 13:14
@rysurd
Copy link
Contributor Author

rysurd commented Dec 12, 2023

Thanks for having a look at this. I think we need to be more careful about when we use the hierachy feature: it should only be used on domain classes that will be serialized with JAXB, not on everything that was declared for reflection. That's why you end up with all these warnings.

You can have a closer look if you want or I can have a look if you prefer, let me know.

In any case, it's nice to have a test case as we will be able to test that everything is fine if we make adjustments.

Thanks for your review! I did some changes according to your inputs but I still got the warning, even if now there are only jaxb classes involved. If you don't mind I would not say no to a little help to troubleshoot this ... :D Thanks a lot again!

EDIT : Found the issue :) I added a logic to filter out the JAXB classes themselves when looping over annotated classes. This is done so we only use the hierarchybuilditem on domain classes only, excluding JAXB's ones.

@gsmet
Copy link
Member

gsmet commented Dec 12, 2023

I will have a look later this week. Thanks for pursuing this.

@rysurd rysurd force-pushed the ISSUES-36479 branch 6 times, most recently from 652785f to e8cb980 Compare December 16, 2023 14:23
@rysurd
Copy link
Contributor Author

rysurd commented Dec 16, 2023

@gsmet I think I resolved the issue with the Jandex warning ... Build seems ok now (No specific warnings or errors) so maybe if you have some time could you check on this please ? 😄 The integration test seems to do its job too as it failed (throwing the original issue) when using the main branch codebase and succeed when I use the fix.

Edit : Any chance to check this @gsmet ? (happy new year too 😄)

@rysurd rysurd force-pushed the ISSUES-36479 branch 5 times, most recently from d982b89 to 239859d Compare December 20, 2023 09:11
@rysurd rysurd force-pushed the ISSUES-36479 branch 2 times, most recently from dff06b9 to 6103261 Compare January 2, 2024 10:16
@rysurd rysurd force-pushed the ISSUES-36479 branch 2 times, most recently from 39e0f3e to cc9c530 Compare January 10, 2024 10:16
Copy link
Member

@gsmet gsmet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rysurd sorry for the delay, your latest changes look good.

I made some very small changes to make it more consistent with code we already had in the tree but these were really micro changes.

Let's see what CI has to say and merge!

@gsmet gsmet added the triage/waiting-for-ci Ready to merge when CI successfully finishes label Jan 12, 2024
@gsmet gsmet changed the title Fixing Jaxb unmarshalling error with native compilation Fix JAXB unmarshalling error when compiling to native Jan 12, 2024
Copy link

quarkus-bot bot commented Jan 12, 2024

✔️ The latest workflow run for the pull request has completed successfully.

It should be safe to merge provided you have a look at the other checks in the summary.

You can consult the Develocity build scans.

@gsmet gsmet merged commit f3ffc50 into quarkusio:main Jan 12, 2024
24 checks passed
@quarkus-bot quarkus-bot bot added this to the 3.7 - main milestone Jan 12, 2024
@quarkus-bot quarkus-bot bot added kind/bugfix and removed triage/waiting-for-ci Ready to merge when CI successfully finishes labels Jan 12, 2024
@gsmet
Copy link
Member

gsmet commented Jan 12, 2024

Merged, thanks for your contribution!

@rysurd
Copy link
Contributor Author

rysurd commented Jan 12, 2024

Merged, thanks for your contribution!

Thanks !

@gsmet gsmet modified the milestones: 3.7 - main, 3.6.6 Jan 15, 2024
@ppalaga
Copy link
Contributor

ppalaga commented Jan 16, 2024

This change breaks both Quarkus CXF and Camel Quarkus - see apache/camel-quarkus#5650
I am checking whether we need to revert or whether there is a some way to keep the test in this PR working.

@gsmet
Copy link
Member

gsmet commented Jan 16, 2024

@ppalaga I created https://github.com/quarkusio/quarkus/pull/38217/files that, I think, should mitigate the issues you're having. Let me know how it goes.

@rysurd
Copy link
Contributor Author

rysurd commented Jan 16, 2024

Ah, sorry I should have catched that the extent of these changes would reach also into other libs ...

@ppalaga
Copy link
Contributor

ppalaga commented Jan 16, 2024

#36479 complained about ancestors of a JAXB class not being registered for reflection. The current change does much more, because ReflectiveHierarchyBuildItem does much more: it registers not only ancestors, but also all field types, type parameters, etc.
I'd vote for having a much more conservative fix that just climbs up the supertypes and registers those. A PR follows.

@ppalaga
Copy link
Contributor

ppalaga commented Jan 16, 2024

Here is my proposal: #38221

@ppalaga
Copy link
Contributor

ppalaga commented Jan 16, 2024

@rysurd @turing85 could you perhaps check that #38221 fixes your original issue?

@turing85
Copy link
Contributor

@ppalaga Seems to work 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

JAXB unmarshalling fails in native mode
4 participants