将 ANTLR 生成的类文件制作为一个 jar 文件

发布于 2024-08-24 23:00:17 字数 2221 浏览 4 评论 0原文

使用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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

岁月蹉跎了容颜 2024-08-31 23:00:17

您用于测试类的包命名空间是什么?

假设你的主类是 pro.seek.Test,
你把它表现为吗

Main-class: pro.seek.Test

Antler 会生成一个文件夹层次结构

whatever/pro/seek

,以便您的主类文件位于

whatever/pro/seek/Test.java

当您 jarred 文件时,您是否首先 cd 到“whatever”文件夹,以便在创建时将 jar 内容植根于“pro”文件夹罐子?这样,当您使用 zip 查看器列出 jar 文件时,您可以看到层次结构 /pro/seek/,在该层次结构下您可以找到一堆生成的 java 源文件。

您是否正确创建了 jar 文件?可能不是 antlr 问题,而是如何创建可执行 jar 的问题。

从您包含的更多信息来看,

这里有进一步的想法:

当您运行 hello.jar 时,您没有包含 antlr 发行版 jar 的路径。

在清单中将其指定为

Class-Path: antlr-3.1.1-runtime.jar

,或者在运行 hello.jar 时将其指定为,

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

并确保 antlr jar 位于 hello.jar 旁边。

当您的 java 源代码在编译期间使用任何库时,在运行编译后的代码时必须包含这些库,这应该是非常明显的规则,因为计算机需要知道如何处理对库例程进行的这些调用。

比如说,有人在 Truth 类中编写了一个例程 showMe(boolean theTruth) 并将其放置在一个 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");
  }
}

并且您的 Test.java 有一个调用,

Truth.showMe(false);

您必须包含 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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文