Search code examples
javalinuxmaventerminallanterna

Code runs inside IDE but fails outside


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?


Solution

  • 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>