ANTLR4 TestRig (grun) 抛出 java.lang.NoClassDefFoundError 异常
ANTLR4 TestRig (grun) throws java.lang.NoClassDefFoundError exception
我正在尝试学习 ANTLR 4,我正在按照 The Definitive ANTLR 4 Reference 中给出的示例进行操作。可悲的是,我卡在了第一个例子中。
系统:
Windows 10 (1703)
Java8、更新151
ANTLR 4,v4.7
我的%CLASSPATH%
设置为系统变量(.;"D:\Program Files\Java\libs\antlr-4.7-complete.jar";
)。
我的 %PATH%
中有 antlr4.bat
和 grun.bat
,我可以从命令行 运行 antlr4
。
antlr4.bat
: java -cp %CLASSPATH% org.antlr.v4.Tool %*
grun.bat
: java -cp %CLASSPATH% org.antlr.v4.gui.TestRig %*
我明确地使用 -cp %CLASSPATH%
,因为我看到其他一些人在不使用 -cp
选项时遇到问题。
我的问题是:
当我 运行 grun
在示例语法 Hello
(grun Hello r -tokens
) 上时,我收到此错误消息
Exception in thread "main" java.lang.NoClassDefFoundError: HelloLexer (wrong name: main/resource/hello/HelloLexer)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access0(Unknown Source)
at java.net.URLClassLoader.run(Unknown Source)
at java.net.URLClassLoader.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at org.antlr.v4.gui.TestRig.process(TestRig.java:129)
at org.antlr.v4.gui.TestRig.main(TestRig.java:119)
对我做错了什么有什么想法吗?
非常感谢!
编辑:
我以为我找到了答案。通过 cd
-ing 进入编译文件所在的文件夹(而不是从根项目文件夹调用 grun
),我设法完成了所讨论的示例。
但是当我尝试建立自己的项目时,我遇到了同样的问题,并出现与上述相同的错误消息。
这一次,在我 运行 antlr4
使用 -package
选项后,grun
似乎在抱怨。
有人知道这是为什么吗?
哇...解决方案当然是一个简单的解决方案...我的问题是我已经 cd
' 到我的测试项目的根文件夹,并且我只需要 cd
到(并从中调用 grun
)编译文件所在的目录。
编辑:
看来我对 grun
仍有疑问。请参阅已编辑的问题。
编辑 2:
据我所知,grun
与 antlr4
的 -package
选项配合得不是很好。
所以我的解决方案是我必须将我的项目设置为 Gradle 项目,因为显然这样效果更好。
尝试使用它所属的包完全限定语法名称,例如
com.demo.pl.Grammar。似乎适用于 ANTLR 4.7.2
我遇到了和你一样的问题。
@DoTheGenes 提醒我这可能是由 .g4 文件中的 @header {package com.blahblah.antlr4.hello;}
引起的。 G运行 在包重定位命令中有一些未修复的错误。当我用@header 删除这一行时,问题就解决了,我可以 运行 g运行 gui、tree 和任何其他带有生成和编译文件的命令。
希望这能有所帮助。
我正在使用 ANTLR 4.9.1 并且遇到了完全相同的问题。我的项目布局有一个独特且独立的位置:
- 语法
- 生成的源文件(在语法中由
@header
块指定的位置)
这使得 grun
总是失败(因为所有东西都必须在同一个文件夹中)。解决方法是制作另一个脚本来修复这 2 个 grun
错误:
- 将所有内容移动到 1 个文件夹(修复第一个错误)
- 从语法中删除
@header{...}
(修复第二个错误)
- (可选)如果类路径中没有 antlr,则添加它
- 编译所有
.java
个文件
- 运行
antlr4
(或手动 org.antlr.v4.Tool
)生成解析器 .java
文件
- 编译所有解析器
.java
个文件
- 运行
grun
(或 org.antlr.v4.gui.TestRig
手动),随心所欲
下面的 PowerShell
脚本展示了我是如何完成的(请记住你的路径可能不同),在我的例子中,语言和项目被称为 Nameless
并且我使用了 .g4test
测试脚本的扩展(因此请相应地调整您的 Bash
/Batch
/PowerShell
脚本)
# Script name : run.ps1
# Script arguments
param ($Target="-tokens")
# Options
$lang = "Nameless"
$startRule = "file"
# Paths
$antlr = "D:\Desktop\Workspaces\Java\ANTLRv4\antlr-4.9.1-complete.jar"
$project = "D:\Desktop\Workspaces\Java\Eclipse Workspace 2020\Nameless"
$javas = "$project\target\generated-sources\antlr4\generated"
$script = "$project\scripts\LiteralsTest.g4test"
$classes = "$project\build\classes\generated"
# Fix weird bug of TestRig needing all in 1 folder lol
Write-Host "Moving project files.." -NoNewLine
Copy-Item "$project$lang.g4" -Destination $classes
Copy-Item -Path "$javas\*" -Destination $classes
cd $classes
Write-Host " done."
# Fix other framework bug that makes '@header' lines not run lol..
Write-Host "Removing package header line from grammar.." -NoNewline
(Get-Content -Path "$lang.g4" -Raw) -replace "(?sm)^@header`{.*?`}$" | Out-File -FilePath ".$lang.g4" -Encoding ASCII
Write-Host " done."
# All should be good now, do the usual
Write-Host "Adding to classpath temporarily.." -NoNewLine
$env:CLASSPATH = ".;$antlr;$env:CLASSPATH"
Write-Host " done."
Write-Host "Generating Java files from grammar.." -NoNewLine
java -cp ".;$antlr" org.antlr.v4.Tool "$lang.g4" -listener -visitor
Write-Host " done."
Write-Host "Compiling java files.." -NoNewLine
javac -cp ".;$antlr" *.java
Write-Host " done."
Write-Host "Running.."
java -Xmx500M -cp ".:$env:CLASSPATH" org.antlr.v4.gui.TestRig $lang $startRule $Target $script
我正在尝试学习 ANTLR 4,我正在按照 The Definitive ANTLR 4 Reference 中给出的示例进行操作。可悲的是,我卡在了第一个例子中。
系统:
Windows 10 (1703)
Java8、更新151
ANTLR 4,v4.7
我的%CLASSPATH%
设置为系统变量(.;"D:\Program Files\Java\libs\antlr-4.7-complete.jar";
)。
我的 %PATH%
中有 antlr4.bat
和 grun.bat
,我可以从命令行 运行 antlr4
。
antlr4.bat
: java -cp %CLASSPATH% org.antlr.v4.Tool %*
grun.bat
: java -cp %CLASSPATH% org.antlr.v4.gui.TestRig %*
我明确地使用 -cp %CLASSPATH%
,因为我看到其他一些人在不使用 -cp
选项时遇到问题。
我的问题是:
当我 运行 grun
在示例语法 Hello
(grun Hello r -tokens
) 上时,我收到此错误消息
Exception in thread "main" java.lang.NoClassDefFoundError: HelloLexer (wrong name: main/resource/hello/HelloLexer)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access0(Unknown Source)
at java.net.URLClassLoader.run(Unknown Source)
at java.net.URLClassLoader.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at org.antlr.v4.gui.TestRig.process(TestRig.java:129)
at org.antlr.v4.gui.TestRig.main(TestRig.java:119)
对我做错了什么有什么想法吗?
非常感谢!
编辑:
我以为我找到了答案。通过 cd
-ing 进入编译文件所在的文件夹(而不是从根项目文件夹调用 grun
),我设法完成了所讨论的示例。
但是当我尝试建立自己的项目时,我遇到了同样的问题,并出现与上述相同的错误消息。
这一次,在我 运行 antlr4
使用 -package
选项后,grun
似乎在抱怨。
有人知道这是为什么吗?
哇...解决方案当然是一个简单的解决方案...我的问题是我已经 cd
' 到我的测试项目的根文件夹,并且我只需要 cd
到(并从中调用 grun
)编译文件所在的目录。
编辑:
看来我对 grun
仍有疑问。请参阅已编辑的问题。
编辑 2:
据我所知,grun
与 antlr4
的 -package
选项配合得不是很好。
所以我的解决方案是我必须将我的项目设置为 Gradle 项目,因为显然这样效果更好。
尝试使用它所属的包完全限定语法名称,例如 com.demo.pl.Grammar。似乎适用于 ANTLR 4.7.2
我遇到了和你一样的问题。
@DoTheGenes 提醒我这可能是由 .g4 文件中的 @header {package com.blahblah.antlr4.hello;}
引起的。 G运行 在包重定位命令中有一些未修复的错误。当我用@header 删除这一行时,问题就解决了,我可以 运行 g运行 gui、tree 和任何其他带有生成和编译文件的命令。
希望这能有所帮助。
我正在使用 ANTLR 4.9.1 并且遇到了完全相同的问题。我的项目布局有一个独特且独立的位置:
- 语法
- 生成的源文件(在语法中由
@header
块指定的位置)
这使得 grun
总是失败(因为所有东西都必须在同一个文件夹中)。解决方法是制作另一个脚本来修复这 2 个 grun
错误:
- 将所有内容移动到 1 个文件夹(修复第一个错误)
- 从语法中删除
@header{...}
(修复第二个错误) - (可选)如果类路径中没有 antlr,则添加它
- 编译所有
.java
个文件 - 运行
antlr4
(或手动org.antlr.v4.Tool
)生成解析器.java
文件 - 编译所有解析器
.java
个文件 - 运行
grun
(或org.antlr.v4.gui.TestRig
手动),随心所欲
下面的 PowerShell
脚本展示了我是如何完成的(请记住你的路径可能不同),在我的例子中,语言和项目被称为 Nameless
并且我使用了 .g4test
测试脚本的扩展(因此请相应地调整您的 Bash
/Batch
/PowerShell
脚本)
# Script name : run.ps1
# Script arguments
param ($Target="-tokens")
# Options
$lang = "Nameless"
$startRule = "file"
# Paths
$antlr = "D:\Desktop\Workspaces\Java\ANTLRv4\antlr-4.9.1-complete.jar"
$project = "D:\Desktop\Workspaces\Java\Eclipse Workspace 2020\Nameless"
$javas = "$project\target\generated-sources\antlr4\generated"
$script = "$project\scripts\LiteralsTest.g4test"
$classes = "$project\build\classes\generated"
# Fix weird bug of TestRig needing all in 1 folder lol
Write-Host "Moving project files.." -NoNewLine
Copy-Item "$project$lang.g4" -Destination $classes
Copy-Item -Path "$javas\*" -Destination $classes
cd $classes
Write-Host " done."
# Fix other framework bug that makes '@header' lines not run lol..
Write-Host "Removing package header line from grammar.." -NoNewline
(Get-Content -Path "$lang.g4" -Raw) -replace "(?sm)^@header`{.*?`}$" | Out-File -FilePath ".$lang.g4" -Encoding ASCII
Write-Host " done."
# All should be good now, do the usual
Write-Host "Adding to classpath temporarily.." -NoNewLine
$env:CLASSPATH = ".;$antlr;$env:CLASSPATH"
Write-Host " done."
Write-Host "Generating Java files from grammar.." -NoNewLine
java -cp ".;$antlr" org.antlr.v4.Tool "$lang.g4" -listener -visitor
Write-Host " done."
Write-Host "Compiling java files.." -NoNewLine
javac -cp ".;$antlr" *.java
Write-Host " done."
Write-Host "Running.."
java -Xmx500M -cp ".:$env:CLASSPATH" org.antlr.v4.gui.TestRig $lang $startRule $Target $script