简体   繁体   English

尽管清单类路径包括包含该类的.jar,但仍发生ClassNotFoundException

[英]ClassNotFoundException despite the manifest classpath including a .jar which contains the class

I have a maven java project that I am trying to run from the command line. 我有一个要从命令行运行的Maven Java项目。 The project is built using Netbeans 8.1. 该项目是使用Netbeans 8.1构建的。 It is built to java-snap-2.0.jar with the maven-dependency-plugin and maven-jar-plugin. 它使用maven-dependency-plugin和maven-jar-plugin构建到java-snap-2.0.jar

In my root/target directory, I find a lib/ directory containing all the .jar needed for my project's dependencies. 在我的根目录/目标目录中,我找到一个lib /目录,其中包含项目依赖项所需的所有.jar。 I have, for instance, a snap-core-6.0.0-SNAPSHOT.jar which contains, among others, org/esa/snap/core/datamodel/Product.class . 例如,我有一个snap-core-6.0.0-SNAPSHOT.jar ,其中包含org / esa / snap / core / datamodel / Product.class In my executable jar, I have a META-INF/MANIFEST.MF file which contains a list of white-space-seperated paths to the jar files in the lib/ directory, including lib/snap-core-6.0.0-20170810.175327-200.jar . 在我的可执行jar中,我有一个META-INF / MANIFEST.MF文件,其中包含lib /目录中jar文件的空白分隔路径列表,包括lib / snap-core-6.0.0-20170810.175327- 200.jar

Despite this, when I run the jar file from the command line like so : java -jar java-snap-2.0.jar argument1, argument2 ... argumentN , I get the following error : 尽管如此,当我像这样从命令行运行jar文件时: java -jar java-snap-2.0.jar argument1, argument2 ... argumentN ,出现以下错误:

Exception in thread "main" java.lang.NoClassDefFoundError: org/esa/snap/core/datamodel/Product
    at com.batchprocessing.java.snap.ProcessMultiTemporal.main(ProcessMultiTemporal.java:56)
    at com.batchprocessing.java.snap.Main.ProcessMultiTemporalHPC(Main.java:178)
    at com.batchprocessing.java.snap.Main.main(Main.java:189)
Caused by: java.lang.ClassNotFoundException: org.esa.snap.core.datamodel.Product
    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)
    ... 3 more

Here is an excerpt from the pom.xml file : 这是pom.xml文件的摘录:

(...)    
<build>
    <plugins>
        <!-- Copy dependencies during package phase to root/lib directory -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${project.build.directory}/lib/</outputDirectory>
                        <overWriteReleases>false</overWriteReleases>
                        <overWriteSnapshots>false</overWriteSnapshots>
                        <overWriteIfNewer>true</overWriteIfNewer>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <!-- Build an executable JAR and add classpaths (in lib/) to manifest -->
        <plugin>             
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                        <mainClass>com.batchprocessing.java.snap.Main</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    (... other plugins ...)
</build>
(...)

I would greatly appreciate help figuring this out. 我将不胜感激帮助弄清楚这一点。 I've been using this application for a year by running it from the IDE, but I'd like to be able to run it from the command line and move it to other machines (by moving the executable jar and the lib/ directory). 我已经通过IDE运行该应用程序一年了,但我希望能够从命令行运行它并将其移动到其他计算机(通过移动可执行jar和lib /目录)。 。 I run into other issues if I try using a jar-with-dependencies or shade approach, so I'd like to get this setup (maven-jar-plugin + maven-dependency-plugin) working. 如果尝试使用具有依赖关系的jar或阴影方法,则会遇到其他问题,因此我想使此设置(maven-jar-plugin + maven-dependency-plugin)正常工作。

Alright, the issue (as rightly identified by Roman Pushkovskiy) was that the names of the jar files in the manifest file were different from their names in the lib directory. 好了,这个问题(由Roman Pushkovskiy正确识别)是清单文件中的jar文件的名称与lib目录中的名称不同。 These dependencies are mostly snapshots, and so the name of the jar is something like dependency-1.0.0-SNAPSHOT.jar. 这些依赖关系大多是快照,因此jar的名称类似于dependency-1.0.0-SNAPSHOT.jar。 In the manifest, they would be attributed a unique name based on the date of the snapshot : lib/dependency-1.0.0-20170810.175327-200.jar. 在清单中,它们将基于快照的日期被赋予唯一的名称:lib / dependency-1.0.0-20170810.175327-200.jar。 The solution was to add this line to the maven-jar-plugin : <useUniqueVersions>false</useUniqueVersions> . 解决方案是将此行添加到maven-jar-plugin中: <useUniqueVersions>false</useUniqueVersions>

Updated pom.xml excerpt : 更新了pom.xml摘录:

(...)
    <build>
        <plugin>             
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                        <mainClass>com.batchprocessing.java.snap.Main</mainClass>
                        <useUniqueVersions>false</useUniqueVersions>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
        (... other plugins ...)
    </build>
(...)

Hope this can help others ! 希望这可以帮助别人!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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