Reputation: 12269
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?
Upvotes: 4
Views: 5628
Reputation: 12269
For reference: This has been fixed by the Elastic team: They have switched from the Glassfish implementation
api("org.glassfish", "jakarta.json", "2.0.1")
to Eclipse Parsson:
api("jakarta.json:jakarta.json-api:2.0.1")
api("org.eclipse.parsson:parsson:1.0.0")
Upvotes: 3
Reputation: 12269
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
).
Upvotes: 1