自定义URLClassLoader,运行时出现NoClassDefFoundError [英] Custom URLClassLoader, NoClassDefFoundError when run
问题描述
我创建了自己的URLClassLoader
,并通过java.system.class.loader
将其设置为系统类加载器.它已初始化,并且一切正常,但是找不到我要加载的类.这是URLClassLoader
:
I've created my own URLClassLoader
, and set it as the system classloader via java.system.class.loader
. It's initialized and everything, but the classes I'm trying to load aren't found. Here's the URLClassLoader
:
public class LibraryLoader extends URLClassLoader
{
public LibraryLoader(ClassLoader classLoader)
{
super(new URL[0], classLoader);
}
synchronized public void addJarToClasspath(String jarName) throws MalformedURLException, ClassNotFoundException
{
File filePath = new File(jarName);
URI uriPath = filePath.toURI();
URL urlPath = uriPath.toURL();
System.out.println(filePath.exists());
System.out.println(urlPath.getFile());
addURL(urlPath);
}
}
我已经确认罐子存在,并且路径正确.这是我在程序中的调用方式:
I've confirmed that the jar exists, and that the path is correct. This is how I call it in my program:
LibraryLoader loader = (LibraryLoader) ClassLoader.getSystemClassLoader();
loader.addJarToClasspath("swt.jar");
这是我得到的例外(行166指的是我尝试创建新的Point
的行:
This is the exception that I get (line 166 refers to the line at which I try to create a new Point
:
Exception in thread "main" java.lang.NoClassDefFoundError: org/eclipse/swt/graphics/Point
at mp.MyProgram.loadArchitectureLibraries(MyProgram.java:116)
at mp.MyProgram.main(MyProgram.java:90)
Caused by: java.lang.ClassNotFoundException: org.eclipse.swt.graphics.Point
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 2 more
我什至尝试像这样显式加载类:
I even tried explicitly loading the class like so:
Class.forName("org.eclipse.swt.graphics.Point", false, loader);
可能是什么原因造成的?它不应该行之有效"吗?
What might be causing this? Shouldn't it "just work"?
更新:这是MyProgram
public class MyProgram
{
// ...
public static void main(String[] args)
{
loadArchitectureLibraries();
// ...
}
public static void loadArchitectureLibraries()
{
LibraryLoader loader = (LibraryLoader) ClassLoader.getSystemClassLoader();
String architecture = System.getProperty("os.arch");
try {
if (architecture.contains("64")) {
loader.addJarToClasspath("swt-3.6.1-win32-win32-x86_64.jar");
} else {
loader.addJarToClasspath("swt-3.6.1-win32-win32-x86.jar");
}
Class.forName("org.eclipse.swt.graphics.Point", false, loader);
org.eclipse.swt.graphics.Point pt = new org.eclipse.swt.graphics.Point(0, 0);
} catch (Exception exception) {
exception.printStackTrace();
System.out.println("Could not load SWT library");
System.exit(1);
}
}
}
更新2::这是一个SSCCE: http://nucleussystems.com/files/myprogram.zip .呼叫java -Djava.system.class.loader=mp.LibraryLoader -jar myprogram.jar
.
Update 2: Here's an SSCCE: http://nucleussystems.com/files/myprogram.zip . Call java -Djava.system.class.loader=mp.LibraryLoader -jar myprogram.jar
.
推荐答案
从几英里远可以看到您没有在Class.forName
It's visible from a (few) mile(s) away you are not using the custom classloader beside Class.forName
由于已加载当前类MyProgram
的类加载器尝试加载org.eclipse.swt.graphics.Point,所以发生了ClassNoDefFoundError.
The ClassNoDefFoundError occurs since the classloader that has loaded current class MyProgram
attempts to load org.eclipse.swt.graphics.Point.
您需要通过Class.forName加载另一个类(称为启动器),然后从那里开始-实现一些接口(甚至可以运行)并调用它.
You need to load another class (call it launcher) via Class.forName and then start from there - implement some interface (even runnable will do) and call it.
编辑
如何做,这是一个简单的场景.
1.创建另一个名为mp.loader.Launcher
的类,该类实现了这样的Runnable.
How to do it, a simplistic scenario.
1. Create another class called mp.loader.Launcher
that implements Runnable like that.
public class Launcher implements Runnable{
public void run(){
org.eclipse.swt.graphics.Point pt = new org.eclipse.swt.graphics.Point(0, 0);
//whatever, start from here.
}
}
2.将其放在另一个名为swt-loader.jar的jar中.
2. Place it in another jar called swt-loader.jar.
在MyProgram类中使用:
in MyProgram class use:
loader.addJarToClasspath("swt-loader.jar");
Runnable r = (Runnable) Class.forName("mp.loader.Launcher", true, loader);
r.run();//there you have
这篇关于自定义URLClassLoader,运行时出现NoClassDefFoundError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!