java 在运行时加载 jars
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10624907/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Loading jars at runtime
提问by itun
I am trying to add jar file to classpath at runtime. I use this code
我正在尝试在运行时将 jar 文件添加到类路径。我用这个代码
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");
}
}
System out prints this url:
系统输出打印这个网址:
file:/B:/Java/Tools/mysql-connector-java-5.1.18/mysql-connector-java-5.1.18/mysql-connector-java-5.1.18-bin.jar
I was check this path carefully, this jar exist. Even this test show that com.mysql.jdbc. Driver class exists.
我仔细检查了这条路径,这个罐子存在。连这个测试都显示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 {};
}
But I still get java.lang.ClassNotFoundException when I use this Class.forName(driver). What is wrong with this code?
但是当我使用这个 Class.forName(driver) 时,我仍然得到 java.lang.ClassNotFoundException。这段代码有什么问题?
采纳答案by miks
The URL is ok, nevertheless you try to load a jar from classpath, so it means that yo need to have the file in cp first. In your case you want to load a jar that is not in classpath so you have to use URLClassLoader and for JAR you can use also the JARClassLoader If you want some sample lesson on it: http://docs.oracle.com/javase/tutorial/deployment/jar/jarclassloader.html
URL 没问题,但是您尝试从类路径加载 jar,因此这意味着您需要先将文件放在 cp 中。在您的情况下,您想加载一个不在类路径中的 jar,因此您必须使用 URLClassLoader,对于 JAR,您也可以使用 JARClassLoader 如果您想要一些示例课程:http://docs.oracle.com/javase/ 教程/部署/jar/jarclassloader.html
Here a sample I ran by myself see if helps you. It search the Logger class of Log4j that is not in my classpath, of course i got exception on invocation of the constructor since i did not pass the right params to the constructor
这是我自己运行的示例,看看是否对您有帮助。它搜索不在我的类路径中的 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)
Exception due to the wrong invocation, nevertheless at this stage we already found the class
由于错误调用导致的异常,不过在这个阶段我们已经找到了类
回答by miks
Ok try the alternative approach with DataSource and not directly the Driver Below is the code (working with oracle driver, i don't have my sql db, but the properties are the same) Generally using the DataSource interface is the preferred approach since JDBC 2.0 The DataSource jar was not in the classpath neither for the test below
好的,请尝试使用 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");
}
}