代码之家  ›  专栏  ›  技术社区  ›  prosseek

使antlr生成的类文件成为一个jar文件

  •  2
  • prosseek  · 技术社区  · 14 年前

    在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测试”时,得到了正确的结果。

    我使用的示例是“最终的Antlr引用”一书中的源代码,您可以从中下载 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 {
    
    1 回复  |  直到 12 年前
        1
  •  2
  •   Blessed Geek    14 年前

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

    如果你的主要课程是pro.seek.test, 你证明它是

    Main-class: pro.seek.Test
    

    ?

    鹿角会产生文件夹的层次结构

    whatever/pro/seek
    

    以便在

    whatever/pro/seek/Test.java
    

    当您对文件进行jarred时,您是否首先将CD放入“whatever”文件夹,以便在创建jar时将jar内容扎根于“pro”文件夹?因此,当您用zip查看器列出JAR文件时,您可以看到层次结构/ Pro/Debug /,您可以在其中找到生成的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
    

    确保安特尔罐在hello.jar旁边。

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

    比如,有人在类真理中编写了一个例程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.run time.charstream类。

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