自定义URLClassLoader,运行时出现NoClassDefFoundError [英] Custom URLClassLoader, NoClassDefFoundError when run

查看:863
本文介绍了自定义URLClassLoader,运行时出现NoClassDefFoundError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了自己的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆