Marcello Fabrizio
Marcello Fabrizio

Reputation: 337

"ClassNotFoundException" while trying to run .jar file

I have a .jar that I built following the Oracle docs, using jar cfm hangman.jar Manifest.txt src/classes/app/Main.class. The manifest.txt file contains Main-Class as classes.app.Main, telling where my Main class is. When executed, ClassNotFoundException is thrown, saying it couldn't find classes.app.Main. I need help trying to understand what's wrong here. Is it the main class or maybe a missing classpath?

Here's the project tree:

.
├── hangman.jar
├── Manifest.txt
├── README.md
└── src
    ├── app
    │   ├── Main.java
    │   ├── Player.java
    │   ├── Players.java
    │   ├── Play.java
    │   ├── Themes.java
    │   ├── Word.java
    │   └── Words.java
    └── classes
        └── app
            ├── Main.class
            ├── Play.class
            ├── Player.class
            ├── Players.class
            ├── Themes.class
            ├── Word.class
            └── Words.class


Upvotes: 0

Views: 239

Answers (1)

dave_thompson_085
dave_thompson_085

Reputation: 38821

You don't show the code, but it is extremely likely that the package for your class is just app not classes.app, and classes is only a directory name to contain the class files, not actually part of the package hierarchy. The name of a class file entry in a jar, OR the name of a class file relative to a classpath directory, must be exactly a directory path equal to the package hierarchy (if any) plus the class name and the suffix .class, with nothing added or removed. This means your jar should be created by going to the classes directory and then adding the file(s) relative to that directory:

 jar cfm hangman.jar Manifest.txt -C classes app/Main.class 

and the Main-class entry in the manifest should be app.Main. If you only need main-class in the manifest and nothing else (except version, IIRC), you can have jar create it for you:

 jar cfe hangman.jar app.Main -C classes app/Main.class

Also I note that there are other classes in your source tree. If these classes are called or referenced from the Main class, directly or indirectly (i.e. nested), they must also be in the jar. You probably want to use app/* instead, although it is possible you want or even need to be more selective.

Meta: I thought this was covered in the standard tutorial, but although most of the pieces are there they aren't really pulled together anyplace I could find and refer to.

Upvotes: 2

Related Questions