有没有办法修改程序化JShell实例的模块路径和添加的模块? [英] Is there a way to modify module path and added modules of a programmatic JShell instance?

查看:87
本文介绍了有没有办法修改程序化JShell实例的模块路径和添加的模块?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过使用

I'm trying to run some Java code at run-time through a JShell instance I created using the JShell API. To demonstrate my problem, I'm going to share my simple code.

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

With my current setup I have a directory called lib that has the MySQL Java driver: mysql-connector-java-5.1.35.jar.

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

Launching JShell via command tool and adding the needed module as:

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

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

and then loading the mysql driver works for me :

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


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


I've created a similar Java 9 module with module-info.java as:

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

src/example/loadmysql/Runner.java 为:

src/example/loadmysql/Runner.java as :

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实例也不需要.因此找不到课程.


It's clear that even though the example.loadmysql module requires the mysql connector, the created JShell instance doesn't. So it can't find the class.

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

Any ideas on how to programmatically add modules to a JShell instance, so it works like the direct JShell coding example?

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

UPDATE - I've figured out how to set the module path:

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

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

But that's not quite enough. I still have add the needed module somehow.

推荐答案

您可能可以使用

You can probably use addToClassPath before eval in your code as:

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);

指定的路径被添加到在 eval() .请注意,未命名包无法从 放置eval(String)代码的软件包.

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后返回,它基于类路径执行代码,因此,要向其添加任何其他依赖项,您需要使用相同的方法将其添加到类路径中

It seems from the documentation that the state of JShell returned post eval executes the code based on the classpath, hence in order to add any further dependencies to it, you would need to add it to the classpath using the same method.

在您的情况下,尽管您这样做,但我猜这里还是应该将 mysql-connector-java-5.1-35.jar 视为自动模块 >出现在类路径上,因此可以访问类com.mysql.jdbc.Driver.

In your case I am guessing here though as you do so, the mysql-connector-java-5.1.35.jar would ideally be treated to as an automatic module present on the classpath and hence the class com.mysql.jdbc.Driver would be accessible.

更新 :-进一步探索,我认为实现此目标的更好方法可能是尝试使用

Update :- Exploring further I think a better way to achieve this could be though trying to use Jshell.Builder and its option compilerOptions to create an instance with default compiling options somewhat like(not tested) -

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);

这篇关于有没有办法修改程序化JShell实例的模块路径和添加的模块?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆