Reputation: 749
I am creating a client and a server wrapper for a neural network. The client reads and sends an image to the server who runs the models and responds the results back to client. I have created a multimodule project for this reason. When i run client and server from IDE (intellij idea) everything works ok. However when i use maven to build and then run from terminal i get errors.
My main/parent pom.xml is the following:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>gr.enomix</groupId>
<artifactId>imageClassificationWrapper</artifactId>
<packaging>pom</packaging>
<version>1.0</version>
<modules>
<module>Server</module>
<module>Client</module>
</modules>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencies>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
<version>2.0.5</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
My Server pom.xml is:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>imageClassificationWrapper</artifactId>
<groupId>gr.enomix</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>gr.enomix</groupId>
<artifactId>Server</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
</project>
And my client pom.xml is:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>imageClassificationWrapper</artifactId>
<groupId>gr.enomix</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>gr.enomix</groupId>
<artifactId>Client</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
</project>
I want all libraries from parent pom.xml to be inherited to both children client and server. Then i run from terminal mvn clean install and the project successfully builds without any error.
Then finally i execute
java -cp target/Server-1.0.jar RunServer
to run the server and
java -cp target/Client-1.0.jar RunClient
to run the client but i get errors
Exception in thread "main" java.lang.NoClassDefFoundError: org/json/simple/JSONObject
at ImageHttpClient.sendImage(ImageHttpClient.java:78)
at RunClient.main(RunClient.java:11)
from both client and server.
Exception in thread "Thread-0" java.lang.NoClassDefFoundError: org/apache/commons/io/IOUtils
at Handlers.ConnectionHandler.readAndSaveImage(ConnectionHandler.java:39)
at Handlers.ConnectionHandler.run(ConnectionHandler.java:25)
at java.lang.Thread.run(Thread.java:745)
Maven dependencies are not build in class path??? Am i doing something wrong?? Please Help i am breaking my head two days now...
Upvotes: 0
Views: 80
Reputation: 3117
When you develop an standalone Java application, your dependencies are all being used only for the compilation phase. When you want to run your actual code, Java virtual machine needs to have the address of given dependencies to run your code. In order to do that, you've to tell the Java virtual machine explicitly where to find the libraries. You can add all libraries to your -cp
option like this:
java -cp {your-maven-repository-folder}/org/apache/common/commons-io/commons-io-1.3.2.jar:target/Client-1.0.jar RunClient
in which {your-maven-repository-folder} normally is in your user's home folder. For example in linux it is /home/mixtou/.m2/repository
.
You need to specify all your dependencies separating them with :
in linux and ;
in windows.
As you're already using IntelliJ, one simpler solution could be to right click on your RunClient
or RunServer
class and select Run
. By doing so IntelliJ will try to run your project in the Run panel
and if you check the very first line in the run output, you should see the exact command that IntelliJ is using to run your code which includes all necessary libraries.
Remember that in an standalone Java applications, no dependency would be included into your jar file. Such an option is only available in applications that are going to be run on an application server as war
or ear
file. Of course you can use some maven plugins that merge all your libraries into your jar file (which is normally known as fat jar) and then you would not need to specify anything in classpath, but then your jar file may become too big (depends on the number of libraries you use) and so updating that would be more cumbersome.
Upvotes: 0
Reputation: 947
Your dependencies are not included in the .jar
file and therefore they cannot be found. Hence the NoClassDefFoundError
What you have to do is to include the dependencies in your jar, i.e. build a so called "fat jar".
I will not post how to do that, since there are already a lot of posts on stackoverflow. As I see you already have some in the comments.
EDIT: To test if your dependencies have been included, you can open the generated .jar
file using 7zip.
Upvotes: 1
Reputation: 574
I think you should use dependencyManagement tag inside parent pom in order to let child poms inherit dependencies.
Check this link
differences between dependencymanagement and dependencies in maven
Upvotes: 0