- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在尝试通过使用 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 whicheval(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/
我正在尝试创建自定义 JShell 提示符并希望直接从文件加载它。 但是当从文件加载设置提示时它没有显示自定义提示,但我能够在 JShell 上编写相同的命令。 例如:我有一个文件“jshell_pr
从 jShell 脚本内部,是否可以访问或注册在创建 JShell 的代码中定义的变量? 目前似乎没有机制可以访问或注册一个变量到 Shell 实例,或者从 JShell 内部返回无字符串类型(如对象
从 jShell 脚本内部,是否可以访问或注册在创建 JShell 的代码中定义的变量? 目前似乎没有机制可以访问或向 Shell 实例注册变量,或者从 JShell 内部返回任何字符串类型(如对象或
我已经下载并“手动”安装了适用于 Linux 64 位版本的 JDK 10(适用于 Ubuntu 16.04), Oracle Java SE Development Kit(注意:我想下载 Java
我正在使用 JDK9 的 jshell。 我刚刚创建了一个最终变量并为其分配了一个值。 在下一行中,我只是修改了值。令我惊讶的是,修改最终变量时没有错误。 以下是代码片段: jshell> final
我是 java 9 的新手,只是在 jshell 上练习一些代码片段 jshell> System.out.println("hello"); hello jshell> System.out.
有人知道 JShell 历史记录存储在哪里(Windows-10 上的 Java-11/Open JDK,但任何配置都可能有用)?我一直在$HOME($USERPROFILE,$APPDATA,...
我想像这样运行 jshell $ jshell --execute 'System.out.println("Hello World")' Hello World $ 因此它执行 java 单行代码并
我看了几个 JShell 教程,但我仍然不明白最重要的部分:我为什么要使用 JShell? 甲骨文是这样说的: "You can test individual statements, try out
tl;dr:如何在不替换此类的情况下向现有类添加方法? 描述: 当我在 JShell 中运行以下命令时: public class TestClass {} 打印出以下输出: created clas
如何在 JShell 中查找变量或表达式结果的类型。 在 Java 中试验按位运算符 jshell> byte b=5 5 -2147483648 jshell> 有没有像 Python type(5
我在我的机器上使用 'jshell 命令,它无法被识别。但是 java 命令工作正常。 jdk 10 中的jshell 是否有任何环境设置 C:\Users\Kannan λ jshell 'jshe
当我在 JShell (9.0.1) 中输入一个表达式时,它返回: $22 -> 22 从哪里来,$1 到 $21 发生了什么? (它们是未定义的。) 我似乎隐约记得(当我开始使用 Java 9.0
我找到了 this问题,这个 other ,如此有趣以至于引出了几个问题,至少对我而言: 相当开放式的问题,但是 jshell 被限制 在哪里?显然,GUI 应用程序不属于 jshell 解决方案或
如何指示 jshell 在脚本末尾终止,类似于其他语言的解释器,例如 python3 或 node? 以下命令 ./jshell -q /tmp/shell.java 带有脚本/tmp/shell.j
我该怎么做 /exit jshell具有非零错误代码的 session ? /exit产量:进程完成,退出代码 0 /exit 1产量:进程完成,退出代码 0 throw new Error("1")
我正在发现 JShell,并且发现默认添加的导入: jshell> /imports | import java.io.* | import java.math.* | import
为什么我的 jshell 实例(JDK 版本 9-ea)无法识别 printf() 语句?以下是我观察到的错误, jshell> printf("Print number one - %d",1) |
关注帖子Is there a way to remove imports in JShell? .我想知道是否还有办法摆脱默认导入。 jshell> /imports | import java
根据文档, There’s also the option to load a script on startup, including some special predefined options
我是一名优秀的程序员,十分优秀!