首先,我是StackOverflow的长期用户(和受益人),但这是我的第一个问题。我已经对这个主题进行了大量的搜索,但是我发现的大部分文章都谈到了生成JAR文件,而不是使用Maven Central仓库中的第三方JAR,我真的没有权力修复它。我见过的几个解决方案并不是真的可以接受。
问题是,Maven Central存储库中的大多数jaxb JAR都包含指向依赖项的类路径条目(在MANIFEST.MF文件中),并且这些依赖项是使用相对路径指定的 - 通常假设依赖条。 jar与foo.jar存在于同一目录中。
例如,如果您在单个lib目录中拥有所有JAR依赖项,那么这很好。但是:
最终结果是这样的错误消息:
[错误]坏路径元素 “C:\用户\ rpoole \ .m2目录\库\ COM \太阳\ XML \绑定\ JAXB的IMPL \ 2.2.11 \ JAXB-core.jar添加”: 没有这样的文件或目录
一种解决方案是编写脚本或小应用程序来浏览所有JAR,并从嵌入的MANIFEST.MF文件中删除类路径信息。但这不是很干净,在进行实际构建之前需要额外的步骤。
另一个可能的解决方案是,一些较新发布的JAR版本已经解决了这个类路径问题,因此使用最新和最好的。不幸的是,我正在开发的这个应用程序是遗留的,并且正在为第三方开发,因此我无法更新某个版本之外的依赖项。到目前为止,我所研究的所有jaxb JAR似乎都存在问题。
有没有办法告诉Maven忽略JAR中的嵌入式类路径,只依赖于Maven自己的依赖解析?我已经尝试过重新排序依赖项之类的东西,但这不起作用(或将构建问题从一个子项目转移到另一个子项目)。
另外一个烦恼:我们有一个“幸运的”Maven回购似乎让构建完成没有任何问题,但到目前为止,我一直无法弄清楚为什么这个特定的JAR集合构建好。我怀疑有人可能已经进入并手动调整了一些JAR或POM,但是信息量很少,差异工具并没有太多帮助。
无论如何,项目应从头开始构建。
如果我可以在pom.xml中为子项目指定一个类似于排除块的东西,那就更好了,但是用于处理JAR的嵌入式类路径而不是Maven自己的传递依赖项(由groupId / artifactId指定)。
编辑:显然,有些人认为这是不可能的,Maven会忽略Manifest.MF中的Class-Path条目。但是,这是一个已知问题,如this StackOverflow article中所述。还有another good article,它解释了一些更好的历史。
问题是我不能通过JAR并在构建过程中编辑每个上的MANIFEST.MF文件。即使通过脚本自动化,这也不是一种实用的方法。我需要一个实际上适用于已经在生产中的代码的解决方案。这些问题在相关JAR的更高版本中被推测修复,但我可能无法使用这些版本的更新版本。
此外,建议的修复之一是将-Xlint:-path
添加到编译器args,这会抑制错误消息。然而,对于我来说,构建只是在另一个方面失败,所以乍一看这似乎也不是一个好的解决方案。我将再次尝试这个,因为根据this,POM文件中的编译器参数的语法有点不稳定。
答案 0 :(得分:1)
我讨厌回答我自己的问题,但我终于设法解决了这个问题。对于那些坚持认为Maven构建可能不会受到jar的MANIFEST.MF中的Class-Path条目影响的人,请阅读Michael Bayne的this article。它很好地总结了问题和解决方案。提示:javac当然关心jar中的嵌入式类路径。
诀窍是将-Xlint:-path
添加到编译器参数中,尽管我最初对此解决方案持怀疑态度。这样做会抑制错误的路径元素警告/错误,因此Maven不会过早停止构建。我遇到的问题是找出在pom.xml中嵌入这些参数的正确语法。这就是this article派上用场的地方。因此,编译器插件的配置必须如此正确理解:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java-version}</source>
<target>${java-version}</target>
<compilerArguments>
<Xlint/>
<Xlint:-path/>
</compilerArguments>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
</plugins>
请注意,这种语法不是很好的XML(正如Bayne指出的那样),并且大多数IDE会将第二个Xlint行标记为错误,但它可以与Maven一起使用。使用某些Maven教程中给出的语法可能会导致参数根本没有传递给编译器,或者只传递传递的最后一个参数。
一旦解决了这个问题,您可能会发现其他构建问题(我当然也会这样做),但至少这些问题不会再被隐藏起来了。
答案 1 :(得分:0)
问题在于您引用的是七年前的帖子..并且不使用maven-compiler-plugin的更新版本:
javac compiler的参数可以更好地完成:
<project>
[...]
<build>
[...]
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<compilerArgs>
<arg>-Xlint</arg>
<arg>-Xlint:-path</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
[...]
</build>
[...]
</project>