【问题标题】:Running mvn shade on a pre-existing uber jar在预先存在的 uber jar 上运行 mvn shade
【发布时间】:2014-08-28 02:10:20
【问题描述】:

我有一个已经生成的 uber jar(不是通过 Maven;我只有 jar)。我需要将它与另一个存在依赖冲突的 jar 一起使用。我想遮蔽第一个 uber jar 中的所有库,除了一些需要公开的类。

如何设置现有的 jar,并使用 Maven shade 插件重命名其大部分(白名单除外)类,生成一个新的 uber jar?

【问题讨论】:

    标签: maven jar maven-shade-plugin uberjar


    【解决方案1】:

    您可以使用maven-shade-plugin 进行“重命名”类型的活动。例如:

    <relocations>
      <relocation>
        <pattern></pattern>
        <shadedPattern>relocated.</shadedPattern>
        <excludes>
          <exclude>com.myfirm.level1.level2.*</exclude>                   
        </excludes>
      </relocation>
    </relocations>
    

    基本上会将每个包 a.b.c 移动到 relocated.a.b.c(我排除的显式模式除外)。

    似乎重定位过程会将所有对匹配该模式的类的引用移动,无论该类是否定义在用于构造 jar 的依赖项中。

    以下堆栈跟踪(通过尝试运行在使用上述重定位构造的 jar 中定义的 main() 获得)显示对 java.lang.Object 的引用已重命名为 relocated.java.lang.Object,并且(显然)找不到relocated. 版本。

    java.lang.NoClassDefFoundError: relocated/java/lang/Object
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
        at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:482)
    Caused by: java.lang.ClassNotFoundException: relocated.java.lang.Object
        at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
        ... 13 more
    Exception in thread "main"
    

    【讨论】:

    • 为什么不能使用?只要不在 Jar 外部访问该类,就不会修改字节码以使用 relocated.a.b.c
    • 如果您查看堆栈跟踪,它会显示重定位“编辑”对未在 jar 中定义的类型的引用。因此,对java.lang.Object 的引用更改为relocated.java.lang.Object,它在类路径中不存在。我将编辑此答案以使其更清晰。
    猜你喜欢
    • 2017-06-18
    • 1970-01-01
    • 2012-02-07
    • 2013-11-28
    • 2021-01-07
    • 2019-04-30
    • 1970-01-01
    • 2010-09-20
    相关资源
    最近更新 更多