简体   繁体   English

在 java shebang 脚本中加载库

[英]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.214.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 .在 shebang 文件中,第一行被视为#!$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 启动器将按空格拆分参数。
  • I can't fully explain muttonUp's working example.我无法完全解释 muttonUp 的工作示例。 I suspect it is related to the usage of macOS.我怀疑这与macOS的使用有关。 Maybe the used shell split up the shebang argument already.也许使用过的 shell 已经拆分了 shebang 参数。
  • Thus, it might be that this issue is limited to certain shells.因此,这个问题可能仅限于某些 shell。 I have tested the behavior with Ubuntu's bash and dash .我已经用 Ubuntu 的bashdash测试了行为。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM