我正在尝试将类动态加载到组件中。我正在使用文件选择器来选择将要加载的.JAR文件,然后使用选项窗格来获取类的名称。
我已经在互联网上搜索如何将java文件转换为URL以便在URLClassLoader中加载它我已经提出:
File myFile = filechooser.getSelectedFile();
String className = JOptionPane.showInputDialog(
this, "Class Name:", "Class Name", JOptionPane.QUESTION_MESSAGE);
URL myUrl= null;
try {
myUrl = myFile.toURL();
} catch (MalformedURLException e) {
}
URLClassLoader loader = new URLClassLoader(myUrl);
loader.loadClass(className);
我现在收到一个'无法找到符号'错误,无法将网址加载到URLClassLoader
答案 0 :(得分:8)
我喜欢the answer by Zellus中提到的ClassPathHacker类,但它充满了不赞成的调用和不良做法,所以这里是一个重写版本,它还缓存了Classloader和addUrl方法:
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.io.IOException;
import java.io.File;
public class ClassPathHacker{
private static final Class<URLClassLoader> URLCLASSLOADER =
URLClassLoader.class;
private static final Class<?>[] PARAMS = new Class[] { URL.class };
public static void addFile(final String s) throws IOException{
addFile(new File(s));
}
public static void addFile(final File f) throws IOException{
addURL(f.toURI().toURL());
}
public static void addURL(final URL u) throws IOException{
final URLClassLoader urlClassLoader = getUrlClassLoader();
try{
final Method method = getAddUrlMethod();
method.setAccessible(true);
method.invoke(urlClassLoader, new Object[] { u });
} catch(final Exception e){
throw new IOException(
"Error, could not add URL to system classloader");
}
}
private static Method getAddUrlMethod()
throws NoSuchMethodException{
if(addUrlMethod == null){
addUrlMethod =
URLCLASSLOADER.getDeclaredMethod("addURL", PARAMS);
}
return addUrlMethod;
}
private static URLClassLoader urlClassLoader;
private static Method addUrlMethod;
private static URLClassLoader getUrlClassLoader(){
if(urlClassLoader == null){
final ClassLoader sysloader =
ClassLoader.getSystemClassLoader();
if(sysloader instanceof URLClassLoader){
urlClassLoader = (URLClassLoader) sysloader;
} else{
throw new IllegalStateException(
"Not an UrlClassLoader: "
+ sysloader);
}
}
return urlClassLoader;
}
}
答案 1 :(得分:5)
ClassPathHacker.java
是一个动态加载类的选项。
import java.lang.reflect.*;
import java.io.*;
import java.net.*;
public class ClassPathHacker {
private static final Class[] parameters = new Class[]{URL.class};
public static void addFile(String s) throws IOException {
File f = new File(s);
addFile(f);
}//end method
public static void addFile(File f) throws IOException {
addURL(f.toURL());
}//end method
public static void addURL(URL u) throws IOException {
URLClassLoader sysloader = (URLClassLoader)ClassLoader.getSystemClassLoader();
Class sysclass = URLClassLoader.class;
try {
Method method = sysclass.getDeclaredMethod("addURL",parameters);
method.setAccessible(true);
method.invoke(sysloader,new Object[]{ u });
} catch (Throwable t) {
t.printStackTrace();
throw new IOException("Error, could not add URL to system classloader");
}//end try catch
}//end method
}//end class
答案 2 :(得分:2)
答案 3 :(得分:1)
URLClassLoader takes an array of URLs的构造函数,而不是单个URL。
答案 4 :(得分:0)
我在scala中重写了这个,以防任何人需要,因为它不是100%琐碎:)
/*
* Class which allows URLS to be "dynamically" added to system class loader
*/
object class_path_updater {
val URLCLASSLOADER = classOf[URLClassLoader]
var urlClassLoader = getUrlClassLoader
var addUrlMethod = getAddUrlMethod
/*
* addFile - have to use reflection to retrieve and call class loader addURL method as it is protected
*/
def addFile(s: String) = {
val urlClassLoader = getUrlClassLoader
try {
val method = getAddUrlMethod
method.setAccessible(true)
val v = (new File(s)).toURI.toURL
invoke(urlClassLoader, method, Array[AnyRef](v))
def invoke(proxy: AnyRef, m: Method, args: Array[AnyRef]) = m.invoke(proxy, args: _*)
}
}
private def getAddUrlMethod: Method = {
if (addUrlMethod == null) addUrlMethod = URLCLASSLOADER.getDeclaredMethod("addURL", classOf[URL])
addUrlMethod
}
private def getUrlClassLoader: URLClassLoader = {
if (urlClassLoader == null) {
val sysLoader = ClassLoader.getSystemClassLoader
sysLoader match {
case x: URLClassLoader => urlClassLoader = sysLoader.asInstanceOf[URLClassLoader]
case _ => throw new IllegalStateException("Not a UrlClassLoader: " + sysLoader)
}
}
urlClassLoader
}
}