我想在程序找不到引用的类的位置时让用户手动指定类所在jar包(如jdbc驱动等)的具体位置,只加载一个jar包倒是可以,可我要同时加载多个jar,怎么弄都不对——我用sqlServer的jdbc包测试的,在实例化类的时候没错,可一到连接数据库时就出错了,但我按正常方式加载jar包(用IDE预设好)时程序又能正确运行!程序片段如下大侠们帮看一下:
//这里是重新写的ClassLoader的子类,加载多个jar不行
public class LazyClassLoader extends URLClassLoader {
/**
* 或者是构造函写得不对??那该怎么写呢?
*
* */
public LazyClassLoader() {
super(new URL[0], ClassLoader.getSystemClassLoader());
}
public void selectPath(String[] paths) {
for(int i=0;i<paths.length;i++){
if (paths[i] == null || paths[i].length() <= 0) {
return;
} String separator = System.getProperty("path.separator");
String[] pathToAdds = paths[i].split(separator);
for (int j = 0; j < pathToAdds.length; j++) {
if (pathToAdds[j] != null && pathToAdds[j].length() > 0) {
try {
File pathToAdd = new File(pathToAdds[j]).getCanonicalFile();
System.out.println(pathToAdd.toURL());
addURL(pathToAdd.toURL());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
//直接用CloassLoader类也不行
/**
* @@@@@jdbc驱动加载及异常处理
* */
private Driver driverLoad(String driverStr){
Driver driver = null;
try{
driver = (Driver)Class.forName(driverStr).newInstance();
}catch(Exception ex){
//如果加载出现异常,即找不到相关的驱动程序所在包,弹出窗口供用户选择具体包路径
System.out.println("加载驱动出错,下面由用户手动加载:"+ex.fillInStackTrace());
try{
//这是用户自选得到的文件列表
File[] fileList = getJarFileList();
URL[] url = new URL[fileList.length] ;
for(int i=0;i<fileList.length;i++){
File myfile=fileList[i];
//由于取得的字符串是“c:\adf\x.jar”的形式,所以进行转换以便符合URL规则
String tFile = "file:"+myfile.getPath().replace('\\','/');
URL u = new URL(tFile);
url[i]=u;
}
URLClassLoader classLoader = new URLClassLoader(url, Thread.currentThread().getContextClassLoader());
driver = (Driver)Class.forName(driverStr,true,classLoader).newInstance();
System.out.println(url); }catch(Exception ioe){
System.err.print("再次加载jdbc驱动时出错:");
ioe.printStackTrace();
//以后在此加一个弹出窗口,显示错误信息
} }
return driver;
}
//////////////////////////////////以下是出现的异常(两个片段都这样)
java.lang.NullPointerException
at com.lazy.face.db.DBConnection.setStatement(DBConnection.java:44)
at com.lazy.face.db.DBOperation.showTable(DBOperation.java:20)
at com.lazy.face.LazyFrame.refresh_mouseClicked(LazyFrame.java:331)
at com.lazy.face.LazyFrame_refresh_mouseAdapter.mouseClicked(LazyFrame.java:408)
at java.awt.AWTEventMulticaster.mouseClicked(AWTEventMulticaster.java:208)
at java.awt.Component.processMouseEvent(Component.java:5137)
at java.awt.Component.processEvent(Component.java:4931)
at java.awt.Container.processEvent(Container.java:1566)
at java.awt.Component.dispatchEventImpl(Component.java:3639)
at java.awt.Container.dispatchEventImpl(Container.java:1623)
at java.awt.Component.dispatchEvent(Component.java:3480)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:3450)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3174)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3095)
at java.awt.Container.dispatchEventImpl(Container.java:1609)
at java.awt.Window.dispatchEventImpl(Window.java:1590)
at java.awt.Component.dispatchEvent(Component.java:3480)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:450)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:197)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:144)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:136)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:99)
连接数据库出错java.sql.SQLException: No suitable driver
////////////////////////////////已经正确加载jar包了,可是还jdbc的位置不对??所以很愈闷!高手路过一定要帮帮忙啊!谁帮忙解决了一定n分(n>=90)谢!!
//这里是重新写的ClassLoader的子类,加载多个jar不行
public class LazyClassLoader extends URLClassLoader {
/**
* 或者是构造函写得不对??那该怎么写呢?
*
* */
public LazyClassLoader() {
super(new URL[0], ClassLoader.getSystemClassLoader());
}
public void selectPath(String[] paths) {
for(int i=0;i<paths.length;i++){
if (paths[i] == null || paths[i].length() <= 0) {
return;
} String separator = System.getProperty("path.separator");
String[] pathToAdds = paths[i].split(separator);
for (int j = 0; j < pathToAdds.length; j++) {
if (pathToAdds[j] != null && pathToAdds[j].length() > 0) {
try {
File pathToAdd = new File(pathToAdds[j]).getCanonicalFile();
System.out.println(pathToAdd.toURL());
addURL(pathToAdd.toURL());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
//直接用CloassLoader类也不行
/**
* @@@@@jdbc驱动加载及异常处理
* */
private Driver driverLoad(String driverStr){
Driver driver = null;
try{
driver = (Driver)Class.forName(driverStr).newInstance();
}catch(Exception ex){
//如果加载出现异常,即找不到相关的驱动程序所在包,弹出窗口供用户选择具体包路径
System.out.println("加载驱动出错,下面由用户手动加载:"+ex.fillInStackTrace());
try{
//这是用户自选得到的文件列表
File[] fileList = getJarFileList();
URL[] url = new URL[fileList.length] ;
for(int i=0;i<fileList.length;i++){
File myfile=fileList[i];
//由于取得的字符串是“c:\adf\x.jar”的形式,所以进行转换以便符合URL规则
String tFile = "file:"+myfile.getPath().replace('\\','/');
URL u = new URL(tFile);
url[i]=u;
}
URLClassLoader classLoader = new URLClassLoader(url, Thread.currentThread().getContextClassLoader());
driver = (Driver)Class.forName(driverStr,true,classLoader).newInstance();
System.out.println(url); }catch(Exception ioe){
System.err.print("再次加载jdbc驱动时出错:");
ioe.printStackTrace();
//以后在此加一个弹出窗口,显示错误信息
} }
return driver;
}
//////////////////////////////////以下是出现的异常(两个片段都这样)
java.lang.NullPointerException
at com.lazy.face.db.DBConnection.setStatement(DBConnection.java:44)
at com.lazy.face.db.DBOperation.showTable(DBOperation.java:20)
at com.lazy.face.LazyFrame.refresh_mouseClicked(LazyFrame.java:331)
at com.lazy.face.LazyFrame_refresh_mouseAdapter.mouseClicked(LazyFrame.java:408)
at java.awt.AWTEventMulticaster.mouseClicked(AWTEventMulticaster.java:208)
at java.awt.Component.processMouseEvent(Component.java:5137)
at java.awt.Component.processEvent(Component.java:4931)
at java.awt.Container.processEvent(Container.java:1566)
at java.awt.Component.dispatchEventImpl(Component.java:3639)
at java.awt.Container.dispatchEventImpl(Container.java:1623)
at java.awt.Component.dispatchEvent(Component.java:3480)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:3450)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3174)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3095)
at java.awt.Container.dispatchEventImpl(Container.java:1609)
at java.awt.Window.dispatchEventImpl(Window.java:1590)
at java.awt.Component.dispatchEvent(Component.java:3480)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:450)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:197)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:144)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:136)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:99)
连接数据库出错java.sql.SQLException: No suitable driver
////////////////////////////////已经正确加载jar包了,可是还jdbc的位置不对??所以很愈闷!高手路过一定要帮帮忙啊!谁帮忙解决了一定n分(n>=90)谢!!
URL url = file.toURL();
URLClassLoader loader = new URLClassLoader(new URL[] { url });
Class tidyClazz = loader.loadClass(所需class的含包名的全名);用这种方式加载jar包试试吧。
-------------------------
另外,我总觉得 ClassLoader.getSystemClassLoader() 和 Thread.currentThread().getContextClassLoader() 可疑,你不妨改成 DBConnection.class.getClassLoader() 试试。
================================
改了,依然不对。Thread.currentThread().getContextClassLoader() 主要是为了在不同环境下,比如从纯界面的应用移值到web等环境时可用(有相关文档是这么说的)。但你这提法倒是让我想到,会不会是jdbc驱动包(可一个包又对...)的加载一定要指定哪一个父类加载器。或用改用别的构造函数?!
-----------------------------------
maquan('ma:kju)
是不是因为你使用的 ClassLoader 实例没有保持住,造成由其加载的 class 也就都释放了?
==========================================
这也有可能,但要怎么样保持住它呢,让它自已调用自己??但是我用别的方法(比如设ide或直接放到相应位置)直接加载了这些包,用同样的方法实例化以后,接下来的应用却一点问题也没有(都能找到包,正确加载并正确实例化,区别就是手动加载并实例化以后,用DriverManager找不到任何已经注册的驱动)!!真晕!
File myfile=fileList[i];
//由于取得的字符串是“c:\adf\x.jar”的形式,所以进行转换以便符合URL规则
String tFile = "file:"+myfile.getPath().replace('\\','/');
URL u = new URL(tFile);你这样得到的 tFile 可能并不一定是一个合法的 URL,应该改成下面的方法:
File myfile=fileList[i];
URL u = myfile.toURL();
url[i] = fileList[i].toURL() ;
}
用这个试一下