如何排除打包为应用程序的 uber jar 的 jar 文件

Posted

技术标签:

【中文标题】如何排除打包为应用程序的 uber jar 的 jar 文件【英文标题】:how to exclude a jar file which is packed as a uber jar of an application 【发布时间】:2020-02-01 14:05:11 【问题描述】:

有一个应用程序使用带有通配符 * 的类路径运行

例如 java -cp /opt/sampleapp/lib/* Main

它有旧版本的 joda-time(1.8.),它没有方法 DateTime.now() 并且可从 2.x 版本的 joda-time 中获得。 注意:

这个 joda time(1.8) 被打包到另一个 jar (jruby-jar-1.6.8.jar 文件)

我正在编写一个使用 joda-time(2.x 以上) 版本的测试应用程序,该版本具有 DateTime.now() 方法并被我的 java 类使用。我必须将我的应用程序(jar)文件提交到正在运行的 sampleapp 才能运行它。不幸的是,在我的测试应用程序执行期间,旧版本被选中,这导致了

引起:java.lang.NoSuchMethodError: org.joda.time.DateTime.now()Lorg/joda/time/DateTime;

如果我删除旧版本的 jruby(1.6.8.jar) 并用 jruby(1.7.18) 替换它,则不会出现此类错误。我使用 maven 作为构建工具并使用 maven shaded 插件来创建一个 uber jar。如何在我的应用程序中提及不要在 jruby-1.6.8.jar 中选择 joda-time(1.8) 并在我的测试应用程序中选择正确版本的 joda-time-2.x jar 文件。

【问题讨论】:

【参考方案1】:

这很难。

您的 jruby JAR 通过包含 joda time 的类来打破规则。我可以想到不同的方法,它们都有各自的缺点:

    使用没有问题的较新版本的 jruby。 获取旧的 jruby 版本并对其进行操作:下载它,删除 joda-time 类并将其上传到您的 maven 存储库,使用类似 1.6.8-fixed 的版本。 为您的测试应用程序遮蔽其他版本的 joda time。

【讨论】:

感谢@JF Meier。我已经验证了选项 1,它工作正常。但我不能,因为它来自违反许可证的专有。对于选项 2,也是不可能的,因为如上所述(选项 1)。第三,不确定,但刚才我发现 jar 是我的测试应用程序 jar 的传递依赖。让我检查一下。 shade 插件可以做到这一点,因为 sampleapp 是一个正在运行的单独应用程序,我正在使用 maven-jar-plugin 创建一个 jar 来创建 jars。?任何链接/参考都会非常有帮助。

以上是关于如何排除打包为应用程序的 uber jar 的 jar 文件的主要内容,如果未能解决你的问题,请参考以下文章

Spark如何从打包的jar中选择类

如何使用不打包任何依赖项的 maven 程序集插件构建 jar?

Gradle - 排除文件与 jar 打包

java jar怎么把指定目录排除掉再进行打包?

spring boot使用gradle打包怎么样排除指定jar包

如何删除maven中冲突的jar包