java - 为什么 jrunscript 不支持我的类路径?

标签 java classloader rhino jdbc jsr223

我正在尝试使用 Java 6 中包含的 Rhino 从 JavaScript 进行一些 JDBC 访问。但是我无法让 DriverManager 找到我想使用的 Driver

这两个例子应该是等价的:

Java:

public class DbTest {
    public static void main(String[] argv) {
        java.sql.Connection c = null;
        try {
            java.lang.Class.forName("net.sourceforge.jtds.jdbc.Driver");
            c = java.sql.DriverManager.getConnection(
                "jdbc:jtds:sqlserver://myserver/mydb", "user", "password");
        }
        catch (Exception e) {
            c = null;
            System.out.println(e);
        };

        if(c != null) {
           System.out.println("yay, got c!");
           try {
               c.close();
           }
           catch(Exception e) {}
        } else {
           System.out.println("awww.");
        }
    }
}

JavaScript:

importPackage(Packages.net.sourceforge.jtds.jdbc);
java.lang.Class.forName('net.sourceforge.jtds.jdbc.Driver');
var c = null;
try {
    c = java.sql.DriverManager.getConnection(
        'jdbc:jtds:sqlserver://myserver/mydb', 'user', 'password');
}
catch (e) {
    c = null;
    println(e);
};

if(c) {
   println('yay, got c!');
   c.close();
} else {
   println('awww.');
}

...但是当我运行它们时,我得到了这种行为:

Java:

> java -cp .;jtds-1.2.5.jar DbTest
java.sql.SQLException: Unknown server host name 'myserver'.
awww.

太好了,它成功加载了驱动程序并尝试解析服务器。

JavaScript:

> jrunscript -cp .;jtds-1.2.5.jar dbtest.js
script error in file dbtest.js :
sun.org.mozilla.javascript.internal.WrappedException: 
Wrapped java.lang.ClassNotFoundException: 
net.sourceforge.jtds.jdbc.Driver (dbtest.js#2) in dbtest.js at line number 2

为什么找不到类?我尝试过使用和不使用 importPackage()importClass(),使用和不使用 Packages 前缀。如果我注释掉 forName,则 DriverManager 找不到合适的驱动程序。

最佳答案

根据 an IBM DeveloperWorks forum post ,“jrunscript -classpath 值由一个单独的“脚本”类加载器使用,该类加载器与通常的应用程序类加载器并行,用于解析 importClass() 和 importPackage() 中提到的类”。

并根据this SO answer , "... DriverManager 执行"使用直接调用者的类加载器实例的任务" "。

所以,除非你把驱动jar放到bootclasspath中或者想办法修改如何jrunscript (和 Ant <script /> )设置脚本环境的系统类加载器,让它工作的唯一方法似乎是跳过 DriverManager完全:

var c = null;
try {
    var p = new java.util.Properties();
    p.setProperty('user', 'user');
    p.setProperty('password', 'password');
    c = (new net.sourceforge.jtds.jdbc.Driver()).connect(
             'jdbc:jtds:sqlserver://myserver/mydb', p);
}
catch (e) {
    c = null;
    println(e);
};

if(c) {
   println('yay, got c!');
   c.close();
} else {
   println('awww.');
}

它删除了一层间接寻址,这可能是也可能不是那杯茶,但它有效(插入了真实的服务器/用户/密码):

$ jrunscript -cp jtds-1.2.5.jar dbtest_realparams.js 
yay, got c!

关于java - 为什么 jrunscript 不支持我的类路径?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3355262/

相关文章:

java - 如何获取JavaCompiler编译任务生成的类文件列表?

javascript - 使用 Rhino 在 Eclipse 中调试 Javascript

java - 为 kNN 算法发布加载数据集 - Java

java空引用复制

java - 方法内类加载器的上下文

android - 如何防止丢失的、未使用的注释类使我的程序崩溃?

java - ArrayList<Integer> 上的 indexOf 函数在 JSR 223(Rhino 脚本引擎)中不起作用

java - 为 rhino 构建 java 脚本调试器

java - 将 Blob 转换为带有特殊字符的字符串

java - Hibernate 不会在插入时将外键设置为父级主键的值