Search code examples
mavenjaxbquarkusjava-17jakarta-migration

Quarkus 3.8.x Java 17 NoClassDefFoundError: javax/xml/bind/JAXBException Dependency Conflict


I have migrated from Quarkus 2.x.x to Quarkus 3.8.3, and therefore from Java 11 to Java 17, for an Apache Camel Routes application.
When trying to handle a JAXBException case, I'm met with the: NoClassDefFoundError:javax/xml/bind/JAXBException.

The necessary packages seem to be in the classpath, and the package/class is resolved and referencable in IntelliJ.

So far I've tried a plethora of different dependencies in order to amend this.
The pom.xml file is as follows:

<properties>
        <compiler-plugin.version>3.12.1</compiler-plugin.version>
        <quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
        <quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
        <quarkus.platform.version>3.8.3</quarkus.platform.version>

        <maven.compiler.release>17</maven.compiler.release>
        <maven.compiler.target>17</maven.compiler.target>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.testTarget>${maven.compiler.target}</maven.compiler.testTarget>
        <maven.compiler.testSource>${maven.compiler.source}</maven.compiler.testSource>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

        <maven-jar-plugin.version>3.3.0</maven-jar-plugin.version>
        <groovy-maven-plugin.version>2.1.1</groovy-maven-plugin.version>
        <surefire-plugin.version>3.2.5</surefire-plugin.version>

        <version.lombok>1.18.30</version.lombok>
        <version.ermis.commons>1.6.0</version.ermis.commons>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>${quarkus.platform.group-id}</groupId>
                <artifactId>${quarkus.platform.artifact-id}</artifactId>
                <version>${quarkus.platform.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>io.quarkus.platform</groupId>
                <artifactId>quarkus-camel-bom</artifactId>
                <version>${quarkus.platform.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <!--    XML and Data Format -->
        <dependency>
            <groupId>jakarta.xml.bind</groupId>
            <artifactId>jakarta.xml.bind-api</artifactId>
            <version>4.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>4.0.4</version>
        </dependency>
        <dependency>
            <groupId>javax.xml.ws</groupId>
            <artifactId>jaxws-api</artifactId>
            <version>2.3.1</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.3.4</version>
        </dependency>
        <!--  Quarkus Core  -->
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-arc</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-jaxb</artifactId>
        </dependency>
        <!--  Database  -->
        <dependency>
            <groupId>jakarta.persistence</groupId>
            <artifactId>jakarta.persistence-api</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-hibernate-orm</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-jdbc-postgresql</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-liquibase</artifactId>
        </dependency>
        <!--    Camel Quarkus Core  -->
        <dependency>
            <groupId>org.apache.camel.quarkus</groupId>
            <artifactId>camel-quarkus-bean</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.camel.quarkus</groupId>
            <artifactId>camel-quarkus-ftp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.camel.quarkus</groupId>
            <artifactId>camel-quarkus-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.camel.quarkus</groupId>
            <artifactId>camel-quarkus-sql</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.camel.quarkus</groupId>
            <artifactId>camel-quarkus-kafka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.camel.quarkus</groupId>
            <artifactId>camel-quarkus-xpath</artifactId>
        </dependency>
        <!--    Rest and JSON   -->
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-resteasy-jackson</artifactId>
        </dependency>
        <!--  Smallrye Health  -->
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-smallrye-health</artifactId>
        </dependency>
        <!--    Utility -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${version.lombok}</version>
            <scope>provided</scope>
        </dependency>
        <!--    Intrasoft Dependencies  -->
        <dependency>
            <groupId>com.intrasoft.ermis.commons</groupId>
            <artifactId>ermis-event</artifactId>
            <version>${version.ermis.commons}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.projectlombok</groupId>
                    <artifactId>lombok</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.evpav.shared.kernel</groupId>
            <artifactId>ddnta_v5.15.1</artifactId>
            <version>2.4.17</version>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.logging.log4j</groupId>
                    <artifactId>log4j-slf4j-impl</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>commons-collections</groupId>
                    <artifactId>commons-collections</artifactId>
                </exclusion>
                <exclusion>
                    <artifactId>lombok</artifactId>
                    <groupId>org.projectlombok</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.evpav.commons2</groupId>
            <artifactId>xml-common</artifactId>
            <version>2.2.0</version>
            <exclusions>
                <exclusion>
                    <groupId>org.projectlombok</groupId>
                    <artifactId>lombok</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--    Test    -->
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-junit5</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>postgresql</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-jdbc-h2</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>${quarkus.platform.group-id}</groupId>
                <artifactId>quarkus-maven-plugin</artifactId>
                <version>${quarkus.platform.version}</version>
                <extensions>true</extensions>
                <executions>
                    <execution>
                        <goals>
                            <goal>build</goal>
                            <goal>generate-code</goal>
                            <goal>generate-code-tests</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${compiler-plugin.version}</version>
                <configuration>
                    <compilerArgs>
                        <arg>-parameters</arg>
                        <arg>-Xlint:unchecked</arg>
                    </compilerArgs>
                    <showDeprecation>true</showDeprecation>
                    <showWarnings>true</showWarnings>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${surefire-plugin.version}</version>
                <configuration>
                    <systemPropertyVariables>
                        <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
                        <maven.home>${maven.home}</maven.home>
                    </systemPropertyVariables>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>${surefire-plugin.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <systemPropertyVariables>
                        <native.image.path>${project.build.directory}/${project.build.finalName}-runner
                        </native.image.path>
                        <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
                        <maven.home>${maven.home}</maven.home>
                    </systemPropertyVariables>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.gmaven</groupId>
                <artifactId>groovy-maven-plugin</artifactId>
                <version>${groovy-maven-plugin.version}</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>${maven-jar-plugin.version}</version>
            </plugin>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <version>3.2.0</version>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Import-Package>
                            org.apache.xpath.jaxp
                        </Import-Package>
                    </instructions>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <profiles>
        <profile>
            <id>native</id>
            <activation>
                <property>
                    <name>native</name>
                </property>
            </activation>
            <properties>
                <skipITs>false</skipITs>
                <quarkus.package.type>native</quarkus.package.type>
            </properties>
        </profile>
    </profiles>

The above tried with and without the quarkus-jaxb.

Also attempted with the following <!-- XML and Data Format --> section but to no avail:

        <!--    XML and Data Format -->
        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
            <version>2.13.0</version>
        </dependency>
        <!--    XML Processing  -->
        <dependency>
            <groupId>org.jdom</groupId>
            <artifactId>jdom2</artifactId>
            <version>2.0.6.1</version>
        </dependency>
        <dependency>
            <groupId>xalan</groupId>
            <artifactId>xalan</artifactId>
            <version>2.7.3</version>
        </dependency>
        <dependency>
            <groupId>xalan</groupId>
            <artifactId>serializer</artifactId>
            <version>2.7.3</version>
        </dependency>

Now the package in which the JAXBException lives and is used by my specific external dependency is javax.xml.bind:jaxb-api:2.3.1 under package javax.xml.bind;
but! we can also find the JAXBException class in:
jakarta.xml.bind:jakarta.xml.bind-api:4.0.1 under package jakarta.xml.bind

Even without the dependencies being explicitly added, quarkus will in fact include jakarta.xml.bind:jakarta.xml.bind-api:4.0.1 transitively through hibernate, rest-easy or quarkus-bean.

I believe this is the reason why this error is being encountered:

.CamelExecutionException: Exception occurred during execution on the exchange: Exchange[]
    at org.apache.camel.CamelExecutionException.wrapCamelExecutionException(CamelExecutionException.java:45)
    at org.apache.camel.support.AbstractExchange.setException(AbstractExchange.java:559)
    at org.apache.camel.support.DefaultExchange.setException(DefaultExchange.java:32)
    at org.apache.camel.support.processor.DelegateSyncProcessor.process(DelegateSyncProcessor.java:68)
    at org.apache.camel.processor.errorhandler.RedeliveryErrorHandler$SimpleTask.handleFirst(RedeliveryErrorHandler.java:462)
    at org.apache.camel.processor.errorhandler.RedeliveryErrorHandler$SimpleTask.run(RedeliveryErrorHandler.java:438)
    at org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.doRun(DefaultReactiveExecutor.java:199)
    at org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.executeReactiveWork(DefaultReactiveExecutor.java:189)
    at org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.tryExecuteReactiveWork(DefaultReactiveExecutor.java:166)
    at org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.schedule(DefaultReactiveExecutor.java:148)
    at org.apache.camel.impl.engine.DefaultReactiveExecutor.scheduleMain(DefaultReactiveExecutor.java:59)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:163)
    at org.apache.camel.impl.engine.CamelInternalProcessor.processNonTransacted(CamelInternalProcessor.java:354)
    at org.apache.camel.impl.engine.CamelInternalProcessor.process(CamelInternalProcessor.java:330)
    at org.apache.camel.impl.engine.DefaultAsyncProcessorAwaitManager.process(DefaultAsyncProcessorAwaitManager.java:82)
    at org.apache.camel.support.AsyncProcessorSupport.process(AsyncProcessorSupport.java:32)
    at org.apache.camel.component.file.GenericFileConsumer.processExchange(GenericFileConsumer.java:484)
    at org.apache.camel.component.file.remote.RemoteFileConsumer.processExchange(RemoteFileConsumer.java:153)
    at org.apache.camel.component.file.GenericFileConsumer.processBatch(GenericFileConsumer.java:244)
    at org.apache.camel.component.file.GenericFileConsumer.poll(GenericFileConsumer.java:205)
    at org.apache.camel.support.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:204)
    at org.apache.camel.support.ScheduledPollConsumer.run(ScheduledPollConsumer.java:118)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
    at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305)
    at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
    at com.intrasoft.processors.XsdFailedValidationMessageProcessor.process(XsdFailedValidationMessageProcessor.java:56)
    at com.intrasoft.processors.XsdFailedValidationMessageProcessor_ClientProxy.process(Unknown Source)
    at org.apache.camel.support.processor.DelegateSyncProcessor.process(DelegateSyncProcessor.java:65)
    ... 24 more
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.JAXBException
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
    at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:518)
    at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:468)
    ... 27 more

Therefore what is the best way to overcome this?
Preferably there is a way to use the jaxb-api:2.3.1 class of JAXBException in order to use the external dependency.


Solution

  • As stated in my last comment :

    Quarkus 3 has updated to the latest Jakarta APIs, which includes a community alignment around the new “jakarta.*” package names. We know this is a big change, so In order to make migrating as smooth as possible, we included an automated update tool to minimize your effort. Learn more about migrating to Jakarta EE API’s

    So you need to change your dependencies to get rid of jaxb2.3 (javax-based) to fix your migration problem