Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove a maven lib (jsr250-api-1.0.jar) from the plugin classpath (jetty:run)?

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.

like image 661
Thierry Avatar asked Oct 02 '18 11:10

Thierry


1 Answers

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.

like image 91
Charlee Chitsuk Avatar answered Sep 28 '22 23:09

Charlee Chitsuk