我创建了一个 github 存储库,以便其他人可以从这个问题和答案中学习/受益。
github 存储库公开于:https://github.com/steranka/maven-shade-example https://github.com/steranka/maven-shade-example
Readme.md 解释了解决方案。有些如果记录在此处,以防万一消失(有一天)。
应用概述
这个例子说明了大多数大型项目中出现的问题以及如何
maven-shade-plugin 可以解决这个问题。
开发此代码示例是为了让我了解 maven-shade-plugin 的工作原理
具有真实的代码,但非常简化。
简单性的想法受到 StackOverflow 答案的启发:maven-shade-plugin 的用途是什么?为什么要重新定位 Java 包? https://stackoverflow.com/questions/13620281/what-is-the-maven-shade-plugin-used-for-and-why-would-you-want-to-relocate-java/13620420#13620420
这解释了为什么需要 maven-shade-plugin 以及它解决的问题。
在此代码中存在以下 JAR 文件
-
helloworld.jar - 作为主程序的 Java 可执行 jar。
-
loglib.jar - 此 jar 文件有两个版本(位于不同的目录中)。
-
goodlib.jar - 这是另一个使用 loglib.jar 版本 1 的 JAR 文件(dir loglibv1)。
依赖树概述
下图显示了 helloworld 应用程序的依赖关系树。
每个 pom 文件都会创建一个 JAR 文件,因此此代码示例创建了 4(四)个 jar 文件。
问题总结
下图显示了主应用程序 (helloworld) 中使用的 loglib.jar 文件
它显示了班级LogIt
包含一个方法sayHello
需要一个参数字符串名称在软件包 (liblog.jar) 的 1.0.0 版本中
和sayHello
在包的第二个版本中采用两个参数。
虽然这个例子是为了演示一般问题
当 Java 开发人员面临更复杂的代码库时,这个问题的简化版本旨在解决这个问题
易于理解和修复。
因此,默认情况下,当为 FAT jar 创建时你好世界应用程序中,Fat jar 仅包含类文件的一份副本com.steranka.play.LogIt
。
结果是,要么HelloWorld
类会崩溃或者GoodFeature
类会崩溃。其中 crash 意味着抛出异常下面是我第一次运行该应用程序时看到的异常示例。
Hello World!
What's up, Sam
Exception in thread "main" java.lang.NoSuchMethodError: 'java.lang.String com.steranka.play.LogIt.sayHello(java.lang.String)'
at com.steranka.play.GoodFeature.sayGoodbye(GoodFeature.java:6)
at com.steranka.play.HelloWorldApp.main(HelloWorldApp.java:15)
出现此问题的原因是使用了包含签名的 loglib.jar 版本 2.0.0:
sayHello(String name, String greeting)
和代码GoodFeature.sayGoodbye
有调用签名版本 1.0.0 的字节码:
sayHello(String name)
由于该签名不存在,因此发生了异常。
解决方案
The solution is to include both versions of the loglib
jar file as shown in the next diagram.
下一步
如果您想跟随我所做的,并了解我是如何解决这个问题的
继续这里有 doc/01-Starting.md https://github.com/steranka/maven-shade-example/blob/main/doc/01-Starting.md file.