简体   繁体   中英

How to produce an executable jar file with all maven dependencies?

I have a maven project and I would like to produce the jar file with all dependencies. I use package shade plugin and the command mvn package to produce the jar file.

However, the produced jar file does not consider any of the dependencies that is pom.xml. The produced jar file keep give me exception:

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/Level

Here is the content of pom.xml:

<dependencies>
    <dependency>
        <groupId>${project.groupId}</groupId>
        <artifactId>myProject-core</artifactId>
        <version>${project.version}</version>
    </dependency>
    <dependency>
        <groupId>${project.groupId}</groupId>
        <artifactId>myProject-parser</artifactId>
        <version>${project.version}</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>${slf4j.version}</version>
    </dependency>
    <dependency>
        <groupId>info.picocli</groupId>
        <artifactId>picocli</artifactId>
        <version>${picoli.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>${shade.version}</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/log4j/log4j -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.16</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.13.1</version>
     </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.13.1</version>
     </dependency>
</dependencies>
<profiles>
    <profile>
        <id>client</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-shade-plugin</artifactId>
                    <version>${shade.version}</version>
                    <executions>
                        <execution>
                            <phase>package</phase>
                            <goals>
                                <goal>shade</goal>
                            </goals>
                            <configuration>
                                <finalName>myProject-client-${project.version}</finalName>
                                <transformers>
                                    <transformer
                                        implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                        <mainClass>myProject.package.main</mainClass>
                                    </transformer>
                                    <transformer
                                        implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
                                </transformers>
                                <filters>
                                    <!-- This is necessary to avoid a java.lang.SecurityException -->
                                    <filter>
                                        <artifact>*:*</artifact>
                                        <excludes>
                                            <exclude>META-INF/*.SF</exclude>
                                            <exclude>META-INF/*.DSA</exclude>
                                            <exclude>META-INF/*.RSA</exclude>
                                        </excludes>
                                    </filter>
                                </filters>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-jar-plugin</artifactId>
                    <configuration>
                         <archive>
                            <manifest>
                                <!-- Jar file entry point -->
                                <mainClass>myProject.package.main</mainClass>
                            </manifest>
                         </archive>
                    </configuration>
                </plugin>

            </plugins>
        </build>

Where is my mistake? It is even does not consider <mainClass>myProject.package.main</mainClass> for the main class when I run the jar I have to specify the class name:

java -cp myApp.jar myProject.package.main 

I looked over most of the questions and nothing solve my issue.

First of all, there are two plugins that you can use to create fat jars: maven-shade-plugin and maven-assembly-plugin .

The main difference between them is that maven-assembly just builds a jar containing all the dependency, while maven-shade also relocate these dependencies internally so that, if another project is depending on your jar, you won't risk having conflicts on dependencies.

If you don't expect yo use this artifact as a dependency of other projects, you can use maven-assembly-plugin for it. Here is an example of how to use it:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>3.1.1</version>
            <configuration>
                <finalName>${project.artifactId}</finalName>
                <archive>
                    <manifest>
                        <mainClass>myProject.package.main</mainClass>
                    </manifest>
                </archive>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <appendAssemblyId>false</appendAssemblyId>
            </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

If you really need to shade your dependencies, try to modify the manifest config of the plugin with this, at least it should solve the problem that you-re having with identifying the main class:

            <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
              <manifestEntries>
                <Main-Class>myProject.package.main</Main-Class>
                <X-Compile-Source-JDK>${maven.compiler.source}</X-Compile-Source-JDK>
                <X-Compile-Target-JDK>${maven.compiler.target}</X-Compile-Target-JDK>
              </manifestEntries>
            </transformer>

There are no groupId in the dependencies with org.apache.log4j, you have: org.apache.logging.log4j but its not the same as: org.apache.log4j

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM