将 ANTLR 生成的类文件制作为一个 jar 文件
使用ANTLR,我在编译后得到了一些java类文件。 我需要将所有类文件放入一个 jar 文件中。
我制作的manifest.mf 文件有一行“Main-class: Test”来指示主文件。 我运行 'jar cmf manifest.mf hello.jar *.class' 来获取 hello.jar 文件。
但是当我尝试运行“java -jar hello.jar”时,我收到以下错误消息。
$ 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)
怎么了? 当我运行“java Test”时,我得到了正确的结果。
我使用的示例是《The Definitive ANTLR Reference》一书的源代码,您可以从 http://www.pragprog.com/titles/tpantlr/source_code
示例位于 /tour/trees/ 中。编译 g 和 java 文件后,我得到了一堆类文件。
使用 unzip -l,我得到以下信息。
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
Test.java 启动如下。
import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
public class Test {
public static void main(String[] args) throws Exception {
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 {
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您用于测试类的包命名空间是什么?
假设你的主类是 pro.seek.Test,
你把它表现为吗
?
Antler 会生成一个文件夹层次结构
,以便您的主类文件位于
当您 jarred 文件时,您是否首先 cd 到“whatever”文件夹,以便在创建时将 jar 内容植根于“pro”文件夹罐子?这样,当您使用 zip 查看器列出 jar 文件时,您可以看到层次结构 /pro/seek/,在该层次结构下您可以找到一堆生成的 java 源文件。
您是否正确创建了 jar 文件?可能不是 antlr 问题,而是如何创建可执行 jar 的问题。
从您包含的更多信息来看,
这里有进一步的想法:
当您运行 hello.jar 时,您没有包含 antlr 发行版 jar 的路径。
在清单中将其指定为
,或者在运行 hello.jar 时将其指定为,
并确保 antlr jar 位于 hello.jar 旁边。
当您的 java 源代码在编译期间使用任何库时,在运行编译后的代码时必须包含这些库,这应该是非常明显的规则,因为计算机需要知道如何处理对库例程进行的这些调用。
比如说,有人在 Truth 类中编写了一个例程 showMe(boolean theTruth) 并将其放置在一个 jar Truth.jar 中:
并且您的 Test.java 有一个调用,
您必须包含 Truth.jar,否则 jvm 将如何知道如何处理对 showMe() 的调用?
Antlr 生成一堆 java 源文件,并且它们调用 antlr 运行时,因此您需要在运行时类路径中包含 antlr 运行时。您的运行时错误表明jvm正在寻找在antrl运行时jar中找到的org.antlr.runtime.CharStream类。
http://java.sun.com/docs/books/教程/部署/jar/downman.html
What is the package namespace you used for Test class?
Say, if your main class was pro.seek.Test,
did you manifest it as
?
Antler would have produced a hierarchy of folders
so that your main class file is found at
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
or specify it when you run hello.jar as
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:
And your Test.java has a call
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