加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

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

发布时间:2020-12-15 01:08:11 所属栏目:Java 来源:网络整理
导读:我试图通过我使用JShell API创建的JShell实例在运行时运行一些Java代码.为了演示我的问题,我将分享我的简单代码. 在我目前的设置中,我有一个名为lib的目录,它有MySQL Java驱动程序:mysql-connector-java-5.1.35.jar. 通过命令工具启动JShell并添加所需的模

我试图通过我使用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之前的addToClassPath

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返回post 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);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读