Making ANTLR generated class files into one jar file
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 开发者_如何学JAVA03-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 {
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
精彩评论