【问题标题】:Java main method not recognized in jar file, but compiles fineJava main 方法在 jar 文件中无法识别,但可以正常编译
【发布时间】:2016-03-18 14:50:53
【问题描述】:

我想指出的第一件事是我不使用 IDE。我使用具有最少帮助的 Notepad++,我从 bash 或 DOS 编译和运行我的所有代码。在这种情况下,我尝试使用命令java -jar CharDefs.jar 将 Java 中的文件作为可执行 jar 文件运行,但它总是给我消息:Main method not found in LispDefs.CharDefs, please define the main method as: public static void main(String[] args).

到目前为止,我已经浏览了 Oracle 网站上的教程并创建了一个清单文件,方法是创建一个名为 Manifest.txt 的文本文件,其中包含 Main-Class: LispDefs.CharDefs 行和一个回车符。 我使用命令jar cfm LispDefs.jar Manifest.txt LispDefs/*.class 将其包含在我的 jar 文件中,如他们的教程中所示。 文件创建成功,但它仍然给我消息。但是,当我编译没有包头的文件并单独使用 java.exe 运行它时,它会成功运行。这是我的代码:

//package LispDefs;

public class CharDefs {
    public static void main(String[] args) {
        System.out.println(lChar("hello"));
        System.out.println(rChar("hello"));
    }

    public static String cChar(String var1, String var2) {
        return var1.concat(var2);
    }

    public static String lChar(String var1) {
        if (var1.length() == 0) {
            return new String();
        }

        if (var1.length() == 1) {
            return String.valueOf(var1.charAt(0));
        }

        return String.valueOf(var1.charAt(0));
    }

    public static String rChar(String var1) {
        if (var1.length() == 0) {
            return new String();
        }

        if (var1.length() == 1) {
            return new String();
        }

        String temp = new String();
        for (int k = 1; k < var1.length(); k++) {
            temp = temp.concat(String.valueOf(var1.charAt(k)));
        }

        return temp;
    }
}

我要做的是创建一个包含不同类的包,这些类允许不同层的 LISP 样式列表解析方法,这些方法可以通用地应用于不同的程序。现在,我只是尝试自己测试运行它,但它无法识别我在 jar 可执行文件中的主要方法。我阅读了其他文章并尝试了各种方法,似乎可能存在某种语义错误或我可能没有注意到的东西。我不太习惯 Java,因为我是从 python 移植这个概念。

【问题讨论】:

  • 你告诉你如何尝试和运行生成的 jar,而不是你如何实际尝试和编译这些东西;显示完整过程
  • 奇怪的代码。您可以极大地简化这些方法。您需要发布您的 Manifest 文件和 JAR 文件列表。
  • 具体来说,lChar()中的第二个ifrChar()中的ifs都可以去掉。
  • @MarquisofLorne 我无法再访问此代码,但当时并没有什么比这更多的了。所以,我可能会在某个时候重振这个项目,并将这篇文章作为所用代码的基础。我意识到这有点奇怪。我在一个奇怪的固执时期写了它,当时我有一种特定的做事方式,基本上试图直接模仿汇编和 LISP 等语言,并在现代语言中使用它们时将编码约定抛在一边。因此,多个 if 语句在模仿数字电子设备中的 AND/OR 方式,我讨厌 try/catch。

标签: java jar packages main javac


【解决方案1】:

您似乎误读或掩盖了如何制作“可执行 jar”的一些细节。

首先,您有一个源目录,其中包含您的源文件(名称以.java 结尾的文件,具有适当的目录结构;我知道您知道很多)。

您需要做的是将源目录中的这些文件编译到目标目录中(这可能是相同的);此外,在您的一个源目录中,您应该有一个名为(相对)的文件:

META-INF/MANIFEST.MF

在该文件中,有一行内容如下:

Main-Class: relative.path.to.MyMainClass

地点:

relative/path/to/MyMainClass.java

有一个带有原型的main 方法:

public static void main(String... args) // or String[] args

所以,基本流程是:

  • 知道你的源目录是什么,你的.java文件在哪里;
  • 知道您的目标目录是什么;
  • 适当地发出编译过程;在目标目录中手动复制编译过程未处理的文件(这包括META-INF/MANIFEST.MF);
  • 从目标目录中制作一个 jar。

总而言之,你的构建目录的内容应该是:

  • META-INF/MANIFEST.MF(至少包含 Main-Class);
  • **/*.class(您编译的 Java 文件)。

你应该可以用它制作一个“可执行jar”。

当然,如果你有外部依赖,问题就复杂多了……

【讨论】:

    【解决方案2】:

    您的Manifest.txt 文件可能没有以新行结尾。

    另一种解决问题的方法是使用该命令创建带有清单的 JAR:

    jar cfe jar-file main-class input-file(s)
    

    然后Manifest 文件将被自动创建。因此,在您的情况下,此命令可能如下所示:

    jar cfe LipsDefs.jar CharDefs *
    

    或者如果你有包裹:

    jar cfe LipsDefs.jar LispDefs.CharDefs LispDefs/*
    

    您可以在这里找到更多信息https://docs.oracle.com/javase/tutorial/deployment/jar/appman.html

    【讨论】:

    • 不完全。他需要LispDefs/*.class,而不是*
    • 包被注释掉了。
    • 阅读问题。其中讨论了被注释/注释掉的包。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-15
    • 1970-01-01
    • 1970-01-01
    • 2010-09-17
    • 2014-09-10
    • 1970-01-01
    • 2020-06-11
    相关资源
    最近更新 更多