1

I am trying to write a maven integrated Java API. I have included log4j for logging purpose. Which works well when running through eclipse, but when maven package is done and the jar is run it is unable to run from cmd line using java -jar jar_name.jar throwing an error

  Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/Logger

Now the log4j.properties file is placed under src/main/resources folder. And the pom.xml is mentioned. Have tried searching for answers but none worked for me. Any help available

           <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>Weather_Simulator</groupId>
     <artifactId>weather_simulator</artifactId>
     <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>weather_simulator</name>
 <url>http://maven.apache.org</url>

 <build>
<plugins>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>3.0.2</version>
     <configuration>
      <archive>
        <manifest>
          <addClasspath>true</addClasspath>
          <mainClass>com.test.weather.simulator.MainClass</mainClass>
        </manifest>
      </archive>
    </configuration>
  </plugin>

  <plugin>
    <!-- NOTE: We don't need a groupId specification because the group is
         org.apache.maven.plugins ...which is assumed by default.
     -->
    <artifactId>maven-assembly-plugin</artifactId>
    <version>3.0.0</version>
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
    </configuration>
    </plugin>
</plugins>
  </build>

  <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 </properties>

      <dependencies>
    <dependency>
            <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
    <version>3.6.1</version>
</dependency>

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-configuration2</artifactId>
    <version>2.1.1</version>
</dependency>

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>3.8.1</version>
  <scope>test</scope>
</dependency>


<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.6.1</version>
    <scope>test</scope>
</dependency>

<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>

Chetan chadha
  • 558
  • 1
  • 4
  • 19
Ashit_Kumar
  • 601
  • 2
  • 10
  • 28
  • What does `maven integrated API` mean? Is your resulting JAR a plugin, a library or an application? For libraries and plugins the runtime and compile scope dependencies are included automatically, for an application you need to either embed them or provide them yourself. In case of `Java -jar` you typically have to embed all. – eckes Aug 12 '17 at 13:40

3 Answers3

3

Your <scope> in your pom.xml appears to be wrong. Try this (notice I've changed "test" to "compile").

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.6.1</version>
    <scope>compile</scope>    <!-- look here -->
</dependency>

The way you currently have your pom.xml configured (with "test"), maven will only provide the log4j jar when doing "mvn test". If you need the jar at both compile time and run time (which is the scenario that appears to be causing problems for you), the scope needs to be "compile".

Note that "compile" is the default scope, so if you leave the <scope> element off, the scope will be "compile".

From the maven docs: "This [compile] is the default scope, used if none is specified. Compile dependencies are available in all classpaths of a project. Furthermore, those dependencies are propagated to dependent projects"

For more info about maven "scopes" look here.

StvnBrkdll
  • 3,924
  • 1
  • 24
  • 31
1

This is a classpath problem, the jar generated by Maven contains only your classes. To fix this you can pack all the dependencies inside your project jar: How can I create an executable JAR with dependencies using Maven?

rodrigoap
  • 7,405
  • 35
  • 46
0

There are two things you should be aware if you like to create an executable jar which contains all dependent jars you have to use maven-assembly-plugin as you already did but you forgot to bind it to the life cycle...which looks like this:

<project>
  [...]
  <build>
    [...]
    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>3.0.0</version>
        <configuration>
          <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>
      [...]
</project>

Furthermore having plugins as dependencies is simply wrong..

<dependency>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.6.1</version>
</dependency>

This means remove this entry from your pom file.

Defining a dependency with a scope test means it will be available only during the unit tests which means also it will never being packaged into a resulting jar file. This means you have to change the following:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.6.1</version>
    <scope>test</scope>
</dependency>

into the following:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.6.1</version>
</dependency>

After you have fixed those issues you should be able to build your app via:

mvn clean package

and find the resulting jar file which contains the dependencies in the target directory named like weather_simulator-1.0.0-SNAPSHOT-jar-with-dependencies.jar which you should use to call your app.

khmarbaise
  • 92,914
  • 28
  • 189
  • 235