【发布时间】:2025-08-11 20:35:01
【问题描述】:
在旧版本的 Groovy 中,我可以在 Cygwin 下将 Groovy 作为 shell 脚本运行,遵循他们自己的 instructions 这样做:
$ cat ~/bin/hiworld
#!/usr/bin/env groovy
println("Hello world")
这行得通。但是,在(至少)Groovy 2.3.2 和 2.3.3 下,我看到的是:
$ hiworld
Caught: java.net.MalformedURLException: unknown protocol: c
java.net.MalformedURLException: unknown protocol: c
我在黑暗中的最佳尝试:“env”通过绝对路径启动脚本(例如“groovy /home/myacct/bin/hiworld”),并且新版本的 Groovy 已经被“改进”了,因此 Groovy不再明白如何处理这个问题。
确实,我这样做也会产生同样的错误:
$ groovy ~/bin/hiworld
Caught: java.net.MalformedURLException: unknown protocol: c
java.net.MalformedURLException: unknown protocol: c
所以我不确定 Groovy 是如何 (a) 将其解析为 windows 样式的路径,然后 (b) 无法理解它是 windows 样式的路径。
然后,我可以通过运行它来“修复”它:
$ groovy $(cygpath -w ~/bin/hiworld)
Hello world
...但是,来吧,这是让用户启动实用程序脚本的一种完全疯狂的方式。 (当然,或者我可以只用那一行编写一个“前端”脚本来启动另一个脚本。但是,对于我最终想要完成的事情,我还不如放弃 Groovy 并分发一个可运行的带有相关启动脚本的 JAR。)
Groovy 是否只是放弃了对 Cygwin 的支持?或者他们真的有可能至少发布了两个版本而没有测试他们自己推荐的在最流行的环境之一下运行脚本的方法?
如果没有,我错过了什么或做错了什么?
更新:我认为备份我在这里建议的一些内容会很有帮助。
首先,我想说明 Cygwin 显然是(或曾经)至少在一定程度上受支持:例如,groovyStart 中有相当多的代码支持 Cygwin 平台(看起来和 Mac OSX 一样多)。如前所述,它显然在以前的版本中运行良好。
目前,最后一个示例在 groovyStart 下解析为:
'/cygdrive/c/Program Files/Java/jdk1.7.0_51/bin/java' -classpath C:/cygwin64/home/myacct/opt/groovy-2.3.3/lib/groovy-2.3.3.jar -Dscript.name=/home/myacct/opt/groovy-2.3.3/bin/groovy -Dprogram.name=groovy -Dgroovy.starter.conf=C:/cygwin64/home/myacct/opt/groovy-2.3.3/conf/groovy-starter.conf -Dgroovy.home=C:/cygwin64/home/myacct/opt/groovy-2.3.3 '-Dtools.jar=C:/Program Files/Java/jdk1.7.0_51/lib/tools.jar' org.codehaus.groovy.tools.GroovyStarter --main groovy.ui.GroovyMain --conf C:/cygwin64/home/myacct/opt/groovy-2.3.3/conf/groovy-starter.conf --classpath . C:/cygwin64/home/myacct/bin/hiworld
澄清一下,调用 JDK 本身没有问题——运行命令的那部分运行得很好。被破坏的部分是最后一个论点:如果我改变
C:/cygwin64/home/myacct/bin/hiworld
到
file:///C:/cygwin64/home/myacct/bin/hiworld
...它再次工作。这与我上面的断言一致,即“groovy”(脚本)确实正确地从 Cygwin/UNIX 样式的路径转换为本地 Windows 路径,但是在 Windows Java 中运行的底层进程实际上被混淆了窗户路径!显然它期待一个 URL。
更新 2: 下面,Warren 提出了尝试使用 GVM 的极好建议。可悲的是,这仍然会产生相同的错误:
$ which groovy
/home/myacct/.gvm/groovy/current/bin/groovy
$ hiworld
Caught: java.net.MalformedURLException: unknown protocol: c
java.net.MalformedURLException: unknown protocol: c
$ sh $(which groovy) ~/bin/hiworld
Caught: java.net.MalformedURLException: unknown protocol: c
java.net.MalformedURLException: unknown protocol: c
在前面的命令中添加“-x”标志表明 Groovy 仍在使用我的 Windows JVM(这并没有错,只是注意一下)并且现在正在引用 GVM 安装的库(为了便于阅读,此处稍微重新格式化) :
'/cygdrive/c/Program Files/Java/jdk1.7.0_51/bin/java' \
-classpath C:/cygwin64/home/myacct/.gvm/groovy/2.3.3/lib/groovy-2.3.3.jar \
-Dscript.name=/home/C400334/.gvm/groovy/current/bin/groovy \
-Dprogram.name=groovy \
-Dgroovy.starter.conf=C:/cygwin64/home/myacct/.gvm/groovy/2.3.3/conf/groovy-starter.conf \
-Dgroovy.home=C:/cygwin64/home/myacct/.gvm/groovy/2.3.3 \
'-Dtools.jar=C:/Program Files/Java/jdk1.7.0_51/lib/tools.jar' \
org.codehaus.groovy.tools.GroovyStarter \
--main groovy.ui.GroovyMain \
--conf C:/cygwin64/home/myacct/.gvm/groovy/2.3.3/conf/groovy-starter.conf \
--classpath . \
C:/cygwin64/home/myacct/bin/hiworld
和以前一样,在最后一个参数之前添加“file:///”似乎可以解决问题。
所以我想知道我们是否使用了不同版本的 JVM 或其他什么?
更新 3: 升级到 jdk1.7.0_60(尝试了 64 位和 32 位版本),但这似乎没有什么不同。 Java 6 出现了同样的问题,但也增加了关于缺少 NioGroovyMethods 的抱怨。
【问题讨论】: