【问题标题】:ClassNotFoundException after include local jar to maven project将本地 jar 包含到 maven 项目后的 ClassNotFoundException
【发布时间】:2016-06-23 10:25:41
【问题描述】:

我有一个基于maven的spring boot项目。

我必须包括一个由另一个团队提供的本地 jar。所以我按照接受的答案来自:How to include local jar files in Maven project

所以我使用:

<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>

这在 IDEA 上运行良好。但是当我尝试使用以下命令运行包 jar 时:

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

Stacktrace 是这样的:

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

有什么我想念的

【问题讨论】:

  • 您是否已在本地 m2 存储库中成功安装了您的 jar?如果有,你是怎么做到的?
  • @Lucky ,我想没有。我们是 Maven 新手。

标签: java spring maven


【解决方案1】:

我今天也遇到了类似的问题,搞了半天才解决。

在大多数情况下,使用下面的开发是很好的。

<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>

如果你把jar放到正确的路径下,那么IDEAEclipse都可以运行。

将jar部署到服务器或本地运行jar后,可能会抛出ClassNotFoundException

如果你使用的是spring-boot,你还需要下面的插件:

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

运行mvn clean package后,可以在/BOOT_INF/lib下找到jar。

如果你的包是war,那么你还需要这个插件:

 <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>

-----------------另一种方式--------------------

你可以用这个插件替换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>  

并添加资源:

<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>

【讨论】:

  • 为 includeSystemScope 点赞
【解决方案2】:

在我看来,当您尝试运行 jar 时,您没有为此运行指定类路径,因此您想要的 .jar 文件丢失了。

使用 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>

或确保 .jar 文件中的清单存在并包含所有其他 jar 的类路径。

【讨论】:

    【解决方案3】:

    mvn clean package 不会将依赖 jar 打包到目标 jar 中。在运行java -jar target/prome-data.jar 时,您应该将-classpath 设置为指向所有依赖jar。

    【讨论】:

      【解决方案4】:

      您的问题是系统范围不适用于 Spring Boot 用于构建“全包”jar 的程序集插件。

      如果您希望您的第三方库包含在 spring boot 插件构建的“全包”jar 中,那么您应该通过存储库以“maven 方式”依赖该第三方库。

      如果您不想为该库创建/维护一个真正完整的存储库(在小型项目/少量第三方库中可以理解),那么首选的解决方案是将它们存储在与项目相关的本地存储库中。该存储库(基本上是一个非常静态的目录结构)甚至可以提交到源代码控制。

      这是来自 Pascal Thivent 的一个很好的例子:

      Maven: add a dependency to a jar by relative path

      我刚刚对照 maven 3.3 检查了它,它可以工作。工作示例:

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

      还要注意,Spring Boot 隐藏了创建“全部包含”jar 的复杂性。所以你不应该在这里手动弄乱组装插件。

      【讨论】:

        猜你喜欢
        • 2014-02-05
        • 2020-10-27
        • 1970-01-01
        • 2016-11-17
        • 2017-11-06
        • 2019-10-21
        • 2011-04-15
        • 2018-12-19
        • 1970-01-01
        相关资源
        最近更新 更多