Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maven shade plugin does not exclude the manifest signature files

I am using the maven shade plugin to generate a consolidate jar for my project. The jar is generated as expected and when i try to use the jar and run it, i get a

java.lang.SecurityException: Invalid signature file digest for Manifest main attributes error.

I googled the above error message and many people have suggested to exclude the manifest signatures from the META-INF directory. Thus i have included the step to exclude these files from the directory [i see two files by the name JARSIGN_.RSA and JARSIGN_.SF], but for some strange reason, maven shade plugin is unable to exclude these files from the META-INF directory. Could anyone explain me what i might be doing wrong? My pom.xml is below and the command that i am using to generate the jar is:

mvn clean package shade:shade

pom.xml

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>

        <groupId>com.abc.xyz</groupId>
        <artifactId>myjar</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>jar</packaging>
        <url>http://maven.apache.org</url>

        <properties>
            <!-- A few custom properties -->
        </properties>


        <dependencies>
            <dependency>
                <groupId>com.google.code.gson</groupId>
                <artifactId>gson</artifactId>
                <version>2.3.1</version>
            </dependency>
            <dependency>
                <groupId>com.google.guava</groupId>
                <artifactId>guava</artifactId>
                <version>18.0</version>
            </dependency>
        <!-- Other The dependencies are here -->
        </dependencies>

        <repositories>
            <!-- Repository Information -->
        </repositories>
        <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-compiler-plugin</artifactId>
                        <version>2.3.2</version>
                        <configuration>
                            <source>1.8</source>
                            <target>1.8</target>
                            <encoding>UTF-8</encoding>
                        </configuration>
                    </plugin>
                    <!-- Maven Shade Plugin -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-shade-plugin</artifactId>
                        <version>2.4.2</version>
                        <executions>
                            <!-- Run shade goal on package phase -->
                            <execution>
                                <phase>package</phase>
                                <goals>
                                    <goal>shade</goal>
                                </goals>
                                <configuration>
                                    <filters>
                                        <filter>
                                            <artifact>*:*</artifact>
<!-- The below statement is not executed by shade plugin -->
                                            <excludes>
                                                <exclude>META-INF/*.SF</exclude>
                                                <exclude>META-INF/*.DSA</exclude>
                                                <exclude>META-INF/*.RSA</exclude>
                                            </excludes>
                                        </filter>
                                    </filters>                          
                                    <minimizeJar>true</minimizeJar>
                                    <artifactSet>
                                        <includes>
                                            <include>com.google.guava:guava</include>
                                            <include>com.google.code.gson:gson</include>
                                        </includes>
                                    </artifactSet>
                                    <transformers>
                                        <!-- add Main-Class to manifest file -->
                                        <transformer
                                            implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                            <manifestEntries>
                                                <Main-Class>com.abc.xyz.HelloWorld</Main-Class>
                                            </manifestEntries>
                                        </transformer>
                                    </transformers>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
        </build>
    </project>
like image 663
Var Avatar asked Jan 12 '16 08:01

Var


People also ask

What is Maven Shade plugin used for?

This plugin provides the capability to package the artifact in an uber-jar, including its dependencies and to shade - i.e. rename - the packages of some of the dependencies.

What is uber jar maven?

An uber-JAR—also known as a fat JAR or JAR with dependencies—is a JAR file that contains not only a Java program, but embeds its dependencies as well. This means that the JAR functions as an “all-in-one” distribution of the software, without needing any other Java code.

What is dependency reduced POM XML?

The dependency-reduced-pom. xml removes transitive dependencies which are already in your shaded jar. This prevents consumers from pulling them in twice.

What is a shaded jar?

Shading is a process where a dependency is relocated to a different Java package and copied into the same JAR file as the code that relies on that dependency. The main purpose of shading is to avoid conflicts between the versions of dependencies used by a library and the versions used by the consumers of that library.


2 Answers

With shade plugin 3.2.1 the following works for me.

<!-- language: lang-xml -->
<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <filters>
                        <filter>
                            <artifact>*:*</artifact>
                            <excludes>
                                <exclude>META-INF/*.SF</exclude>
                                <exclude>META-INF/*.DSA</exclude>
                                <exclude>META-INF/*.RSA</exclude>
                            </excludes>
                        </filter>
                    </filters>
                </configuration>
            </plugin>
        </plugins>
    </pluginManagement>
</build>

On the plugin's doc page (https://maven.apache.org/plugins/maven-shade-plugin/examples/includes-excludes.html) the whole <configuration> block is shown inside the <execution> tag. This does not work. The <configuration> block should be outside the <executions> tag as shown above.

like image 154
krishnakumarp Avatar answered Sep 23 '22 13:09

krishnakumarp


Maybe the configuration syntax for the plugin has changed, but this worked for me in the past with version 1.5 of the shader plugin:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>1.5</version>
    <configuration>
        <transformers>
            <transformer implementation="org.apache.maven.plugins.shade.resource.DontIncludeResourceTransformer">
                <resource>META-INF/JARSIGN_.SF</resource>
            </transformer>
        </transformers>
    </configuration>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
        </execution>
    </executions>
</plugin>

I have not tried to use wildcards. But looking at the documentation the following should exclude all .SF files:

<resource>.SF</resource>

See this thread for another example.

like image 45
Ralf Avatar answered Sep 22 '22 13:09

Ralf