Code runs inside IDE but fails outside

1k Views Asked by At

I am trying to run an example code with Java Lanterna for a terminal GUI. Running the example within Netbeans 8.2 IDE successfully runs (essentially klicking the 'Play' button), but running the JAR file from the Linux terminal fails.

Main.java:

package com.glasses.lanternatest;

import com.googlecode.lanterna.TerminalFacade;
import com.googlecode.lanterna.screen.Screen;
import com.googlecode.lanterna.terminal.Terminal;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Screen screen = TerminalFacade.createScreen();
        screen.startScreen();
        screen.putString(10, 5, "Hello World!", Terminal.Color.WHITE, Terminal.Color.BLACK);
        screen.refresh();
        Thread.sleep(3000);
        screen.stopScreen();
        System.exit(0);
    }
}

pom.xml:

<?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>com.glasses</groupId>
    <artifactId>LanternaTest</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <build>
        <plugins>
            <plugin>
                <!-- Build an executable JAR -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.0.2</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>lib/</classpathPrefix>
                            <mainClass>com.glasses.lanternatest.Main</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>com.googlecode.lanterna</groupId>
            <artifactId>lanterna</artifactId>
            <version>2.1.9</version>
        </dependency>
    </dependencies>
</project>

The error I get when running the resulting JAR file from the terminal:

myuser@mylaptop:~$ java -jar /home/myuser/NetBeansProjects/LanternaTest/target/LanternaTest-1.0-SNAPSHOT.jar
Exception in thread "main" java.lang.NoClassDefFoundError: com/googlecode/lanterna/TerminalFacade
    at com.glasses.lanternatest.Main.main(Main.java:14)
Caused by: java.lang.ClassNotFoundException: com.googlecode.lanterna.TerminalFacade
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496)
    ... 1 more

Why does running the code through the Linux terminal fail? Why doesn't it find the class com.googlecode.lanterna.TerminalFacade when run from the terminal, but successfully finds it when run the same code from within Netbeans 8.2 pressing the 'Play' button?

3

There are 3 best solutions below

1
Karol Dowbecki On BEST ANSWER

Your NetBeans project execution classpath is simply different than your command line execution classpath.

Instead of using maven-jar-plugin to put classpath entries into META-INF/MANIFEST.MF it might be easier to use maven-shade-plugin to build a self-contained uber jar. Because this uber jar will include all the dependencies of your Maven module it won't have external classpath requirements, as per shade mojo docs:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <version>3.1.0</version>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>shade</goal>
      </goals>
    </execution>
  </executions>
</plugin>
2
Jade On

You need what is called a Fat Jar. Basically, you are compiling your code, but not the library you are using. A Fat Jar compiles the libraries with your code.

Disclaimer: It is better style and coding practice to have your code load the library instead of packaging it with your code, however making a Fat Jar is easier.

0
Mister_Hanley On

Yes, I had the same problem...Thanks much for the suggestion....

Here is an excerpt my pom.xml from NetBeans Make sure you allow NB to create a package for you ...

<build>
<plugins>`enter code here`
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.2.4</version>
    <executions>
      <execution>
        <phase>package</phase>
        <goals>
          <goal>shade</goal>
        </goals>
        <configuration>
          <transformers>
            <transformer implementation=
                "org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
              <mainClass>
                hanleysoft.brian_park_polymorphic_rpg_lanterna_2.RPG_Main
              </mainClass>
            </transformer>
          </transformers>
        </configuration>
      </execution>
    </executions>
  </plugin>
</plugins>