开发者

Unable to run executable jar containing dependencies

I'm stuck with this and shame on me if I still don't know how to run an executable jar generated by maven.

The myapp-uberjar.jar contains the following:

com/myapp/... (all my project packages and classes are here)
META-INF/MANIFEST.MF
dependency1.jar
dependency2.jar
...

The manifest seems ok also (I deleted some dependencies here for brevity):

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: rabdi
Build-Jdk: 1.6.0_18
Main-Class: com.myapp.core.main.Boot
Class-Path: spring-context-3.0.5.RELEASE.jar spring-context-support-3.0.5.RELEASE.jar spring-test-3.0.5.RELEASE.jar axis-1.4.jar axis-jaxrpc-1.4.jar axis
 -saaj-1.4.jar axis-wsdl4j-1.5.1.jar commons-discovery-0.2.jar xml-api
 s-1.0.b2.jar log4j-1.2.15.jar commons-pool-1.5.4.jar hamcrest-core-1.1.jar junit-de
 p-4.8.2.jar


Now when I go to run my jar I've the following errors:

D:\myapp\target>java -jar myapp-uberjar.jar
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/Logger
        at com.myapp.core.main.Boot.(Boot.java:14)
Caused by: java.lang.ClassNotFoundException: org.apache.log4j.Logger
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLo开发者_运维问答ader.loadClass(Unknown Source)
        ... 1 more
Could not find the main class: com.myapp.core.main.Boot. Program will exit.

Why it doesn't work? How to get it working.

Thanks!


if your distribute my program as single zip with my jar and libraries, then you have to build a class path. if you want the dependencies to go the a libraries out side the jar (highly recommended) you'll have to use assembly plugin in (or another plugin that do that). here is a full explanation how to do that: pom build element:

<build>
    <!-- final name set the jar name, if left it 
    will give defualt "${artifactId}-${version}" -->
    <finalName>jar final name</finalName>
    <sourceDirectory>src</sourceDirectory>

        <!-- compiler plug in -->
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
            </configuration>
        </plugin>
        <!-- assembly plugin -->
        <!-- the assembly plugin is used to define your 
        final deploy output (jar, zip, dir, war, etc..)-->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <executions>
                <execution>
                    <id>assembly:package</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                    <configuration>
                        <!-- The filename of the assembled distribution 
                        file defualt ${project.build.finalName}-->
                        <finalName>${project.build.finalName}</finalName>
                        <appendAssemblyId>false</appendAssemblyId>
                        <!--    A list of descriptor files path to generate from-->
                        <descriptors>
                            <descriptor>assembly/assembly.xml</descriptor>
                        </descriptors>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <!-- jar plug in -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.3</version>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>fully.qualified.MainClass</mainClass>
                        <!-- to create a class path to your 
                        dependecies you have to fill true in this field-->
                        <addClasspath>true</addClasspath>
                        <!-- if you put your dependencySet/outputDirectory 
                        in the assembly file is in a specific folder (lib for example), 
                        you need to add classpathPrefix-->
                        <classpathPrefix>lib/</classpathPrefix>

                        <!-- if you defined your dependencySet/outputFileNameMapping 
                        in the assembly, instead of using the classpathPrefix, 
                        you should use customClasspathLayout, 
                        add the classpathPrefix at the begining of the 
                        customClasspathLayout, and then add the pattern of the outputFileNameMapping, 
                        NOTICE YOU NEED TO ADD '$' BEFOR OF EACH '$'.
                        supported only from version 2.3>-->
                        <!--<classpathLayoutType>custom</classpathLayoutType>
                        <customClasspathLayout>
                            lib/$${artifact.groupId}.$${artifact.artifactId}.$${artifact.extension}
                        </customClasspathLayout>-->

                    </manifest>

                    <manifestEntries>
                        <Class-Path>conf/</Class-Path>
                    </manifestEntries>
                </archive>

            </configuration>
        </plugin>

    </plugins>
</build>

the assembly file:

<?xml version="1.0" encoding="UTF-8"?>
<assembly>
    <!--the id will be add to the end of the distribution file -->
    <id>package</id>
    <formats>
        <format>zip</format>
    </formats>
    <includeBaseDirectory>true</includeBaseDirectory>


    <fileSets>
        <fileSet>
            <directory>target</directory>
            <outputDirectory></outputDirectory>
            <includes>
                <include>*.jar</include>                
            </includes>
        </fileSet>
        <fileSet>
            <directory>icons</directory>
            <outputDirectory>icons</outputDirectory>
            <includes>
                <include>**/*</include>
            </includes>
        </fileSet>
        <fileSet>
            <directory>conf</directory>
            <outputDirectory>conf</outputDirectory>
            <includes>
                <include>**/*</include>
            </includes>
        </fileSet>
    </fileSets>

    <files>
        <!-- you need to create the bat file yourself -->
        <file>
            <source>batFileName.bat</source>
            <filtered>true</filtered>
        </file>
    </files>

        <dependencySets>
            <dependencySet>
                <!--define the outputDirectory of the dependencies, 
                    NOTICE: if it's diffrent from '/'  make sure to 
                    change the classPath configuration for 
                    the maven-jar-plugin in the pom-->
                <outputDirectory>lib</outputDirectory>
                <!-- maping the dependencies jar names.
                    NOTICE : if you used this definition, you need to use 
                    customClasspathLayout classPath configuration 
                    for the maven-jar-plugin in the pomg-->
                <outputFileNameMapping>
                    ${artifact.groupId}.${artifact.artifactId}.${artifact.extension}
                </outputFileNameMapping>
                <unpack>false</unpack>
            </dependencySet>
        </dependencySets>

</assembly>


First possibility: Java is expecting all those jars on the classpath to be in the same directory as your executable jar. Are they?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜