简体   繁体   English

如何仅使用 javac 和 jar 编译和运行可运行的 JAR

[英]How to compile and run a runnable JAR using only javac and jar

How can I compile and run a runnable JAR file using only javac and jar ?如何仅使用javacjar编译和运行可运行的 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 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如何正确运行此 JAR 和java

I have tried building the JAR like this:我试过像这样构建 JAR:

$ 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:然后我尝试了各种方法来执行 JAR,但都没有奏效:

$ 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:我的代码,只是为了显示我有一个Example class 和一个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.我的javacjarjava工具都是 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. 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.

Thanks to @f1sh and @pdem, I found an answer:感谢@f1sh 和@pdem,我找到了答案:

$ 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. 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.至于使 JAR 可执行,需要清单文件。 A manifest file can be created manually, or you can let jar create it for you with the e option.可以手动创建清单文件,也可以让jar使用e选项为您创建它。 The general format for using the e option is使用e选项的一般格式是

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 .有关使用e选项或手动编写清单文件的更多信息,请参阅设置应用程序的入口点使用清单文件:基础知识的其他子页面之一。

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注意 jar 的倒数第二个参数是主jar的名称

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM