1

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?

Socrates
  • 8,724
  • 25
  • 66
  • 113
  • did u run mvn clean install first? – HRgiger Mar 30 '18 at 22:20
  • According to your POM setup you need to have all your jar dependencies in a folder “lib” beside your JAR. – Strelok Mar 30 '18 at 22:35
  • @Strelok True, corrected that. Thank you. – Socrates Mar 30 '18 at 23:00
  • 1
    You need to configure maven to include your dependencies, for [example](https://stackoverflow.com/questions/24028921/in-maven-my-dependencies-are-set-up-but-i-get-a-classnotfoundexception-when-i-r/24030042#24030042) and [example](https://stackoverflow.com/questions/24899985/this-project-cannot-be-added-because-it-does-not-produce-a-jar-file-using-an-ant/24900260#24900260) – MadProgrammer Mar 30 '18 at 23:02

3 Answers3

1

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.

Jacob
  • 425
  • 3
  • 13
  • Your answer would be better if you included **how** to build your fat jar. As it is, this is only half of an answer. – SiKing Mar 30 '18 at 22:48
  • I don't use maven, I don't know the particular plugin to use. That is a simple google search that @Socrates can make. I simply diagnosed the problem. – Jacob Mar 30 '18 at 22:50
1

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>
Karol Dowbecki
  • 43,645
  • 9
  • 78
  • 111
  • This solved it. I added the `maven-shade-plugin` and also added the Main-class file to the manifest file using `...`. Works fine now as fat JAR. – Socrates Mar 30 '18 at 23:03
0

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>