Antlr4:使用grun命令,触发NoClassDefFoundError

1. 意外的发现

  • 学习使用grun命令时,从未遇到过错误
  • 最近使用grun命令,却遇到了NoClassDefFoundError的错误,使得grun测试工具无法成功启动

错误复现:

  1. 使用antlr4命令编译Hello.g4文件,并为指定package(com.sunrise.hello

    antlr4 Hello.g4 -o ../java/com/sunrise/hello -package com.sunrise.hello
    

    最终生成的Java代码如下:

  2. 使用mvn clean compile命令编译整个project

  3. target/classes/com/sunrise/hello目录下执行grun命令解析token,出现NoClassDefFoundError的错误

    详细的错误日志如下:

    Exception in thread "main" java.lang.NoClassDefFoundError: HelloLexer (wrong name: com/sunrise/hello/HelloLexer)
            at java.lang.ClassLoader.defineClass1(Native Method)
            at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
            at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
            at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
            at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
            at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
            at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
            at java.security.AccessController.doPrivileged(Native Method)
            at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
            at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
            at org.antlr.v4.gui.TestRig.process(TestRig.java:129)
            at org.antlr.v4.gui.TestRig.main(TestRig.java:119)
    

2. 错误原因

  • 从报错信息看,貌似是HelloLexer有错误的包名,导致运行时JVM无法找到HelloLexer

  • 上网查阅NoClassDefFoundError的原因如下:

    NoClassDefFoundError错误的发生,是因为Java虚拟机在编译时能找到合适的类,而在运行时不能找到合适的类导致的错误

  • 有一大堆文字,但是没看懂 😂 😂

  • 但是,对错误原因的简单描述跟当前情况十分吻合:生成的package为com.sunrise.hello的Java代码已经编译成功,但运行时却提示not found

  • 猜测:执行grun命令的路径不对,且作为GrammerName的Hello应该带包名

  • 验证猜测:回到target/classes目录,执行grun命令

    grun com.sunrise.hello.Hello r -tokens
    
  • 成功使用grun命令解析出tokens

3. 正确的解决办法

  • 使用grun测试lexer或parser时,如果生成的Java代码有设置package,需要到target/classes目录,并在GrammerName中使用类的完全限定名
  • 也就是需要带上package信息,就像下面的命令一样
    grun com.sunrise.hello.Hello r -tokens
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值