4

I have a spring boot project based on maven.

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

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. But when I tried to run the package jar with:

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

Stacktrace is like:

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

Is there anything I am missing

Community
  • 1
  • 1
JaskeyLam
  • 15,405
  • 21
  • 114
  • 149

4 Answers4

6

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.

After you deploy the jar to a server or run the jar locally, then it may throws ClassNotFoundException.

If you are using spring-boot, you still need below plugin:

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

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:

 <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>
Chao Jiang
  • 483
  • 3
  • 13
3

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.

Either use Maven plugin to bundle the dependencies inside the jar, which will produce the jar with all the dependencies packed.

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

Lucky
  • 16,787
  • 19
  • 117
  • 151
Jakub Balhar
  • 315
  • 1
  • 7
1

mvn clean package will not pack the dependency jars into the target jar. You should set -classpath to point to all the dependency jars when running java -jar target/prome-data.jar.

free6om
  • 438
  • 3
  • 10
1

Your problem is that the system scope doesn't work with the assembly plugin, which Spring Boot uses to build the "all-included" 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.

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

Maven: add a dependency to a jar by relative path

I've just checked it against maven 3.3 and it works. Working example:

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. So you should not mess manually with the assembly plugin here.

Community
  • 1
  • 1
riskop
  • 1,693
  • 1
  • 16
  • 34