I am developing an application targeting a Java EE 8 application server (JBoss/Wildfly).
However, one of the dependencies (elasticsearch api) is already using jakarta.json.* classes which results in a ClassCastException at runtime:
java.lang.ClassCastException: org.glassfish.json.JsonProviderImpl cannot be cast to jakarta.json.spi.JsonProvider
That is because the org.classfish.json.JsonProviderImpl in my classpath (org.classfish:javax.json:1.1.4) is still using javax.json classes.
However, as both org.glassfish:jakarta.json and org.classfish:javax.json define the same class org.classfish.json.JsonProviderImpl (one using the javax.json.* classes and one using the jakarta.json.* classes...), I am unable to simply include both maven artifacts.
The implementation of JsonProviderImpl (in both artifacts!) basically returns the following by default:
return Class.forName("org.glassfish.json.JsonProviderImpl");
When both org.glassfish:jakarta.json and org.classfish:javax.json are on the classpath, this will cause issue for any of the implementations which will get the JsonProviderImpl from the other package.
What can I do to resolve this?
One workaround seems to be to use the maven shade plugin to basically "rename" the package org.glassfish.json in the "new" org.glassfish:jakarta.json to jakarta.org.glassfish.json:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<filters>
<filter>
<artifact>org.glassfish:jakarta.json</artifact>
<includes>
<include>org/glassfish/json/**</include>
</includes>
</filter>
</filters>
<artifactSet>
<includes>
<include>org.glassfish:jakarta.json</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>org.glassfish.json</pattern>
<shadedPattern>jakarta.org.glassfish.json</shadedPattern>
</relocation>
</relocations>
</configuration>
</plugin>
</plugins>
</build>
Then, one can create the file src/main/resources/META-INF/services/jakarta.json.spi.JsonProvider with the following content:
jakarta.org.glassfish.json.JsonProviderImpl
This will tell the implementation of jakarta.json.spi.JsonProvider to use the shaded version of the JsonProviderImpl (from the org.glassfish:jakarta.json artifact - which uses the jakarta.json.* classes) instead of the JsonProviderImpl (with the same name from org.glassfish:javax.json).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With