当前位置: 首页 > 面试题库 >

自定义URLClassLoader,运行时出现NoClassDefFoundError

湛文乐
2023-03-14
问题内容

我已经创建了自己的文件URLClassLoader,并通过将其设置为系统类加载器java.system.class.loader。它已经初始化,并且一切正常,但是找不到我要加载的类。这是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);
    }
}

我已确认该罐子存在,并且路径正确。这是我在程序中如何称呼它:

LibraryLoader loader = (LibraryLoader) ClassLoader.getSystemClassLoader();
loader.addJarToClasspath("swt.jar");

这是我得到的例外(第166行是指我尝试创建新行的行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

我什至尝试像这样显式加载类:

Class.forName("org.eclipse.swt.graphics.Point", false, loader);

是什么原因造成的?它不应该“正常工作”吗?

更新: 这是来自的重要代码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


问题答案:

从您不在旁边使用自定义类加载器的一(几)英里处可见 Class.forName

由于已加载当前类的类加载器MyProgram尝试加载org.eclipse.swt.graphics.Point
,因此发生ClassNoDefFoundError 。

您需要通过Class.forName加载另一个类(称为启动器),然后从那里开始-实现一些接口(即使是runnable也可以)并调用它。

编辑

怎么做,一个简单的场景。
1.创建另一个名为mp.loader.LauncherRunnable的类。

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中。

在MyProgram类中使用:

loader.addJarToClasspath("swt-loader.jar");
Runnable r = (Runnable) Class.forName("mp.loader.Launcher", true, loader);
r.run();//there you have


 类似资料:
  • 我正在尝试使用AWS CDK而不是无服务器在AWS Lambda中使用Bref自定义运行时。 CDK代码如下所示。 这里是完整的源代码https://github.com/petrabarus/cdk-bref-function 当我尝试使用AWS CLI手动调用时,它显示错误。 Cloudwatch日志显示了如下内容。 如果我将部署与无服务器框架进行比较,那么配置(层、代码等)几乎是相同的。我错

  • 故事 我用的是keycloak 6.0.1。我有一个领域有两种类型的用户:管理员和常规用户。我需要一个主题,可以区分他们之间,因为登录是不同的(3字段vs 2字段)。因此,我希望扩展提供程序FreeMarkerLoginFormsProvider以传递一个自定义参数。我正在使用keycloak部署器部署我的SPI。 Keycloak在部署时不幸引发异常: 我也尝试过模块方法,但得到一个NullPo

  • 所以我复制了这个项目,它使用swift作为自定义lambda运行时,并使用makefile作为构建方法。 现在我创建了一个AWS CodePipeline,它使用使用CodeBuild打包我的项目,并最终通过CloudForm部署它。 我的lambda的设置在根文件夹中,就像我在上面链接的repo中看到的那样。我认为这是应该的,正如我在自定义运行时部分的sam文档中看到的那样。问题是打包了我的整个

  • 问题内容: 我需要为应用程序的某些部分向现有应用程序添加插件功能。我希望能够在运行时添加jar,并且应用程序应该能够从jar中加载类,而无需重新启动应用程序。到目前为止,一切都很好。我使用URLClassLoader在线找到了一些示例,并且运行良好。 我还希望能够在罐子的更新版本可用时重新加载相同的类。我再次发现了一些示例,据我所知,实现此目标的关键是我需要为每个新负载使用一个新的类加载器实例。

  • 问题内容: 我想将我的python软件包设为“ pip installable”。问题在于,程序包具有必须来自用户的初始Shell脚本(例如)的Shell脚本。 但是在安装之后,用户并不完全知道脚本的去向(大概是,但是我们不能保证)。当然,用户可以运行并手动编辑其初始化脚本。 但我想使这一步骤自动化。我可以创建一个新的distutils命令,但不调用它。而且我可以扩展,但是安装会通过pip中断(尽

  • 我有一个自定义列表视图的应用程序,它有一个textview和一个imageview。当我点击图像视图时,背景颜色应该改变。我试图这样做,但是得到了。。。这是我的密码 CustomListViewAdapter。JAVA 任何建议都将不胜感激。谢谢