如何从插件类路径 (jetty:运行) 中删除 Maven 库 (jsr250-api-1.0.jar)?
How to remove a maven lib (jsr250-api-1.0.jar) from the plugin classpath (jetty:run)?
我正在努力将我们的项目从 java 8 迁移到 11。
作为第一步,我正在使用源和目标兼容性 1.8 编译它,但试图 运行 通过 openjdk-11 应用程序。
在开发过程中,我们使用 jetty:run 目标来启动应用程序服务器。此目标失败并出现此错误:
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[=13=](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
我找到了错误版本的 @Resource
注释的来源:
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]
似乎 maven 正在将插件放在 classpath 其 /lib/ 文件夹中的所有库
我想当我运行在jdk 1.8 上安装它时,jdk 中的@Resource
注释具有优先权(因为我从来没有见过这个错误),但情况已不再如此(因为 jdk11 中不再包含此注释)。
我有什么选择可以摆脱这个旧的 class?
(我可以从 maven 安装升级 lib,但我宁愿保留它作为最后的手段,这将要求从事该项目的每个人都调整其 maven 安装)。
编辑:jetty:run-forked 目标也工作正常,但为了这个目标,我无法保留插件的 <webApp>
配置部分。
看来确实是maven class路径隔离问题
关于 Using Extensions and Core Classloader,我们可以通过在 pom.xml
处定义 extensions
来覆盖 ${maven.home}/lib
,如下所示:-
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>
当执行 mvn -e -X clean test
时,它给我们以下信息:-
[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]]
备注
我不能去掉javax.annotation:jsr250-api:1.0
,然后我把它放在javax.annotation:javax.annotation-api:1.3.2
之后,这样它就远离类路径,并确保首先使用javax.annotation:javax.annotation-api:1.3.2
.
请注意 Maven 3.8.3+
不再是问题
我正在努力将我们的项目从 java 8 迁移到 11。
作为第一步,我正在使用源和目标兼容性 1.8 编译它,但试图 运行 通过 openjdk-11 应用程序。
在开发过程中,我们使用 jetty:run 目标来启动应用程序服务器。此目标失败并出现此错误:
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[=13=](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
我找到了错误版本的 @Resource
注释的来源:
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]
似乎 maven 正在将插件放在 classpath 其 /lib/ 文件夹中的所有库
我想当我运行在jdk 1.8 上安装它时,jdk 中的@Resource
注释具有优先权(因为我从来没有见过这个错误),但情况已不再如此(因为 jdk11 中不再包含此注释)。
我有什么选择可以摆脱这个旧的 class?
(我可以从 maven 安装升级 lib,但我宁愿保留它作为最后的手段,这将要求从事该项目的每个人都调整其 maven 安装)。
编辑:jetty:run-forked 目标也工作正常,但为了这个目标,我无法保留插件的 <webApp>
配置部分。
看来确实是maven class路径隔离问题
关于 Using Extensions and Core Classloader,我们可以通过在 pom.xml
处定义 extensions
来覆盖 ${maven.home}/lib
,如下所示:-
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>
当执行 mvn -e -X clean test
时,它给我们以下信息:-
[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]]
备注
我不能去掉javax.annotation:jsr250-api:1.0
,然后我把它放在javax.annotation:javax.annotation-api:1.3.2
之后,这样它就远离类路径,并确保首先使用javax.annotation:javax.annotation-api:1.3.2
.
请注意 Maven 3.8.3+
不再是问题