正确地最小化Uber Jar,使用Shade-Plugin

32

我正在使用Maven-Shade-Plugin创建可运行的Uber-jar。 根据此页面上的最后一帧,可以通过使用以下方法来将jar大小最小化:

<configuration>
      <minimizeJar>true</minimizeJar>
</configuration>

然而,这个功能并没有考虑在log4j.properties文件中声明的类。因此,例如org.apache.log4j.appender.TimeAndSizeRollingAppender尽管在log4j.properties文件中声明了,但它不包含在Uber-jar中。

我相信我在使用Spring时也会遇到同样的问题。如果我的代码只引用接口A,并且我的Spring文件包含一个实现A的类B的实例化,则由于B不在代码中,可能不会将其添加到jar中。

如何解决这个问题?


几乎是一个重复的问题,但并不完全相同:https://dev59.com/62oy5IYBdhLWcg3wN7a8 - Raedwald
1个回答

42

这个功能已经被添加到maven-shade-plugin的1.6版本中(刚刚发布)。minimizeJar现在不会删除使用过滤器特别包含的类。请注意,将一个artifact的一些类包含在过滤器中可能会排除该artifact未指定的类,因此请确保包含您所需的所有类。

这里是一个示例插件配置:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>1.6</version>    
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>                        
            <configuration>
                <minimizeJar>true</minimizeJar>    
                <filters> 
                    <filter>
                       <artifact>log4j:log4j</artifact>
                       <includes>
                           <include>**</include>
                       </includes>
                    </filter> 
                    <filter>
                       <artifact>commons-logging:commons-logging</artifact>
                       <includes>
                           <include>**</include>
                       </includes>
                    </filter>                      
                </filters>
            </configuration>
        </execution>
    </executions>
</plugin>

要仅包含特定类,请使用类名中的路径斜杠将它们作为包含项添加到过滤器中(再次强调,未包含的类将自动排除)。

<filter>
  <artifact>org.yourorg:your-artifact</artifact>
  <includes>
    <include>org/yourorg/yourartifact/api/*</include>
    <include>org/yourorg/yourartifact/util/*</include>
  </includes>
</filter>

@VladimirSitnikov 编辑的答案,我相信底部的包含过滤器应该可以用来包含特定的类。 - Shane
再次强调,未包含的类将自动被排除。我不想手动找出所有需要包含的类。 - Vladimir Sitnikov
1
我不想手动找出所有需要包含的类。 例如,jarjar ant插件会自动扫描使用的类,你只需要指定主类即可。 - Vladimir Sitnikov
6
Maven-Shade-Plugin已经扫描了项目依赖并在使用<minimizeJar>true</minimizeJar>时自动包含它们。但是,当您的代码或依赖项使用动态类加载时,maven-shade-plugin无法检测到对动态加载类的依赖,因此您必须手动使用过滤器包含这些依赖关系,就像这里演示的那样。如果您不想这样做,请使用<minimizeJar>false</minimizeJar>,并且只需要处理较大的阴影jar包。这些是您的选择。 - Shane
在这种情况下,Proguard是最好的选择...它可以处理依赖项使用动态类加载的情况。 - Stephan
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接