【问题标题】:Runnable JAR File: Classes that implement "org.apache.hadoop.util.Tool" are not found可运行的 JAR 文件:找不到实现“org.apache.hadoop.util.Tool”的类
【发布时间】:2017-07-24 12:13:18
【问题描述】:

我有一个名为 MyTest 的项目。它分为三个类:

第一个类实现了 Tool 接口(这是导致问题的类)为简单起见,我做了空实现:

import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.util.Tool;

public class A1  extends Configured implements Tool{

    public static void main(String[] args) throws Exception {

        System.out.println("Hello A1");
    }

    @Override
    public int run(String[] args) throws Exception {
        // TODO Auto-generated method stub
        return 0;
    }

}

第二类是普通类:

public class A2 {

    public static void main(String[] args) throws Exception {

        System.out.println("Hello A2");
    }


}

第三类也是普通类:

public class A3 {

    public static void main(String[] args) throws Exception {

        System.out.println("Hello A3");
    }


}

我将项目导出为“可运行 Jar”(即在 Eclipse 中:项目>>导出>>可运行 Jar 文件)。

我在“Launch Configuration”和“Packaged required libraries into generated JAR”中将“A2”设置为主类,输出jar或“export destination”的名称是“MyTest.jar”

如果我运行命令,现在正如预期的那样:

java -jar MyTest.jar

它将打印:

Hello A2

如果我运行命令:

java -cp MyTest.jar A2

它将打印:

Hello A2

如果我运行命令:

java -cp MyTest.jar A3

它将打印:

Hello A3

现在的问题是,如果我运行命令:

java -cp MyTest.jar A1

我会给出这个错误:

Error: Could not find or load main class A1

我尝试了很多次,不同的场景问题都是一样的:当类实现“org.apache.hadoop.util.Tool”接口时,找不到该类。

请注意:如果我在“启动配置”中将 jar 文件的主类设置为“A1”,那么命令“java -jar MyTest.jar”将正确运行并给出“Hello A1”,但命令“java -cp MyTest.jar A1”仍然无法找到“A1”。

那么为什么会发生这种情况,如何在命令“java -cp MyTest.jar A1”中找到“A1”?

更新:

我现在可以通过指定所需的 jar 文件来解决问题:

java -cp MyTest.jar:"/home/mosab/workspace/Hadoop Jars/Binaries/hadoop-common-2.7.3.jar" A1

如果您有一堆 jar 文件,您可以使用“将所需库复制到生成的 JAR 旁边的子文件夹”选项导出“可运行的 Jar 文件”,然后:

java -cp MyTest.jar:./MyTest_lib/* A1

注意: MyTest_lib 是包含所有 jar 文件的文件夹

如果你想传递 java 选项、参数或包名,那么:

java -Xms2048m -Option2 -cp MyTest.jar:./MyTest_lib/* PackageName.A1 Arg1 Arg2

【问题讨论】:

    标签: java hadoop jar executable-jar mainclass


    【解决方案1】:

    要使 A1 工作,您需要在 -cp 中包含所有包含引用类的 jar。它可能与您用于编译 A1 的 jar 列表相同。 在 Windows 上,列表由 ';' 分隔。在 Linux 上,列表由 ':' 分隔。 您看到的错误是因为它找不到 A1 引用的类文件。因此它无法加载 A1。

    使用 Hadoop.jar 和 Hadoop2.jar 作为一般示例:

    java -cp MyTest.jar;Hadoop.jar;Hadoop2.jar A1
    

    【讨论】:

    • 感谢您的回复,这可行,但这里的问题是我应该包含哪些 jar 文件?在我的项目中,我有一个主类,它使用 jar 文件中存在的一些类,这些类将其他类用于其他 jar 文件等等。所以我应该包括所有的 jar 文件,即依赖 jar 和依赖的依赖等。我有一个巨大的 jar 列表有没有更好的方法来做到这一点。
    • 请注意:所有必需的 jar 都已经打包在 Runnable Jar 文件中,所以我怎样才能轻松使用它们。此外,“启动配置”中指定的主类不需要指定任何依赖项/jar,只需“java -jar MyTest.jar”,因为我认为 MANIFEST.MF 中已经提到了所需的 jar,所以我可以使用 MANIFEST。 MF 文件告诉“java”命令为任何主类包含这些 jar。
    • 我认为你最好的办法是重新创建以A1为主要类的jar文件并使用java -jar MyTest.jar。当您创建 Runnable Jar 文件时,一个类被标识为 Main-Class。您可以在 META-INF/MANIFEST.MF 的 jar 文件中看到这一点。这就是java在使用“java -jar”时知道哪个类是主类的方式。
    • 是的,没错,但我的意思是,如果我有很多主要课程,我该如何克服这个问题(指定所有的罐子)?
    猜你喜欢
    • 2013-04-12
    • 2013-01-16
    • 2015-03-01
    • 2012-01-27
    • 2015-07-10
    • 1970-01-01
    • 2013-06-30
    • 1970-01-01
    • 2015-08-18
    相关资源
    最近更新 更多