1

What I've done

I created a maven project with IntelliJ IDEA, following a tutorial.

The tiny project in JDK11 is to demo (for myself) how com.google.code.gson serializes an object to a json string.

This project's POM 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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>mig</groupId>
    <artifactId>mia</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!--  Gson: Java to Json conversion -->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.6</version>
        </dependency>
    </dependencies>
    
    <properties>
        <maven.compiler.release>11</maven.compiler.release>
    </properties>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.1</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

</project>

In Employee.java, I did generated the setters and getters though I don't put them here to save some space.

public class Employee
{
   private Integer id;
   private String firstName;
   private String lastName;
   private List<String> roles;
    
   public Employee(){      
   }
    
   public Employee(Integer id, String firstName, String lastName, Date birthDate){
      this.id = id;
      this.firstName = firstName;
      this.lastName = lastName;
   }
    
   //Getters and setters
    
   @Override
   public String toString()
   {
      return "Employee [id=" + id + ", firstName=" + firstName + ", " +
            "lastName=" + lastName + ", roles=" + roles + "]";
   }
}

O2Json.java

package mig;

import java.util.Arrays;
import com.google.gson.*;

public class O2Json {
    public static void main(String[] args) throws Exception{
        Employee employee = new Employee();
        employee.setId(1);
        employee.setFirstName("Lokesh");
        employee.setLastName("Gupta");
        employee.setRoles(Arrays.asList("ADMIN", "MANAGER"));
        System.out.println(employee.toString());

        Gson gson = new Gson();
        System.out.println(gson.toJson(employee));
    }
}

The project consists of the following standard project structure

mvn_idea 
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   ├── Employee.java
    │   │   └── O2Json.java
    │   └── resources
    └── test
        └── java

Everything goes well with IntelliJ IDEA on my mac when I run the app using Run menu command of IDEA.

enter image description here

This command generates an executable JAR with IntelliJ IDEA

/Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home/bin/java -Dmaven.multiModuleProjectDirectory=/Users/ubuntu/sourcecode/mvn_idea "-Dmaven.home=/Applications/IntelliJ IDEA CE.app/Contents/plugins/maven/lib/maven3" "-Dclassworlds.conf=/Applications/IntelliJ IDEA CE.app/Contents/plugins/maven/lib/maven3/bin/m2.conf" "-javaagent:/Applications/IntelliJ IDEA CE.app/Contents/lib/idea_rt.jar=65438:/Applications/IntelliJ IDEA CE.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath "/Applications/IntelliJ IDEA CE.app/Contents/plugins/maven/lib/maven3/boot/plexus-classworlds-2.5.2.jar" org.codehaus.classworlds.Launcher -Didea.version2019.1.3 install

However, this method is not as convenient on a Ubuntu server which I connect via SSH.

So I tried to do the job with the command line tool mvn.

mvn package seemed to work well

[INFO] Building jar: /Users/ubuntu/sourcecode/mvn_idea/target/mia-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:13 min
[INFO] Finished at: 2021-05-16T09:41:04+08:00
[INFO] Final Memory: 18M/74M
[INFO] ------------------------------------------------------------------------

However, when I tried to run the app, the error showed up

$ java -cp target/mia-1.0-SNAPSHOT.jar mig.O2Json
mig.Employee [id=1, firstName=Lokesh, lastName=Gupta, roles=[ADMIN, MANAGER]]
Exception in thread "main" java.lang.NoClassDefFoundError: com/google/gson/Gson
    at mig.O2Json.main(O2Json.java:15)
Caused by: java.lang.ClassNotFoundException: com.google.gson.Gson
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:636)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:182)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:519)
    ... 1 more

Questions

How do I fix this error?

Update

Here is the new version of POM

<?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>mig</groupId>
    <artifactId>mia</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!--  Gson: Java to Json conversion -->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.6</version>
        </dependency>
    </dependencies>

    <properties>
        <maven.compiler.release>11</maven.compiler.release>
    </properties>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <executions>
                        <execution>
                            <phase>package</phase>
                            <goals>
                                <goal>single</goal>
                            </goals>
                        </execution>
                    </executions>
                    <configuration>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                    </configuration>
                </plugin>

            </plugins>
        </pluginManagement>
    </build>

</project>

I executed mvn clean, mvn package and java -cp target/mia-1.0-SNAPSHOT.jar mig.O2Json and got the same error.

I also tried mvn clean compile assembly:single and java -cp target/mia-1.0-SNAPSHOT.jar mig.O2Json and got the same error.

JJJohn
  • 915
  • 8
  • 26
  • I updated the answer. After you move the plugin section in your pom, make sure you change your java command to point to the new jar, which will be called *-with-dependencies – Vlad L May 16 '21 at 03:13

1 Answers1

1

You need to tell maven to include the dependencies. When IntelliJ runs it for you, it adds all the dependencies to the classpath, which is why it works from IntelliJ.

Try this

If you run mvn package and unzip the resulting jar with your updated pom.xml, you will see the dependencies are still not included.

The reason for this is that you need to put

                <plugin>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <executions>
                        <execution>
                            <phase>package</phase>
                            <goals>
                                <goal>single</goal>
                            </goals>
                        </execution>
                    </executions>
                    <configuration>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                    </configuration>
                </plugin>

under

    <build>
        <plugins>
                <plugin>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <executions>
                        <execution>
                            <phase>package</phase>
                            <goals>
                                <goal>single</goal>
                            </goals>
                        </execution>
                    </executions>
                    <configuration>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                    </configuration>
                </plugin>
        </plugins>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.1</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

Not inside pluginManagement. I tried it, it generates a jar called ...-with-dependencies and your java command then runs fine.

Vlad L
  • 1,544
  • 3
  • 6
  • 20