[英]Load library in a java shebang script
Since JDK-11 we have ability to run java source code directly.从 JDK-11 开始,我们可以直接运行 Java 源代码。 This code
这段代码
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"));
}
}
can be run with可以运行
$ /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
But in a shell script form (shebang)但是以 shell 脚本形式 (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
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"));
}
}
I get an error:我收到一个错误:
$ ./jscript.sh
Error: Could not find or load main class ..jscript.sh
Caused by: java.lang.ClassNotFoundException: //jscript/sh
The problem is --class-path
argument in the first line.问题是第一行中的
--class-path
参数。 For some reason --souce
argument gets through, but --class-path
doesn't.由于某种原因
--souce
参数通过,但--class-path
没有。
This does not generally work in OpenJDK <= 11.0.7
.这通常不适用于 OpenJDK <=
11.0.7
。 Whether this is a bug and gets fixed or not is not clear yet.这是否是一个错误并得到修复尚不清楚。 There is an open bug report:
有一个开放的错误报告:
https://bugs.openjdk.java.net/browse/JDK-8242911 https://bugs.openjdk.java.net/browse/JDK-8242911
Specifying the --class-path
works at least with OpenJDK 12.0.2
and 14.0.1
.指定
--class-path
至少适用于 OpenJDK 12.0.2
和14.0.1
。 So I assume some improvements made for Java 12 fixed this issue.所以我假设针对 Java 12 所做的一些改进修复了这个问题。
So the line in the question is supposed to work, no change needed:所以问题中的行应该有效,不需要改变:
#!/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
Some notes on other things mentioned in the other answer and in the comments:关于其他答案和评论中提到的其他事情的一些说明:
--source
must be the first argument. --source
必须是第一个参数。 In shebang files, the first line is treated like #!$COMMAND $ONE-SINGLE-ARGUMENT
.#!$COMMAND $ONE-SINGLE-ARGUMENT
。 So the shell will not separate the $ONE-SINGLE-ARGUMENT
by whitespace.$ONE-SINGLE-ARGUMENT
。 Thus, the Java launcher will split the argument by whitespace iff it starts with --source
and further process the other arguments.--source
开头并进一步处理其他参数,则 Java 启动器将按空格拆分参数。bash
and dash
.bash
和dash
测试了行为。As told in previous answers there is a bug in java 11:如之前的答案所述,Java 11 中有一个错误:
https://bugs.openjdk.java.net/browse/JDK-8242911 https://bugs.openjdk.java.net/browse/JDK-8242911
I found this work around that let me use the class-path parameter:我发现这项工作可以让我使用 class-path 参数:
#!/usr/bin/env -S java --class-path /path/mylib.jar --source 11
Note the order of the parameters, if --source
is before --class-path
it does not work.注意参数的顺序,如果
--source
在--class-path
之前它不起作用。
Your shebang arguments are the wrong way round.你的shebang论点是错误的。
--class-path
needs to come before --source
--class-path
需要在--source
之前
It is mentioned in the original JEP , but it rather esoteric, and split across a couple of sections...它在最初的 JEP 中被提及,但它相当深奥,并分为几个部分......
The below will work.下面将工作。
#!/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"));
}
}
My Version is below我的版本在下面
$ /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/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.