Search code examples
javahadoopjarexecutable-jarmainclass

Runnable JAR File: Classes that implement "org.apache.hadoop.util.Tool" are not found


I have a project called MyTest. It has three classes:

The first class implements the Tool interface (this is the class that is causing the problem) for simplicity I did empty implementations:

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;
    }

}

The second class is a normal class:

public class A2 {

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

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


}

The third class is also a normal class:

public class A3 {

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

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


}

I exported the project as a "Runnable Jar" (i.e. In Eclipse: Project>>Export>>Runnable Jar File).

I set "A2" as the main class in "Launch Configuration" and "Packaged required libraries into generated JAR" and the name of the output jar or "export destination" is "MyTest.jar"

Now as expected if I run the command:

java -jar MyTest.jar

It will print:

Hello A2

If I run the command:

java -cp MyTest.jar A2

It will print:

Hello A2

If I run the command:

java -cp MyTest.jar A3

It will print:

Hello A3

Now the problem is, if I run the command:

java -cp MyTest.jar A1

I will give this error:

Error: Could not find or load main class A1

I tried it many times and with different scenarios the problem is same: when the class implements the "org.apache.hadoop.util.Tool" interface then the class will not be found.

Please Notice: if I set the main class of the jar file in "Launch Configuration" to "A1" then the command "java -jar MyTest.jar" will run correctly and gives "Hello A1" but the command "java -cp MyTest.jar A1" still will fail to find "A1".

So why is this happening and how can I make "A1" be found in the command "java -cp MyTest.jar A1"?

UPDATE:

I am able now to solve the problem by specifying the required jar files:

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

And if you have a bunch of jar files you can export "Runnable Jar File" with "Copy required libraries into a sub-folder next to the generated JAR" option and then:

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

Notice: MyTest_lib is the folder that contains all the jar files

And if you want to pass java options, arguments, or package name then:

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

Solution

  • To make A1 work you need to include all the jars containing the referenced classes in -cp. It's probably the same as the list of jars you used to compile A1. On Windows the list is delimited by ';'. On Linux, the list is delimited by ':'. The error you see is because it cannot find the class files that A1 references. Therefore it cannot load A1.

    Using Hadoop.jar and Hadoop2.jar as general examples:

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