Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:自动定制类加载器_Java_Classloader_Urlclassloader - Fatal编程技术网

Java:自动定制类加载器

Java:自动定制类加载器,java,classloader,urlclassloader,Java,Classloader,Urlclassloader,我的应用程序使用标准的小部件工具包SWT作为它的GUI。我的问题是32位SWT库不能在64位JVM上工作。但我不想让人们在获得软件时选择正确的体系结构。因此,我想捆绑32位和64位库,并在运行时自动检测体系结构。我发现我可以获得正确的JVM架构,如下所示: if (System.getProperty("os.arch").contains("64")) { // ... } 现在剩下的就是装罐子了。但问题是,我发现的所有示例都要求在使用该类之前手动加载该类 Class.forName

我的应用程序使用标准的小部件工具包SWT作为它的GUI。我的问题是32位SWT库不能在64位JVM上工作。但我不想让人们在获得软件时选择正确的体系结构。因此,我想捆绑32位和64位库,并在运行时自动检测体系结构。我发现我可以获得正确的JVM架构,如下所示:

if (System.getProperty("os.arch").contains("64")) {
    // ...
}
现在剩下的就是装罐子了。但问题是,我发现的所有示例都要求在使用该类之前手动加载该类

Class.forName("MyClass", false, myClassLoader);
所以我的问题是,是否可以注册我的类加载器,这样我就不必预先加载类了

更新:我创建了自己的URLClassLoader子类,并使用命令行参数-Djava.system.class.loader将其设置为默认类加载器;但我得到了这个错误:

Error occurred during initialization of VM
java.lang.Error: java.lang.NoSuchMethodException: com.program.LibraryLoader.<init>(java.lang.ClassLoader)
    at java.lang.ClassLoader.initSystemClassLoader(Unknown Source)
    at java.lang.ClassLoader.getSystemClassLoader(Unknown Source)

但是在使用addPath文件lib/jars/swt.jar添加jar之后,它只会产生一个NoClassDefFoundError。是的,我仔细检查了文件是否存在。

您可以尝试通过java.system.class.loader属性注入自定义类加载器。请参阅ClassLoadergetSystemClassLoader。然而,我建议使用OSGi,让框架完成复杂的工作

您可以尝试通过java.system.class.loader属性注入自定义类加载器,请参见ClassLoadergetSystemClassLoader。然而,我建议使用OSGi,让框架完成复杂的工作

作为自定义类加载器构造函数的一部分,使用适当的信息调用definePackage,URL指向所需的jar文件

这个示例显示,当我尝试从swing实例化一个类时,会调用自定义类加载器,因为我将类加载器定义为该包的加载器

import java.net.URL;

public class junk extends ClassLoader {

  byte[] dummy = new byte[0];

  public static void main(String[] args) throws Exception {
    new junk();

    new javax.swing.JPanel();

  }

  public junk() throws Exception {
    definePackage("javax.swing","","","","","","",new URL("file://junk.class"));
  }

  public Class<?> findClass(String s) throws java.lang.ClassNotFoundException{
    Class<?> retVal = super.findClass(s);

    System.out.println("delegated responsibility for "+s+" to superclass");

    return retVal;
  }

  public Package getPackage(String s) {
    Package retVal = super.getPackage(s);

    System.out.println("delegated responsibility for "+s+" to superclass");

    return retVal;
  }

}
结果:


将javax.swing委托给超类的职责作为自定义类加载器构造函数的一部分,使用适当的信息调用definePackage,URL指向所需的jar文件

这个示例显示,当我尝试从swing实例化一个类时,会调用自定义类加载器,因为我将类加载器定义为该包的加载器

import java.net.URL;

public class junk extends ClassLoader {

  byte[] dummy = new byte[0];

  public static void main(String[] args) throws Exception {
    new junk();

    new javax.swing.JPanel();

  }

  public junk() throws Exception {
    definePackage("javax.swing","","","","","","",new URL("file://junk.class"));
  }

  public Class<?> findClass(String s) throws java.lang.ClassNotFoundException{
    Class<?> retVal = super.findClass(s);

    System.out.println("delegated responsibility for "+s+" to superclass");

    return retVal;
  }

  public Package getPackage(String s) {
    Package retVal = super.getPackage(s);

    System.out.println("delegated responsibility for "+s+" to superclass");

    return retVal;
  }

}
结果:


将javax.swing委托给超类的责任

如果我将其注入java.system.class.loader,其他类是否仍使用默认类加载器加载?您必须确保您自己的类加载器将任何非swt类委托给其父类。好的,我在此处找到了一些详细信息:。如何在程序启动之前设置属性java.system.class.loader?可以通过添加以下命令行参数来设置系统属性:-Djava.system.class.loader=com.mycompany.MyClassLoader。请注意,此参数必须设置在您自己的程序参数(如果有)之前,但在Xmx/Xms之后。我可以在清单中设置它吗?如果是这样,怎么做?如果我用java.system.class.loader注入它,其他类是否仍然使用默认类加载器加载?您必须确保您自己的类加载器为任何非swt类委托给其父类。好的,我在这里找到了更多信息:。如何在程序启动之前设置属性java.system.class.loader?可以通过添加以下命令行参数来设置系统属性:-Djava.system.class.loader=com.mycompany.MyClassLoader。请注意,此参数必须设置在您自己的程序参数(如果有)之前,但在Xmx/Xms之后。我可以在清单中设置它吗?如果是,怎么做?