7

Hello guys I am new to Maven and I am trying to integrate slf4j in a maven project Here is my pom.xml file

<dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>slf4j-api</artifactId>
 <version>1.7.9</version>
</dependency>

And I have these two lines in my main function

Logger logger = LoggerFactory.getLogger(App.class);
logger.info("Hello World");

Project is compiled and packaged successfully but when I try to run it through
java -cp target/maven-1.0-SNAPSHOT.jar com.goutam.maven.App The following Exception is thrown

Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
    at com.goutam.maven.App.main(App.java:11)
Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)

4 Answers4

2

build fat jar with maven

add this to your pom.xml

<build>
  <plugins>
  <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.5.3</version>
        <configuration>
            <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
            </descriptorRefs>

        </configuration>
        <executions>
            <execution>
                <id>assemble-all</id>
                <phase>package</phase>
                <goals>
                    <goal>single</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
    </plugins>
    </build>

and then run

java -cp target/maven-jar-with-dependencies-1.0-SNAPSHOT.jar com.goutam.maven.App

note: pick the jar file which has jar-with-dependencies

Community
  • 1
  • 1
jmj
  • 237,923
  • 42
  • 401
  • 438
2

Maven will not by itself bundle all dependencies for you, so your resulting "maven-1.0-SNAPSHOT.jar" does not contains sl4j (nor any of its own dependencies).

If you want your command line to work, you need to include all the librairies inside your jar. This can be achieved using the Maven Assembly Plugin with something like:

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.5.3</version>
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
      <archive>
        <manifest>
          <mainClass>org.sample.App</mainClass>
        </manifest>
      </archive>
    </configuration>
    <executions>
      <execution>
        <id>make-assembly</id> 
        <phase>package</phase>
        <goals>
          <goal>single</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
Ahmed Nabil
  • 17,392
  • 11
  • 61
  • 88
Martin
  • 7,634
  • 1
  • 20
  • 23
1

I don't like the idea of building fat jars, as we loose some flexibilities in this approach.

Rather would advocate for copy-dependencies plugin in maven.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.9</version>
    <executions>
      <execution>
        <id>copy-dependencies</id>
        <phase>install</phase>
        <goals>
          <goal>copy-dependencies</goal>
        </goals>
        <configuration>
          <outputDirectory>${project.build.directory}/lib</outputDirectory>
          <overWriteReleases>false</overWriteReleases>
          <overWriteSnapshots>false</overWriteSnapshots>
          <overWriteIfNewer>true</overWriteIfNewer>
        </configuration>
      </execution>
    </executions>
  </plugin>

Coupling it along with maven-jar-plugin. Read this for details.

Assuming the third party dependencies are copied into target/lib folder.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.5</version>
    <configuration>
        <archive>
            <manifest>
                <mainClass>main class</mainClass>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
            </manifest>
        </archive>
    </configuration>
</plugin>
Himanshu Bhardwaj
  • 4,038
  • 3
  • 17
  • 36
0

Two other answers recommend maven-assembly-plugin. I think you're generally better served with the maven-shade-plugin.

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>2.3</version>
        <configuration>
          <!-- put your configurations here -->
        </configuration>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  ...
</project>
lexicore
  • 42,748
  • 17
  • 132
  • 221