Tuesday, March 1, 2011

Java Command Line Trouble with Reading a Class from a Jar Archive

I am trying to run a java based tool using a command line syntax as the following: java -cp archive.jar archiveFolder.theMainClassName.Although the class I am searching for, a main class, "theMainClassName" is in the archive.jar and in the archiveFolder given at input, I keep getting the error that my class is not seen. Does anybody have any ideas concerning this problem? Thank you in advance

From stackoverflow
  • Perhaps with java -jar archive.jar?

    Of course, it supposes the manifest points to the right class...

    You should give the exact message you got, it might shed more light.

    EDIT: See Working with Manifest Files: The Basics for information on setting the application entry point (Main class) in your jar manifest file.

    Jason Coco : This doesn't actually answer the question... he's not attempting to run the jar but a specific class in the jar. It's almost certainly a packaging problem.
    Bill the Lizard : I agree that this doesn't answer the specific question asked, but other people searching SO might be suffering from a problem with their manifest. They'll run across this question, so I think it's worth having this answer here.
    Jason Coco : @Bill this is true
  • Does theMainClassName class have the following package line at the top:

    package archiveFolder
    

    You need the class file to be in the same directory structure as the declared package. So if you had something like:

    org/jc/tests/TestClass.class
    

    its source file would have to look like this:

    package org.jc.tests;
    
    public class TestClass {
      public static void main(String[] args) {
        System.out.printf("This is a test class!\n");
      }
    }
    

    Then you could use the following to create the jar file and run it from the command line (assuming the current directory is at the top level, just above org):

    $ jar -cf testJar.jar org/jc/tests/*.class
    $ java -cp testJar.jar org.jc.tests.TestClass
    
  • Here's a concrete example of what does work, so you can compare your own situation.

    Take this code and put it anywhere, in a file called MainClass.java. (I've assumed a directory called src later. Normally you'd arrange the source to match the package, of course.)

    package archiveFolder;
    
    public class MainClass
    {
        public static void main(String[] args)
        {
            System.out.println("I'm MainClass");
        }
    }
    

    Then run each of these commands:

    # Compile the source
    javac -d . src/MainClass.java
    
    # Build the jar file
    jar cf archive.jar archiveFolder
    
    # Remove the unpackaged binary, to prove it's not being used
    rm -rf archiveFolder # Or rmdir /s /q archiveFolder on Windows
    
    # Execute the class
    java -cp archive.jar achiveFolder.MainClass
    

    The result:

    I'm MainClass
    

    How are you building your jar file? Is the code in the appropriate package?

  • Usually this happens when a dependent class (static member) is not found - like this, using log4j:

    public class MyClass {
      private static Logger log = Logger.getLogger("com.example");
    }
    

    The reason is that the initialization of such a static member can be understood as part of the class loading - errors causing the class not to be available (loadable), resulting in the error you described.

    Static constructors are another possible reason:

    public class MyClass {
      static {
         // <b>any</b> error caused here will cause the class to 
         // not be loaded. Demonstrating with stupid typecast.
         Object o = new String();
         Integer i = (Integer) o;
      }
    }
    
  • I think others have covered some common stuff here. I'd jar tf the jar and make sure the class is listed. I'd also double-check that the class is public and the method is "public static void main(String[] arg)".

0 comments:

Post a Comment