Closed mdindoffer closed 1 year ago
SystemPropertiesConfigurationModel.hasProperty(java.lang.String)
is inherited from new Jakarta REST 3.1 API Configuration#hasProperty
. Do you use the proper 3.1.0 API?
I am trying it in latest 3.1 branch and it works fine. But you have to remove:
@BeforeAll
void initContainer() throws Exception {
super.setUp();
}
@AfterAll
void destroyContainer() throws Exception {
super.tearDown();
}
That is automatically done by JerseyTest. Otherwise you will get java.net.BindException: Address already in use
SystemPropertiesConfigurationModel.hasProperty(java.lang.String)
is inherited from new Jakarta REST 3.1 APIConfiguration#hasProperty
. Do you use the proper 3.1.0 API?
Yes.
I am trying it in latest 3.1 branch and it works fine. But you have to remove:
Nope. The full example is:
//Let's avoid the expensive recreation of the jax-rs container for each test method by setting up class-level container instance
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class MyTest extends JerseyTest {
@BeforeAll
void initContainer() throws Exception {
super.setUp();
}
@AfterAll
void destroyContainer() throws Exception {
super.tearDown();
}
@BeforeEach
public void initDb() {
someinit();
}
@Override
public void setUp() throws Exception {
//NOOP to avoid recreating container
}
@Override
public void tearDown() throws Exception {
//NOOP to avoid recreating container
}
...
I just omitted the overrides for brevity. And even if I remove all that I still get the NoSuchMethodError
.
@mdindoffer you can try my example.
$ git clone https://github.com/jbescos/Questions.git
$ cd jersey3.1
$ mvn clean install
...
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 3.283 s - in com.github.jbescos.jersey3.DummyJerseyTest
...
[INFO] com.example:jersey3:jar:1.0
[INFO] +- org.glassfish.jersey.containers:jersey-container-servlet-core:jar:3.1.0:compile
[INFO] | +- jakarta.inject:jakarta.inject-api:jar:2.0.1:compile
[INFO] | +- org.glassfish.jersey.core:jersey-common:jar:3.1.0:compile
[INFO] | | +- jakarta.annotation:jakarta.annotation-api:jar:2.1.1:compile
[INFO] | | \- org.glassfish.hk2:osgi-resource-locator:jar:1.0.3:compile
[INFO] | +- org.glassfish.jersey.core:jersey-server:jar:3.1.0:compile
[INFO] | | \- jakarta.validation:jakarta.validation-api:jar:3.0.2:compile
[INFO] | \- jakarta.ws.rs:jakarta.ws.rs-api:jar:3.1.0:compile
[INFO] +- org.glassfish.jersey.inject:jersey-hk2:jar:3.1.0:compile
[INFO] | +- org.glassfish.hk2:hk2-locator:jar:3.0.3:compile
[INFO] | | +- org.glassfish.hk2.external:aopalliance-repackaged:jar:3.0.3:compile
[INFO] | | +- org.glassfish.hk2:hk2-api:jar:3.0.3:compile
[INFO] | | \- org.glassfish.hk2:hk2-utils:jar:3.0.3:compile
[INFO] | \- org.javassist:javassist:jar:3.28.0-GA:compile
[INFO] +- org.glassfish.jersey.test-framework.providers:jersey-test-framework-provider-jdk-http:jar:3.1.0:test
[INFO] | +- org.glassfish.jersey.test-framework:jersey-test-framework-core:jar:3.1.0:test
[INFO] | | +- jakarta.xml.bind:jakarta.xml.bind-api:jar:4.0.0:test
[INFO] | | | \- jakarta.activation:jakarta.activation-api:jar:2.1.0:test
[INFO] | | +- jakarta.servlet:jakarta.servlet-api:jar:6.0.0:test
[INFO] | | \- org.glassfish.jersey.media:jersey-media-jaxb:jar:3.1.0:test
[INFO] | +- org.glassfish.jersey.containers:jersey-container-jdk-http:jar:3.1.0:test
[INFO] | +- org.glassfish.jersey.core:jersey-client:jar:3.1.0:compile
[INFO] | \- junit:junit:jar:4.13.1:test
[INFO] | \- org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] \- org.junit.jupiter:junit-jupiter:jar:5.9.1:test
[INFO] +- org.junit.jupiter:junit-jupiter-api:jar:5.9.1:test
[INFO] | +- org.opentest4j:opentest4j:jar:1.2.0:test
[INFO] | +- org.junit.platform:junit-platform-commons:jar:1.9.1:test
[INFO] | \- org.apiguardian:apiguardian-api:jar:1.1.2:test
[INFO] +- org.junit.jupiter:junit-jupiter-params:jar:5.9.1:test
[INFO] \- org.junit.jupiter:junit-jupiter-engine:jar:5.9.1:test
[INFO] \- org.junit.platform:junit-platform-engine:jar:1.9.1:test
Could you check the classpath/modulepath of the running test?. Just add a Thread.sleep(9999999);
right after void initContainer() throws Exception {
and run $ ps -ef | grep java
.
Uhm, sure, does it tell you anything?
$ ps -ef | grep java
mao 70370 70348 41 14:29 pts/1 00:02:00 /usr/bin/java -classpath /usr/share/maven/boot/plexus-classworlds-2.x.jar -Dclassworlds.conf=/usr/share/maven/bin/m2.conf -Dmaven.home=/usr/share/maven -Dlibrary.jansi.path=/usr/share/maven/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/home/mao/work/com/abc org.codehaus.plexus.classworlds.launcher.Launcher clean package
mao 71583 70370 0 14:30 pts/1 00:00:00 /bin/sh -c cd '/home/mao/work/com/abc/example' && '/usr/lib/jvm/temurin-17-jdk-amd64/bin/java' '-jar' '/home/mao/work/com/abc/example/target/surefire/surefirebooter-20221121143041889_654.jar' '/home/mao/work/com/abc/example/target/surefire' '2022-11-21T14-29-35_642-jvmRun1' 'surefire-20221121143041889_652tmp' 'surefire_9-20221121143041889_653tmp'
mao 71584 71583 8 14:30 pts/1 00:00:19 /usr/lib/jvm/temurin-17-jdk-amd64/bin/java -jar /home/mao/work/com/abc/example/target/surefire/surefirebooter-20221121143041889_654.jar /home/mao/work/com/abc/example/target/surefire 2022-11-21T14-29-35_642-jvmRun1 surefire-20221121143041889_652tmp surefire_9-20221121143041889_653tmp
Here's also a grepped output of mvn dependency:tree
$ mvn dependency:tree | grep jersey
[INFO] | | \- org.glassfish.jersey.containers:jersey-container-servlet-core:jar:3.1.0:compile
[INFO] | \- org.glassfish.jersey.media:jersey-media-json-jackson:jar:3.1.0:compile
[INFO] | \- org.glassfish.jersey.ext:jersey-entity-filtering:jar:3.1.0:compile
[INFO] +- org.glassfish.jersey.inject:jersey-hk2:jar:3.1.0:compile
[INFO] +- org.glassfish.jersey.core:jersey-common:jar:3.1.0:compile
[INFO] +- org.glassfish.jersey.core:jersey-client:jar:3.1.0:compile
[INFO] +- org.glassfish.jersey.connectors:jersey-apache-connector:jar:3.1.0:compile
[INFO] +- org.glassfish.jersey.media:jersey-media-multipart:jar:3.1.0:compile
[INFO] +- org.glassfish.jersey.test-framework.providers:jersey-test-framework-provider-jdk-http:jar:3.1.0:test
[INFO] | +- org.glassfish.jersey.test-framework:jersey-test-framework-core:jar:3.1.0:test
[INFO] | | \- org.glassfish.jersey.media:jersey-media-jaxb:jar:3.1.0:test
[INFO] | +- org.glassfish.jersey.containers:jersey-container-jdk-http:jar:3.1.0:test
[INFO] | +- org.glassfish.jersey.core:jersey-server:jar:3.1.0:compile
$ mvn dependency:tree | grep jakarta.ws.rs
[INFO] | +- jakarta.ws.rs:jakarta.ws.rs-api:jar:3.1.0:compile
Uhm, sure, does it tell you anything?
$ ps -ef | grep java mao 70370 70348 41 14:29 pts/1 00:02:00 /usr/bin/java -classpath /usr/share/maven/boot/plexus-classworlds-2.x.jar -Dclassworlds.conf=/usr/share/maven/bin/m2.conf -Dmaven.home=/usr/share/maven -Dlibrary.jansi.path=/usr/share/maven/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/home/mao/work/com/abc org.codehaus.plexus.classworlds.launcher.Launcher clean package mao 71583 70370 0 14:30 pts/1 00:00:00 /bin/sh -c cd '/home/mao/work/com/abc/example' && '/usr/lib/jvm/temurin-17-jdk-amd64/bin/java' '-jar' '/home/mao/work/com/abc/example/target/surefire/surefirebooter-20221121143041889_654.jar' '/home/mao/work/com/abc/example/target/surefire' '2022-11-21T14-29-35_642-jvmRun1' 'surefire-20221121143041889_652tmp' 'surefire_9-20221121143041889_653tmp' mao 71584 71583 8 14:30 pts/1 00:00:19 /usr/lib/jvm/temurin-17-jdk-amd64/bin/java -jar /home/mao/work/com/abc/example/target/surefire/surefirebooter-20221121143041889_654.jar /home/mao/work/com/abc/example/target/surefire 2022-11-21T14-29-35_642-jvmRun1 surefire-20221121143041889_652tmp surefire_9-20221121143041889_653tmp
Here's also a grepped output of mvn dependency:tree
$ mvn dependency:tree | grep jersey [INFO] | | \- org.glassfish.jersey.containers:jersey-container-servlet-core:jar:3.1.0:compile [INFO] | \- org.glassfish.jersey.media:jersey-media-json-jackson:jar:3.1.0:compile [INFO] | \- org.glassfish.jersey.ext:jersey-entity-filtering:jar:3.1.0:compile [INFO] +- org.glassfish.jersey.inject:jersey-hk2:jar:3.1.0:compile [INFO] +- org.glassfish.jersey.core:jersey-common:jar:3.1.0:compile [INFO] +- org.glassfish.jersey.core:jersey-client:jar:3.1.0:compile [INFO] +- org.glassfish.jersey.connectors:jersey-apache-connector:jar:3.1.0:compile [INFO] +- org.glassfish.jersey.media:jersey-media-multipart:jar:3.1.0:compile [INFO] +- org.glassfish.jersey.test-framework.providers:jersey-test-framework-provider-jdk-http:jar:3.1.0:test [INFO] | +- org.glassfish.jersey.test-framework:jersey-test-framework-core:jar:3.1.0:test [INFO] | | \- org.glassfish.jersey.media:jersey-media-jaxb:jar:3.1.0:test [INFO] | +- org.glassfish.jersey.containers:jersey-container-jdk-http:jar:3.1.0:test [INFO] | +- org.glassfish.jersey.core:jersey-server:jar:3.1.0:compile
$ mvn dependency:tree | grep jakarta.ws.rs [INFO] | +- jakarta.ws.rs:jakarta.ws.rs-api:jar:3.1.0:compile
It does not tell me anything unfortunately because the surefire plugin does not show it.
You can print everything in the System properties instead. Classpath should be there.
What I am trying to verify, is that when you are running the tests there is no wrong jars in the classpath because of some wrong plugins configuration.
Sorry this took so long. I've tracked this down to jakarta.platform:jakarta.jakartaee-api:9.1.0
on our classpath.
This jakartaee-api
artifact also includes the jakarta.ws.rs.core.Configuration
class, just as the jakarta.ws.rs:jakarta.ws.rs-api:3.1.0
does. But, the Configuration
class in jakartaee-api 9.1.0 differs from the one in rs-api 3.1.0.
Obviously I could update jakartaee-api
to 10.0.0, which fixes the test at least. But I wonder if this is really the intended way to manage jakarta dependencies. It seems horribly wrong to have the same class on classpath supplied by two different jakarta artifacts. It is hard to keep everything in sync this way.
What is the recommended way to pull in jakarta APIs ? Why are the classes duplicated in different artifacts? Should I try to
rs-api
from jersey and other 3rd party libs? orjakartaee-api
artifacts from my project and 3rd party libs?@mdindoffer Glad to hear you were able to solve the issue. Mixing the versions between Jakarta EE 9 and Jakarta EE 10 can cause these types of issues.
The existence of jakarta.platform:jakarta.jakartaee-api
is a result of the Jakarta EE platform project, which covers all the Jakarta EE specification. The API can be used so that each individual dependency is not required to be specified separately with its own version. The drawback is that there are many dependencies not used by project but forced on the classpath/module path.
To answer the questions:
Jersey does not include the APIs (except for bundles which likely are not used in your project). Jersey has some mandatory dependencies, such as Jakarta REST API, but those are required to be added by a customer. Jersey, as well as all the Jakarta EE artifacts, define OSGi headers in each of the artifacts which define the versions of dependencies Jersey relies on. These OSGi headers are defined in MANIFEST.MF of each maven artifact (jar) and the dependency versions are enforced by some application servers that are using the OSGi runtime, such as Glassfish, or Payara. In your pure maven (or ANT) test environment the OSGi framework (such as Felix) most likely is not used (setting up the OSGi environment is difficult) and the dependencies can be freely mixed, causing the issues. The proper dependency versions can also be seen in Jersey pom.xml files.
You can choose which dependency you would use, whether the all-API-bundle jakartaee-api
or the individual API. When the JPMS would be used by your project, the jakartaee-api
might have issues with declaring the module-info
, though.
It is possible to use many APIs each providing the same classes. The one to be the first on the classpath/module path would be used by the classloader.
With JakartaEE dependencies, it is important to know which Jakarta EE version your project wants to support. When upgrading the version (such as in your case from Jakarta EE 9 to Jakarta EE 10 with Jersey 3.0.x to 3.1.x), all the dependencies should be upgraded accordingly, JAX-B, JSON-B, CDI, Servlet, you name it. So upgrading the Jakarta EE version is rather a larger task. But it is performed only with a new Jakarta EE release, i.e. next time no sooner than in 2024.
Thanks for the explanation, I'm closing this as it's a simple mixup of JEE10 and 9.1 dependencies. In other words, everything should be updated all at once (Jetty, Jersey, and any other library that depends on JEE specs), mixing is not allowed.
What is interesting though is that Jersey 3.1.x was out for quite some time since November 2022, while Jetty 12 (the first version with support for JEE10) came out just two weeks ago. I wonder how did other folks use Jersey 3.1, when the rest of the ecosystem was way behind playing catch-up.
JerseyTest is broken in 3.1.0 and the test class fails to initialize. Instead an exception is thrown:
NoSuchMethodError: 'boolean org.glassfish.jersey.internal.config.SystemPropertiesConfigurationModel.hasProperty(java.lang.String)'
.This is a regression, 3.0.8 works just fine.
Reproducible example
Junit5 test
Output