Невозможно запустить исполняемый файл, содержащий зависимости - PullRequest
2 голосов
/ 06 мая 2011

Я застрял в этом и позор мне, если я все еще не знаю, как запустить исполняемый jar, сгенерированный maven.

myapp-uberjar.jar содержит следующее:

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

Манифест также выглядит нормально (для краткости я удалил некоторые зависимости здесь):

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


Теперь, когда я запускаю свой jar, у меня появляются следующие ошибки:

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.ClassLoader.loadClass(Unknown Source)
        ... 1 more
Could not find the main class: com.myapp.core.main.Boot. Program will exit.

Почему это не работает?Как заставить это работать.

Спасибо!

Ответы [ 2 ]

2 голосов
/ 11 октября 2011

если ваш distribute my program as single zip with my jar and libraries, то вы должны построить путь к классу. Если вы хотите, чтобы зависимости выходили за пределы библиотеки (очень рекомендуется), вам нужно использовать плагин сборки (или другой плагин, который это делает). Вот полное объяснение, как это сделать: 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>

файл сборки:

<?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>
1 голос
/ 06 мая 2011

Первая возможность: Java ожидает, что все эти jar-файлы в classpath будут находиться в том же каталоге, что и ваш исполняемый jar-файл.Они?

...