在java shebang脚本中加载库

在java shebang脚本中加载库,java,shell,java-11,Java,Shell,Java 11,自从JDK-11以来,我们就能够直接运行java源代码。此代码 import org.apache.commons.codec.digest.Md5Crypt; public class Oneliner { public static void main(String[] args){ System.out.println(Md5Crypt.md5Crypt("ok".getBytes(), "$1$saltsalt")); } } 可以用 $ /usr/lib/jvm/j

自从JDK-11以来,我们就能够直接运行java源代码。此代码

import org.apache.commons.codec.digest.Md5Crypt;

public class Oneliner {
  public static void main(String[] args){
    System.out.println(Md5Crypt.md5Crypt("ok".getBytes(), "$1$saltsalt"));
  }
}
可以用

$ /usr/lib/jvm/jdk-11/bin/java --source 8 -cp /home/imaskar/.m2/repository/commons-codec/commons-codec/1.11/commons-codec-1.11.jar jscript.java
但采用shell脚本形式(shebang)

我得到一个错误:

$ ./jscript.sh
Error: Could not find or load main class ..jscript.sh
Caused by: java.lang.ClassNotFoundException: //jscript/sh

问题是第一行中的
--class path
参数。由于某种原因,
--souce
参数可以通过,但
--class path
不能通过。

您的shebang参数是错误的

--类路径
需要在
--源代码

它被提到了,但它相当深奥,并且分成了几个部分

下面的方法将起作用

#!/usr/lib/jvm/jdk-11/bin/java --class-path /home/imaskar/.m2/repository/commons-codec/commons-codec/1.11/commons-codec-1.11.jar --source 8 

import org.apache.commons.codec.digest.Md5Crypt;

public class Oneliner {
  public static void main(String[] args){
    System.out.println(Md5Crypt.md5Crypt("ok".getBytes(), "$1$saltsalt"));
  }
}
我的版本如下

$ /usr/bin/java -version
java version "11" 2018-09-25
Java(TM) SE Runtime Environment 18.9 (build 11+28)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11+28, mixed mode)

$ cat kkkk.sh
#!/usr/bin/java --class-path /Users/steven/.m2/repository/commons-codec/commons-codec/1.11/commons-codec-1.11.jar --source 8

import org.apache.commons.codec.digest.Md5Crypt;

public class Oneliner {
    public static void main(String[] args){
        System.out.println(Md5Crypt.md5Crypt("ok".getBytes(), "$1$saltsalt"));
    }
}

$ ./kkkk.sh
$1$saltsalt$PXysoX71YwjJOoKzgzTEg/

这个在OpenJDK中通常不起作用,正如前面的回答所述,java 11中有一个bug:

我找到了一个解决方案,让我可以使用类路径参数:

#!/usr/bin/env -S java --class-path /path/mylib.jar --source 11

注意参数的顺序,如果
--source
--class path
之前,它就不起作用了。

给定参数
jscript.sh
,java尝试从
jscript
包中执行
sh
类,因此我认为您需要将文件重命名回
jscript.java
(这不应妨碍shebang解释)。此外,我在您的
--class path
参数中没有看到包含java文件的目录,这一定是个问题。@Aaron在jdk-11中对此进行了处理。@Aaron使用
--source
选项,java知道这是一个源文件名。感谢您提供的信息,我应该已经阅读了JEP。在您的错误中,它看起来仍然需要尝试正在加载
sh
类,但我猜这是因为参数没有像您所说的那样正确解析。
无法识别的选项:--class path/home/imaskar/.m2/repository/commons codec/commons codec/1.11/commons-codec-1.11.ja错误:无法创建Java虚拟机。错误:发生致命异常。程序将退出。
@Imaskar确保你没有使用
cat-A
的奇怪字符吗?@Aaron没有,没什么不寻常的。顺便说一句,谢谢你的有趣命令。还有什么操作系统?我在Ubuntu 16.04和17.10上测试过。我发现它是通过args文件工作的。单用一个脚本仍然没有成功。这个答案是错误的,
--源代码
需要首先测试。事实上,我知道n MacOS
——source
现在对我来说是第一位和第二位的(使用java 14),根据规范,这不应该是这种情况。你可以通过将它委托给env:
#!/bin/env-S java——source 11——更多参数来绕过愚蠢的shebang解析
#!/usr/lib/jvm/jdk-11/bin/java --source 8 --class-path /home/imaskar/.m2/repository/commons-codec/commons-codec/1.11/commons-codec-1.11.jar
#!/usr/bin/env -S java --class-path /path/mylib.jar --source 11