Issue
I'm working on migrating our projects from java 8 to 11.
As a first step, i'm compiling it with source and target compatibility 1.8, but trying to run the application over the openjdk-11.
During development, we are using the jetty:run goal to start the application server. This goal is failing with this error :
Caused by: java.lang.NoSuchMethodError: javax.annotation.Resource.lookup()Ljava/lang/String;
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.<init>(CommonAnnotationBeanPostProcessor.java:621) ~[spring-context-5.1.0.RELEASE.jar:5.1.0.RELEASE]
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.lambda$buildResourceMetadata$0(CommonAnnotationBeanPostProcessor.java:383) ~[spring-context-5.1.0.RELEASE.jar:5.1.0.RELEASE]
at org.springframework.util.ReflectionUtils.doWithLocalFields(ReflectionUtils.java:713) ~[spring-core-5.1.0.RELEASE.jar:5.1.0.RELEASE]
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.buildResourceMetadata(CommonAnnotationBeanPostProcessor.java:365) ~[spring-context-5.1.0.RELEASE.jar:5.1.0.RELEASE]
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.findResourceMetadata(CommonAnnotationBeanPostProcessor.java:350) ~[spring-context-5.1.0.RELEASE.jar:5.1.0.RELEASE]
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(CommonAnnotationBeanPostProcessor.java:298) ~[spring-context-5.1.0.RELEASE.jar:5.1.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:1043) ~[spring-beans-5.1.0.RELEASE.jar:5.1.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:550) ~[spring-beans-5.1.0.RELEASE.jar:5.1.0.RELEASE]
... 63 more
I've located where the wrong version of the @Resource
annotation comes from :
URL [jar:file:[...]/.m2/repository/javax/annotation/javax.annotation-api/1.3.2/javax.annotation-api-1.3.2.jar!/javax/annotation/Resource.class]
URL [jar:file:[...]/Applications/apache-maven-3.5.4/lib/jsr250-api-1.0.jar!/javax/annotation/Resource.class]
It seems maven is putting on the plugin classpath all the libs it has on its /lib/ folder
I guess that when i was running it over jdk 1.8, the @Resource
annotation from the jdk had precedence (as i nver saw this error ever), but it is not anymore the case (as this annotation is not included anymore in jdk11).
What are my options to get rid of this old class ?
(i could upgrade the lib from the maven installation, but i'd prefer to keep that as a last resort, it would require that everybody working on the project tweak its maven installation).
EDIT: the jetty:run-forked goal is also working fine, but with this goal, i can't keep the <webApp>
configuration section of the plugin.
It really seems to be a maven classpath isolation issue.
Solution
Regarding to the Using Extensions and Core Classloader, we are able to override the ${maven.home}/lib
by defining the extensions
at our pom.xml
as the following: -
pom.xml
<build>
<extensions>
<extension>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</extension>
<extension>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
</extension>
</extensions>
</build>
When executing the mvn -e -X clean test
, it give us the following: -
[DEBUG] javax.annotation:javax.annotation-api:jar:1.3.2:
[DEBUG] org.codehaus.plexus:plexus-utils:jar:1.1:runtime
[DEBUG] Created new class realm extension>
javax.annotation:javax.annotation-api:1.3.2
[DEBUG] Importing foreign packages into class realm extension>
javax.annotation:javax.annotation-api:1.3.2
[DEBUG] Imported: < maven.api
[DEBUG] Populating class realm extension>
javax.annotation:javax.annotation-api:1.3.2
[DEBUG] Included: javax.annotation:javax.annotation-api:jar:1.3.2
[DEBUG] Included: org.codehaus.plexus:plexus-utils:jar:1.1
[DEBUG] Dependency collection stats: {...}
[DEBUG] javax.annotation:jsr250-api:jar:1.0:
[DEBUG] org.codehaus.plexus:plexus-utils:jar:1.1:runtime
[DEBUG] Created new class realm extension>
javax.annotation:jsr250-api:1.0
[DEBUG] Importing foreign packages into class realm extension>
javax.annotation:jsr250-api:1.0
[DEBUG] Imported: < maven.api
[DEBUG] Populating class realm extension>
javax.annotation:jsr250-api:1.0
....
[DEBUG] Extension realms for project some-group:some-artifact:some-packing:some-version :
[ClassRealm[extension>javax.annotation:javax.annotation-api:1.3.2,
parent: sun.misc.Launcher$AppClassLoader@5c647e05],
ClassRealm[extension>javax.annotation:jsr250-api:1.0,
parent: sun.misc.Launcher$AppClassLoader@5c647e05]]
[DEBUG] Created new class realm project>some-group:some-artifact:some-version
[DEBUG] Populating class realm project>some-group:some-artifact:some-version
[DEBUG] Included: javax.annotation:javax.annotation-api:jar:1.3.2
[DEBUG] Looking up lifecycle mappings for packaging war from
ClassRealm[project>some-group:some-artifact:some-version,
parent: ClassRealm[maven.api, parent: null]]
Note
I cannot get rid of the javax.annotation:jsr250-api:1.0
, then I put it after the javax.annotation:javax.annotation-api:1.3.2
so that it will be far from the classpath and ensure that the javax.annotation:javax.annotation-api:1.3.2
will be used first.
Answered By - Charlee Chitsuk
Answer Checked By - Senaida (JavaFixing Volunteer)