简体   繁体   English

无法执行jar文件

[英]Cannot execute jar file

Have some technical trouble with compiling Java jar file with command line. 使用命令行编译Java jar文件时遇到一些技术问题。

I have these two .java files in the same directory 我在同一目录中有这两个.java文件

// Source.java // Source.java

package home;

public class Source {

  public Source(){
     System.out.println("This is the source.");
  }

  public static void main(String[] s){
     System.out.println("this is England.");
     System.out.println("ok 1 - Input file close");
     new Source();
     new Other();
     System.exit(3);
  }

}

// Other.java // Other.java

package home;

public class Other {

  public Other(){
     System.out.println("More source here.");
  }


}

I compile these two files into a .jar file like so: 我将这两个文件编译成.jar文件,如下所示:

#!/usr/bin/env bash

javac $(dirname "$0")/*.java
jar cmf MyJar.jar Manifest.txt *.class

the Manifest.txt file just contains these three lines: Manifest.txt文件仅包含以下三行:

   Manifest-Version: 1.0
   Created-By: <Your info>
   Main-Class: home.Source

However when I try to execute the jar file with: 但是,当我尝试使用以下命令执行jar文件时:

#!/usr/bin/env bash
java -jar MyJar.jar 

I get this error: 我收到此错误:

Error: Could not find or load main class home.Source

I have no idea what to do now. 我不知道该怎么办。 Anybody know what's wrong? 有人知道怎么了吗? Perhaps I am using the wrong command to generate the .jar file? 也许我使用了错误的命令来生成.jar文件?

As a check, I run jar tf : 作为检查,我运行jar tf

bash-3.2$ jar tf MyJar.jar
META-INF/
META-INF/MANIFEST.MF
Other.class
Source.class

The issue is that your classes are in a package, and in the jar file should be within a directory - this is encoded in the error message: note the "class home.Source" - java will look for the Source class in a directory called home, whether a native directory or a directory in a jar (all of which must be on the classpath - the contents of an executable jar are automatically added). 问题是您的类在一个包中,并且jar文件中的目录应该在目录内-这在错误消息中进行了编码:请注意“ class home.Source”-Java将在名为的目录中查找Source类。 home,无论是本机目录还是jar中的目录(所有目录都必须位于类路径上-可执行jar的内容会自动添加)。

When using javac it is recommended to specify a target output directory with the -d flag as doing so will create the directory structure for any packages that classes are in. 使用javac时,建议使用-d标志指定目标输出目录,因为这样做会为所有类所在的包创建目录结构。

eg: 例如:

javac -d bin/ $(dirname "$0")/*.java
jar cmf MyJar.jar Manifest.txt -C bin/ *

the -C flag changes directory to the bin/ directory which contains your output package structure, and the * includes everything (you could, of course, use home/*.class here or anything else which will return the full relative path from the new CWD to the target class files). -C标志将目录更改为bin/目录,该目录包含您的输出包结构,而*包含所有内容(您当然可以在此处使用home/*.class或任何其他将从新目录返回完整相对路径的内容CWD到目标类文件)。

Alternatively, you could move the classes to the relevant directories yourself, or compile them there, but it's generally better to let javac do it based on the package declaration in the source. 或者,您可以自己将类移动到相关目录,或在此处进行编译,但是通常最好让javac根据源代码中的包声明来执行。

Finally, consider using gradle, maven or even ant to build your projects as they are all designed to avoid this kind of problem. 最后,考虑使用gradle,maven甚至ant来构建您的项目,因为它们都是为了避免这种问题而设计的。

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

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