How can I compile and run a runnable JAR file using only javac
and jar
? I don't want to build the JAR file with an IDE or with tools like Gradle, Maven, or Ant, because I want to understand, for my own edification, how I can compile a runnable JAR using only javac
and jar
, and then how to correctly run this JAR with java
.
I have tried building the JAR like this:
$ javac Example.java $ file Example.class Example.class: compiled Java class data, version 55.0 $ jar cvf Example.jar Example.class added manifest adding: Example.class(in = 682) (out= 456)(deflated 33%) $ file Example.jar Example.jar: Java archive data (JAR)
Then I tried various ways to execute the JAR, but none of them worked:
$ java -jar Example.jar main no main manifest attribute, in Example.jar $ java -cp '.;Example.jar' main Error: Could not find or load main class main Caused by: java.lang.ClassNotFoundException: main $ java -cp '.;Example.jar' Example Error: Could not find or load main class Example Caused by: java.lang.ClassNotFoundException: Example $ java -cp '.;Example.jar' -jar Example.jar Example no main manifest attribute, in Example.jar $ java -cp '.;Example.jar' -jar Example.jar main no main manifest attribute, in Example.jar
My code, just to show I have an Example
class and a main()
function:
import java.util.ArrayList;
import java.util.List;
public class Example {
private static class A {
public int x = 7;
}
public static void main(String[] args) {
List<A> list = new ArrayList<>();
A a = new A();
list.add(a);
a.x = 5;
System.out.println(a.x);
System.out.println(list.get(0).x);
}
}
My javac
, jar
, and java
tools are all version 11.0.15.
I tried looking at the answers on Compile and run with javac and java using classpath classes in jar and javac compiles files and jars but java fails, but none of the suggestions in the answers to these two questions worked for me.
CodePudding user response:
Thanks to @f1sh and @pdem, I found an answer:
$ javac Example.java $ jar cfe Example.jar Example Example.class 'Example$A.class' $ java -jar Example.jar 5 5
Is @f1sh points out in there comment, I needed to (A) include the Example$A.class
class when creating the JAR, and (B) run the java
command with the correct arguments.
As for making the JAR executable, a manifest file is required. A manifest file can be created manually, or you can let jar
create it for you with the e
option. The general format for using the e
option is
java cfe <name of jar> <name of main class> <list of .class files>
For more info on using the e
option or writing a manifest file by hand, see Setting an Application's Entry Point or one of the other child pages of Working with Manifest Files: The Basics.
CodePudding user response:
goose@t410:/tmp$ javac Example.java
goose@t410:/tmp$ jar cvfe example.jar Example Example*.class
added manifest
adding: Example$A.class(in = 293) (out= 233)(deflated 20%)
adding: Example.class(in = 682) (out= 457)(deflated 32%)
goose@t410:/tmp$ java -jar example.jar
5
5
Note the penultimate argument to jar
is the name of the main class