tags:

views:

300

answers:

1

With ANTLR, I get some java class files after compilation. And I need to make all the class files into one jar file.

I make manifest.mf file that has one line "Main-class: Test" to indicate the main file. I run 'jar cmf manifest.mf hello.jar *.class' to get hello.jar file.

But when I try to run 'java -jar hello.jar', I get the following error messages.

$ java -jar hello.jar 
Exception in thread "main" java.lang.NoClassDefFoundError: org/antlr/runtime/CharStream
Caused by: java.lang.ClassNotFoundException: org.antlr.runtime.CharStream
        at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:315)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:330)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:250)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:398)

What's wrong? I get correct result when I run 'java Test'.

The example that I used is the source code from the book 'The Definitive ANTLR Reference' that you can download from http://www.pragprog.com/titles/tpantlr/source_code

The example is in /tour/trees/. I get a bunch of class files after compiling g and java files.

Using unzip -l, I get the following info.

Archive:  hello.jar
  Length     Date   Time    Name
 --------    ----   ----    ----
        0  03-07-10 17:51   META-INF/
       78  03-07-10 17:51   META-INF/MANIFEST.MF
     5872  03-07-10 14:05   Eval.class
     1020  03-07-10 14:05   ExprLexer$DFA5.class
     5713  03-07-10 14:05   ExprLexer.class
      429  03-07-10 14:05   ExprParser$atom_return.class
      429  03-07-10 14:05   ExprParser$expr_return.class
      437  03-07-10 14:05   ExprParser$multExpr_return.class
      429  03-07-10 14:05   ExprParser$prog_return.class
      429  03-07-10 14:05   ExprParser$stat_return.class
    11048  03-07-10 14:05   ExprParser.class
     1129  03-07-10 14:05   Test.class
 --------                   -------
    27013                   12 files

The Test.java starts as follow.

import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
public class Test {
    public static void main(String[] args) throws Exception {
+1  A: 

What is the package namespace you used for Test class?

Say, if your main class was pro.seek.Test, did you manifest it as

Main-class: pro.seek.Test

?

Antler would have produced a hierarchy of folders

whatever/pro/seek

so that your main class file is found at

whatever/pro/seek/Test.java

When you jarred the file, did you first cd to "whatever" folder first, so that you had the jar contents rooted at "pro" folder when you created the jar? So that, when you list the jar file with a zip viewer, you could see the hierarchy /pro/seek/, under which you would find your bunch of generated java source files.

Did you create the jar file properly? Probably not an antlr issue, but a question on how to create an executable jar.

From your inclusion of more information,

here are further thoughts:

You did not include the path to antlr distribution jar when you ran hello.jar.

Either specify it in your manifest as

Class-Path: antlr-3.1.1-runtime.jar

or specify it when you run hello.jar as

jar hello.jar -classpath antlr-3.1.1-runtime.jar

and make sure the antlr jar is there next to hello.jar.

When your java source code uses any libraries during compilation, those libraries have to be included when you run the compiled code, which should be pretty obvious rule because the computer needs to know what to do with those calls being made to the library routines.

Say, someone wrote a routine showMe(boolean theTruth) in a class Truth and placed it a jar truth.jar:

public class Truth{
  static public void showMe(boolean theTruth){
    if (theTruth)
       println("It's a lie");
    else
       println("Thanks for the truth");
  }
}

And your Test.java has a call

Truth.showMe(false);

you have to include Truth.jar, otherwise how would the jvm know what to do with the call to showMe()?

Antlr produces a bunch of java source files and they have calls to the antlr runtime, therefore you need to include the antlr run-time in your runtime classpath. Your run-time error shows that the jvm is looking for org.antlr.runtime.CharStream class which is found in the antrl run-time jar.

http://java.sun.com/docs/books/tutorial/deployment/jar/downman.html

Blessed Geek
I added more explanation about the jar file.All of the class files are in the same directory, so I'm not sure what hierarchical info do I have to put in the manifest file.And the manifest file itself is in the same directory.
prosseek
And I think 'java.lang.NoClassDefFoundError: org/antlr/runtime/CharStream'error message seems very likely that the cause is from Antlr.
prosseek
I got it. You did not include the path to antlr distribution jar when you ran hello.jar.
Blessed Geek
It works! Thanks.
prosseek