从概念上说,当我加载新的Jar时,我正在做什么? URLClassloader是唯一的选择吗?我应该如何形成这些URL来指向包含更多jar的子目录。动态Jar加载令我困惑
如果有人感觉超级大方,一些演示代码做会以下是很有益的(假设“罐子/ a.jar文件”包含“MyClass的”,我们要实例):
- 从一个子目录加载一些罐子
- 返回从中
- 实例化类
从概念上说,当我加载新的Jar时,我正在做什么? URLClassloader是唯一的选择吗?我应该如何形成这些URL来指向包含更多jar的子目录。动态Jar加载令我困惑
如果有人感觉超级大方,一些演示代码做会以下是很有益的(假设“罐子/ a.jar文件”包含“MyClass的”,我们要实例):
概念特定类,我是什么DOI当我加载一个新的罐子时?
从概念上讲,您并未加载新的JAR。相反,您正在定义一个类加载器,它将根据需要从JAR文件加载代码和其他资源。
是URLClassloader唯一的选择吗?
从理论上讲,您可以实现自己的子类ClassLoader
,但这对于您正在尝试执行的操作不是必需的。
我该如何形成这些URL来指向包含更多jar的子目录。
这是我认为你的问题的核心。该URLClassLoader
构造解释URL[]
参数如下:
“与一个‘/’结尾被假定为是指一个目录下的任何URL否则,URL被假定为是指一个JAR文件,这将是根据需要下载并打开。“
在上述引用文本的第一种情况下,目录被假定为包含要加载的资源的树的根目录。
但我收集你正试图建立一个类加载器,将加载从给定目录中的所有JAR文件。为此,您需要:
File
对象的列表。URL
实例。File
,请使用File.toURL()
创建URL
并添加到该数组。 (使用File.toURL()
意味着您将获得将在您的平台上运行的JAR文件的kosher“file:”URL)。URL
阵列创建URLClassLoader
。如果已知jar包的列表,那么一个潜在的更好/更简单的解决方案就是将一个Class-Path条目添加到父jar的清单中。这样你就可以完全避免使用自定义类加载器。
Class-Path: jars/A.jar
显然这不会在构建时不知道相关的罐子的地方。
真的很短的版本:当你加载一个新的JAR时,你给了Java寻找类的新地方。
对于一个较长的解释,维基百科有与此相关的文章:http://en.wikipedia.org/wiki/Java_Classloader
另外,可以尝试:http://onjava.com/pub/a/onjava/2005/01/26/classloading.html
URLClassLoader的是不是你唯一的选择;退房http://download-llnw.oracle.com/javase/tutorial/deployment/jar/apiindex.html
回复:网址应如何形成的,从Java文档(http://download-llnw.oracle.com/javase/7/docs/api/java/net/URLClassLoader.html):
这个类加载器用于从URL中既指JAR文件的搜索路径加载类和资源,目录。任何以'/'结尾的URL都被假定为指向一个目录。否则,假定该URL是指将根据需要打开的JAR文件。
从How should I load Jars dynamically at runtime?改编:
URLClassLoader child = new URLClassLoader (new URL("jars/A.jar"), this.getClass().getClassLoader());
Class classToLoad = Class.forName ("com.myClass", true, child);
Method method = classToLoad.getDeclaredMethod ("myMethod");
Object instance = classToLoad.newInstance();
Object result = method.invoke (instance);
而且,上面链接的答案列出来URLClassLoader的一些更多的选择(他们提到的OSGi,JCL,和其他几个人,其中没有我有任何经验或我会在这里说点什么)。
HTH
简单的方法是,以确保相关的JAR在类路径中启动程序之前。
如果要从子目录加载,则需要确定要提供给URLClassLoader的JAR路径。您可以使用这样的事情让你的程序的路径:
new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath())
这是一个黑客攻击的一位,但我不知道任何官方的方式来获得一个Java程序的路径。
如果要动态加载一个JAR,这样你可以使用它,如果你已经在类路径中指定,看看这个thread。这绝对是不受支持的黑客领域,但它也很简单。
修改,我使用的版本:
import java.io.File;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
/**
* Hack to modify classpath at runtime. Can be used to load JARs as if they were
* loaded from the start.
*
* Warning: May break if URLClassLoader changes
*
* @author Antony Miguel
*/
public class ClasspathHacker {
/**
* Add a file to the classpath.
*
* @param pPath
* path to the file
*/
public static void addFile(String pPath) {
File f = new File(pPath);
addFile(f);
}
/**
* Add a file to the classpath.
*
* @param pFile
* the file to be added
*/
public static void addFile(File pFile) {
try {
addURL(pFile.toURI().toURL());
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
/**
* Add the content pointed to by a URL to the classpath.
*
* @param pURL
* the URL pointing to the content to be added
*/
public static void addURL(URL pURL) {
/*
* Use reflection to call addURL on the system classloader, which we
* expect to be a URLClassLoader
*/
Method method;
try {
method = URLClassLoader.class.getDeclaredMethod("addURL",
new Class[] { URL.class });
method.setAccessible(true);
method.invoke(ClassLoader.getSystemClassLoader(),
new Object[] { pURL });
} catch (Exception e) {
e.printStackTrace();
}
}
}
究竟怎样的是 '动态的' 负荷? – djangofan 2010-11-03 22:38:40