我正在尝试在运行时将jar文件添加到classpath。我用这个代码
public static void addURL(URL u) throws IOException {
URLClassLoader sysloader = (URLClassLoader) ClassLoader
.getSystemClassLoader();
Class<URLClassLoader> sysclass = URLClassLoader.class;
try {
Method method = sysclass.getDeclaredMethod("addURL", parameters);
method.setAccessible(true);
method.invoke(sysloader, new Object[] { u });
System.out.println(u);
} catch (Throwable t) {
t.printStackTrace();
throw new IOException("Error");
}
}
系统输出打印此网址:
file:/B:/Java/Tools/mysql-connector-java-5.1.18/mysql-connector-java-5.1.18/mysql-connector-java-5.1.18-bin.jar
我仔细检查了这条路,这个罐子存在。即使这个测试显示com.mysql.jdbc。 驱动程序类存在。
javap -classpath "B:\Java\Tools\mysql-connector-java-5.1.18\
mysql-connector-java-5.1.18\mysql-connector-java-5.1.18-bin.jar" com.mysql.jdbc.
Driver
Compiled from "Driver.java"
public class com.mysql.jdbc.Driver extends com.mysql.jdbc.NonRegisteringDriver i
mplements java.sql.Driver{
public com.mysql.jdbc.Driver() throws java.sql.SQLException;
static {};
}
但是当我使用这个Class.forName(驱动程序)时,我仍然得到java.lang.ClassNotFoundException。 这段代码有什么问题?
答案 0 :(得分:5)
网址没问题,但是你尝试从类路径加载一个jar,所以这意味着你需要先把文件放在cp中。 在你的情况下,你想加载一个不在类路径中的jar,所以你必须使用 URLClassLoader和JAR也可以使用JARClassLoader 如果你想要一些示例课程: http://docs.oracle.com/javase/tutorial/deployment/jar/jarclassloader.html
这里我自己跑的样本看看是否有帮助。它搜索不在我的类路径中的Log4j的Logger类,当然我在调用构造函数时遇到异常,因为我没有将正确的参数传递给构造函数
package org.stackoverflow;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
public class URLClassLoaderSample
{
public static void main(String[] args) throws Exception
{
File f = new File("C:\\_programs\\apache\\log4j\\v1.1.16\\log4j-1.2.16.jar");
URLClassLoader urlCl = new URLClassLoader(new URL[] { f.toURL()},System.class.getClassLoader());
Class log4jClass = urlCl.loadClass("org.apache.log4j.Logger");
log4jClass.newInstance();
}
}
Exception in thread "main" java.lang.InstantiationException: org.apache.log4j.Logger
at java.lang.Class.newInstance0(Class.java:357)
at java.lang.Class.newInstance(Class.java:325)
at org.stackoverflow.URLClassLoaderSample.main(URLClassLoaderSample.java:19)
由于错误的调用导致异常,但在此阶段我们已经找到了类
答案 1 :(得分:1)
好的,尝试使用DataSource的替代方法,而不是直接使用Driver 下面是代码(使用oracle驱动程序,我没有我的sql db,但属性是相同的) 通常使用DataSource接口是自JDBC 2.0以来的首选方法 对于下面的测试,DataSource jar不在类路径中
public static void urlCLSample2() throws Exception
{
File f = new File("C:\\_programs\\jdbc_drivers\\oracle\\v11.2\\ojdbc6.jar");
URLClassLoader urlCl = new URLClassLoader(new URL[] { f.toURL() }, System.class.getClassLoader());
// replace the data source class with MySQL data source class.
Class dsClass = urlCl.loadClass("oracle.jdbc.pool.OracleDataSource");
DataSource ds = (DataSource) dsClass.newInstance();
invokeProperty(dsClass, ds, "setServerName", String.class, "<put your server here>");
invokeProperty(dsClass, ds, "setDatabaseName", String.class, "<put your db instance here>");
invokeProperty(dsClass, ds, "setPortNumber", int.class, <put your port here>);
invokeProperty(dsClass, ds, "setDriverType",String.class, "thin");
ds.getConnection("<put your username here>", "<put your username password here>");
System.out.println("Got Connection");
}
// Helper method to invoke properties
private static void invokeProperty(Class dsClass, DataSource ds, String propertyName, Class paramClass,
Object paramValue) throws Exception
{
try
{
Method method = dsClass.getDeclaredMethod(propertyName, paramClass);
method.setAccessible(true);
method.invoke(ds, paramValue);
}
catch (Exception e)
{
throw new Exception("Failed to invoke method");
}
}