gpt4 book ai didi

java - 有没有办法修改模块路径和程序化 JShell 实例的添加模块?

转载 作者:搜寻专家 更新时间:2023-10-31 20:17:20 25 4
gpt4 key购买 nike

我正在尝试通过使用 JShell API 创建的 JShell 实例在运行时运行一些 Java 代码.为了演示我的问题,我将分享我的简单代码。

在我当前的设置中,我有一个名为 lib 的目录,其中包含 MySQL Java 驱动程序:mysql-connector-java-5.1.35.jar

通过命令工具启动 JShell 并添加所需的模块:

jshell --module-path lib --add-modules mysql.connector.java

然后加载 mysql 驱动程序对我有用:

jshell> Class.forName("com.mysql.jdbc.Driver").newInstance();
$1 ==> com.mysql.jdbc.Driver@42f93a98

我用 module-info.java 创建了一个类似的 Java 9 模块:

module example.loadmysql {
requires java.sql;
requires mysql.connector.java;
requires jdk.jshell;
}

src/example/loadmysql/Runner.java 为:

package example.loadmysql;

import jdk.jshell.*;
import java.sql.*;

public class Runner {
public static void main(String[] args) throws Exception {
// this works because this module requires mysql.connector.java
System.out.println(Class.forName("com.mysql.jdbc.Driver").newInstance());

JShell js = JShell.create();
String code = ""
+ "try {"
+ " Class.forName(\"com.mysql.jdbc.Driver\").newInstance();"
+ "} catch (Exception e) {"
+ " System.out.println(e.toString());"
+ "}";
js.eval(code);
}
}

构建/打包之后:

java -p lib -m example.loadmysql
com.mysql.jdbc.Driver@6a4f787b
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver

很明显,即使 example.loadmysql 模块需要 mysql 连接器,但创建的 JShell 实例不需要。所以它找不到类。

关于如何以编程方式将模块添加到 JShell 实例,使其像直接的 JShell 编码示例一样工作,有什么想法吗?

更新 - 我已经弄清楚如何设置模块路径:

String modulePath = System.getProperty("jdk.module.path");
js.eval("System.setProperty(\"jdk.module.path\", \""
+ modulePath + "\");");

但这还不够。我仍然以某种方式添加了所需的模块。

最佳答案

你或许可以使用 addToClassPath在您的代码中的 eval 之前:

JShell js = JShell.create();
js.addToClasspath("path/to/add/to/the/classpath");
String code = ""
+ "try {"
+ " Class.forName(\"com.mysql.jdbc.Driver\").newInstance();"
+ "} catch (Exception e) {"
+ " System.out.println(e.toString());"
+ "}";
js.eval(code);

The specified path is added to the end of the classpath used in eval(). Note that the unnamed package is not accessible from the package in which eval(String) code is placed.

从文档看来,JShell 的状态返回后 eval 执行基于类路径的代码,因此为了向它添加任何进一步的依赖项,您需要将它添加到使用相同方法的类路径。


在您的情况下,我在这里猜测,尽管您这样做时,mysql-connector-java-5.1.35.jar 理想情况下会被视为自动模块 存在于类路径中,因此可以访问类 com.mysql.jdbc.Driver


更新:- 进一步探索我认为实现这一点的更好方法可能是尝试使用 Jshell.Builder及其选项 compilerOptions创建一个带有默认编译选项的实例有点像(未测试)-

JShell js = JShell.builder()
.compilerOptions("--module-path lib","--add-modules mysql.connector.java").build();
String code = ""
+ "try {"
+ " Class.forName(\"com.mysql.jdbc.Driver\").newInstance();"
+ "} catch (Exception e) {"
+ " System.out.println(e.toString());"
+ "}";
js.eval(code);

关于java - 有没有办法修改模块路径和程序化 JShell 实例的添加模块?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46399783/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com