2017-08-11 89 views
0

我有一个Maven的Java项目,我试图从命令行运行。该项目使用Netbeans 8.1构建。它被编译为java-snap-2.0.jar与maven-dependency-plugin和maven-jar-plugin。ClassNotFoundException尽管清单类路径包括一个包含类的.jar

在我的根/目录目录中,我找到一个lib /目录,其中包含项目依赖关系所需的所有.jar文件。例如,我有一个snap-core-6.0.0-SNAPSHOT.jar,其中包含org/esa/snap/core/datamodel/Product.class。在我的可执行jar文件中,我有一个META-INF/MANIFEST.MF文件,其中包含lib /目录中jar文件的空白分隔路径列表,其中包括lib/snap-core-6.0.0-20170810.175327 -200.jar

尽管这样,当我运行从像这样的命令行的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 

下面是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> 
(...) 

我非常感谢帮助解决这个问题。我一直使用这个应用程序一年从IDE运行它,但我希望能够从命令行运行它,并将其移动到其他机器(通过移动可执行jar和lib /目录) 。如果我尝试使用jar -with-dependencies或shade方法,我遇到了其他问题,所以我想要使用此设置(maven-jar-plugin + maven-dependency-plugin)工作。

+0

物理文件叫做snap-core-6.0.0-SNAPSHOT.jar吗?它与清单中的snap-core-6.0.0-20170810.175327-200.jar不同。 –

+0

是的。我注意到这种差异;我该如何解决它?我猜想最新快照的日期将被添加到清单中的.jar文件的名称(代替SNAPSHOT),但不会添加到lib /文件夹中。 –

+0

好的,非常感谢@RomanPuchkovskiy指引我朝着正确的方向前进。我通过将此行添加到maven-jar-plugin中的清单,存档和配置来修复它:在 false(https://stackoverflow.com/questions/ 13090487 /如何-DO-I-正确使用快照依赖性与 - 耳朵和-的EJB) –

回答

1

好的,这个问题(正如罗曼·普什科夫斯基所确定的那样)是清单文件中jar文件的名字与它们在lib目录中的名字不同。这些依赖关系大多是快照,所以jar的名称就像dependency-1.0.0-SNAPSHOT.jar。在清单中,根据快照的日期将它们分配一个唯一的名称:lib/dependency-1.0.0-20170810.175327-200.jar。解决方案是将此行添加到maven-jar-plugin:<useUniqueVersions>false</useUniqueVersions>

更新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> 
(...) 

希望这可以帮助别人!