简体   繁体   English

包含本地jar到maven项目后的ClassNotFoundException

[英]ClassNotFoundException after include local jar to maven project

I have a spring boot project based on maven. 我有一个基于maven的spring boot项目。

I have to include a local jar that provided by another team.So I follow the accepted answer from : How to include local jar files in Maven project 我必须包含另一个团队提供的本地jar。所以我按照接受的答案: 如何在Maven项目中包含本地jar文件

So I use: 所以我使用:

<dependency>
  <groupId>com.netease</groupId>
  <artifactId>thrift</artifactId>
  <version>1.0</version>
  <scope>system</scope>
  <systemPath>${project.basedir}/lib/prome-thrift-client-1.0.0.jar</systemPath>
</dependency>

That works fine at the IDEA. 这在IDEA工作得很好。 But when I tried to run the package jar with: 但是当我尝试运行包jar时:

  mvn clean package
  java -jar target/prome-data.jar

Stacktrace is like: Stacktrace就像:

....
....
Caused by: java.lang.ClassNotFoundException: com.netease.thrift.client.ThriftRpcClient

Is there anything I am missing 有什么我想念的吗?

I have a similar issue today, and stuck me half day to fix it. 我今天也有类似的问题,并且让我停留半天来修复它。

For most case, using below is fine for developing. 对于大多数情况,使用以下可以用于开发。

<dependency>
    <groupId>com.netease</groupId>
    <artifactId>thrift</artifactId>
    <version>1.0</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/lib/prome-thrift-client-1.0.0.jar</systemPath>
</dependency>

If you put the jar to a correct path, then it's fine to run in both IDEA and Eclipse . 如果你把jar放到正确的路径上,那么可以在IDEAEclipse中运行。

After you deploy the jar to a server or run the jar locally, then it may throws ClassNotFoundException . 将jar部署到服务器或在本地运行jar后,它可能会抛出ClassNotFoundException

If you are using spring-boot, you still need below plugin: 如果您使用的是spring-boot,则仍需要以下插件:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
            <includeSystemScope>true</includeSystemScope>
    </configuration>
</plugin>

After run mvn clean package , then you can find the jar under /BOOT_INF/lib . 运行mvn clean package ,就可以在/BOOT_INF/lib下找到jar。

Between, if your package is war , then you still need this plugin: 介于两者之间,如果你的包是战争 ,那么你仍然需要这个插件:

 <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <configuration>
            <webResources>
                <resource>
                        <directory>lib</directory>
                        <targetPath>BOOT-INF/lib/</targetPath>
                        <!-- <targetPath>WEB_INF/lib/</targetPath> just for none spring-boot project -->
                        <includes>
                            <include>**/*.jar</include>
                        </includes>
                </resource>
            </webResources>
        </configuration>
 </plugin>

-----------------Another Way-------------------- - - - - - - - - -其他方式 - - - - - - - - - -

You can using this plugin to replace maven-war-plugin : 您可以使用此插件替换maven-war-plugin

 <plugin>  
      <artifactId>maven-compiler-plugin</artifactId>  
       <configuration>  
            <source>1.8</source>  
            <target>1.8</target>  
            <compilerArguments>  
                <extdirs>${project.basedir}/lib</extdirs>  
            </compilerArguments>  
      </configuration>  
</plugin>  

And add the resource: 并添加资源:

<resources>  
    <resource>  
        <directory>lib</directory>  
        <targetPath>BOOT-INF/lib/</targetPath>  
        <includes>  
            <include>**/*.jar</include>  
        </includes>  
    </resource>
    <resource>
        <directory>src/main/resources</directory>
        <targetPath>BOOT-INF/classes/</targetPath>
    </resource> 
</resources>

It seems to me, that when you try to run the jar you doesn't specify the classpath for this run, therefore the .jar file you want is missing. 在我看来,当您尝试运行jar时,您没有为此运行指定类路径,因此缺少所需的.jar文件。

Either use Maven plugin to bundle the dependencies inside the jar, which will produce the jar with all the dependencies packed. 要么使用Maven插件来捆绑jar中的依赖项,这将生成包含所有依赖项的jar。

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <mainClass>cz.gisat.eoapps.viz.Main</mainClass>
            </manifest>
        </archive>
        <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
    </configuration>
    <executions>
        <execution>
            <id>make-assembly</id> <!-- this is used for inheritance merges -->
            <phase>package</phase> <!-- bind to the packaging phase -->
            <goals>
                <goal>single</goal>
            </goals>
        </execution>
    </executions>
</plugin>

or make sure that you the manifest inside the .jar file is present and contains classpath for all the additional jars. 或确保.jar文件中的清单存在并包含所有其他jar的类路径。

mvn clean package will not pack the dependency jars into the target jar. mvn clean package不会将依赖jar包装到目标jar中。 You should set -classpath to point to all the dependency jars when running java -jar target/prome-data.jar . 在运行java -jar target/prome-data.jar时,应该将-classpath设置为指向所有依赖项jar。

Your problem is that the system scope doesn't work with the assembly plugin, which Spring Boot uses to build the "all-included" jar. 您的问题是系统范围不适用于程序集插件,Spring Boot使用它来构建“全包”jar。

If you want your third party lib to be included in the "all-included" jar built by the spring boot plugin then you should depend on that third party lib in the "maven way" via repository. 如果您希望第三方lib包含在spring boot插件构建的“all-included”jar中,那么您应该通过存储库以“maven方式”依赖第三方lib。

If you don't want to create / maintain a real full fledged repository for that lib (understandable in a small project / small number of third party libs) then the preferred solution is to store them in a project related local repository. 如果您不想为该lib创建/维护一个真正完整的存储库(在小项目/少量第三方库中可以理解),那么首选的解决方案是将它们存储在项目相关的本地存储库中。 That repository (basically a quite static directory structure) can even be committed to source control. 该存储库(基本上是一个非常静态的目录结构)甚至可以提交给源代码控制。

Here is an excellent albeit old example from Pascal Thivent: 这是Pascal Thivent的一个很好的例子:

Maven: add a dependency to a jar by relative path Maven:通过相对路径为jar添加依赖项

I've just checked it against maven 3.3 and it works. 我刚刚对maven 3.3进行了检查,它确实有效。 Working example: 工作范例:

http://peter.risko.hu/java_incubator/spring_boot_with_3rd_party_lib_in_project_relative_local_repo.zip http://peter.risko.hu/java_incubator/spring_boot_with_3rd_party_lib_in_project_relative_local_repo.zip

Note also, that Spring Boot hides the complexities of creating the "all included" jar. 另请注意,Spring Boot隐藏了创建“all included”jar的复杂性。 So you should not mess manually with the assembly plugin here. 所以你不应该在这里手动使用程序集插件。

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

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