为什么jrunscript不尊重我的类路径?
问题描述:
我正在尝试使用Java 6中包含的Rhino来执行一些JDBC访问。但是我无法让DriverManager
找到我想要使用的Driver
。为什么jrunscript不尊重我的类路径?
这两个例子应该是等价的:
的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到引导类路径或找到一种方法来修改如何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.');
}
它消除一个间接层,其可以是或可以不是那些杯茶,但它的工作原理(与真实服务器/用户/ passwd中插入):
$ jrunscript -cp jtds-1.2.5.jar dbtest_realparams.js
yay, got c!
试了一下现在在Linux中,完全相同行为。还尝试运行'java -cp blabla com.sun.tools.script.shell.Main dbtest.js',没有区别。 – clacke 2010-07-28 21:02:33
怀疑这是一个安全问题,并且脚本引擎使用自己的类加载器运行。所以问题是可以修改的地方。 试过运行一个Ant'',它有一个类路径属性,显然是为了脚本的好处。也不起作用。 – clacke 2010-07-28 21:22:03
'java -cp $ JAVA_HOME/lib/tools.jar -Xbootclasspath:“$ JAVA_HOME/jre/lib/rt.jar:$ JAVA_HOME/jre/lib/resources.jar:jtds-1.2.5.jar”com.sun .tools.script.shell.Main dbtest.js'工作。但是我想知道为什么'jrunscript'和''似乎都不能使用正常的类路径,以及它们使用哪一个。 – clacke 2010-07-28 21:33:13