0

I have a simple java code, App.java. I am trying to import the apache commons Fraction class from the apache commons math3 library. So, as a sample code, I put this in my App.java:

package myApp;
import org.apache.commons.math3.fraction.Fraction;

public class App 
{
    public static void main( String[] args )
    {
        Fraction f = new Fraction(2, 3);
        System.out.println( "Hello World!" );
        System.out.println( f );
    }
}

Using the following 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>myApp</groupId>
  <artifactId>Proj1</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>Proj1</name>
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-math3 -->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-math3</artifactId>
        <version>3.6.1</version>
    </dependency>

  </dependencies>

  <build>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
        <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
        <plugin>
          <artifactId>maven-site-plugin</artifactId>
          <version>3.7.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-project-info-reports-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-shade-plugin</artifactId>
          <version>3.2.4</version>
          <configuration>
            <!-- put your configurations here -->
          </configuration>
          <executions>
            <execution>
              <phase>package</phase>
              <goals>
                <goal>shade</goal>
              </goals>
            </execution>
          </executions>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

I have tried to put the plugin suggested by utdemir in his answer to a similar question, but in my case, when I run:

mvn package
java -cp target/Proj1-1.0-SNAPSHOT.jar myApp.App

While it apparently compiles properly, I get the following error:

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/math3/fraction/Fraction
        at myApp.App.main(App.java:8)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.math3.fraction.Fraction
        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

What should I do?

  • Are any of these answers helpful? https://stackoverflow.com/questions/58673427/noclassdeffounderror-with-apache-commons-math – Nora Na Nov 06 '21 at 11:42
  • They all mention that we need to add a JAR file somewhere. Is there any way for Maven to add the jar automatically? – Tahmin Ahmed Nov 06 '21 at 11:57

1 Answers1

1

Its much easier to run your app using mvn, rathen than by calling java directly. This is because in the later case you need to manually set the classpath to the correct value using the -cp flag. This can lead to errors, like in your case.

Here's how you can run your app using mvn

mvn exec:java -Dexec.mainClass="myApp.App"

More details can be found here

Arthur Klezovich
  • 2,595
  • 1
  • 13
  • 17
  • This is it! I was also looking for a way to use maven to automatically download any additional dependencies. The exec command does exactly that. Thank you! – Tahmin Ahmed Nov 06 '21 at 11:58