配置Maven Shade插件以最小化Jar包并包含类文件。

15
我正在尝试通过使用Maven Shade插件的minimizeJar来最小化UberJar的大小。看起来minimizeJar只包括代码中静态导入的类(我怀疑这是因为我在uber jar中看到了org\apache\commons\logging\LogFactory.class,但没有包含impl包中的任何类,因此在运行uber-jar时会抛出java.lang.ClassNotFoundException: org.apache.commons.logging.impl.LogFactoryImpl)。
有没有办法告诉Maven Shade插件将指定的包包含到最终的jar中,无论minimizeJar提供了什么建议?
这是我尝试的pom片段:
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>1.5</version>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>shade</goal>
                </goals>
                <configuration>
                    <minimizeJar>true</minimizeJar>
                    <filters>
                        <filter>
                            <artifact>commons-logging:commons-logging</artifact>
                            <includes>
                                <include>org/apache/commons/logging/**</include>
                            </includes>
                        </filter>    
                    </filters>
                    <transformers>
                        <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                            <mainClass>com.myproject.Main</mainClass>
                        </transformer>
                    </transformers>                            
                </configuration>
            </execution>
        </executions>
    </plugin>

1
org/apache/commons/logging/** 仅匹配目录,你可能想匹配所有文件。请改用 org/apache/commons/logging/**/* - Corubba
根据您的建议,我尝试了 ...logging/**...logging/**/*...logging/**/*.*,但都没有起作用。我猜问题在于包含文件先被包含,然后 minimizeJar 忽略其他所有内容,并将 jar 打包为它认为合适的形式。 - kdabir
2个回答

16

这个功能已经添加到了maven-shade-plugin的1.6版本中(刚刚发布)。minimizeJar现在不会删除已经通过筛选器特别包含的类。需要注意的是,在筛选器中包含某些构件的类将会排除该构件中未指定的类,因此请确保包含您所需的所有类。

下面是一个插件配置示例:

<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>

1
底层的<include>**</include>对我不起作用。它似乎还包括了其他包中的很多东西。相反,我必须使用<include>org/apache/logging/log4j/**</include> <include>Log4j-*</include> - Quantum7
仍然无法在 3.2.4 版本中工作。 - scruel

13

我正在使用Maven Shade Plugin的2.0版本,即使在“最小化” JAR 后,我仍然无法包含类。

作为一种解决方法,我能想到的唯一办法是创建对所需类的引用,以避免最小化代码将它们删除。例如:

/*
 * This block prevents the Maven Shade plugin to remove the specified classes
 */
static {
    @SuppressWarnings ("unused") Class<?>[] classes = new Class<?>[] {
        JButton.class,
        JMenu.class,
        JMenuBar.class,
        JMenuItem.class
    };
}

我希望Maven开发者能够实现一种处理这种情况的方式(我猜想这种情况非常普遍)。


2022年,仍需为log4j执行此操作。总的来说,log4j有很多配置问题。 - Asad-ullah Khan

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