Java:自动定制类加载器
我的应用程序使用标准的小部件工具包SWT作为它的GUI。我的问题是32位SWT库不能在64位JVM上工作。但我不想让人们在获得软件时选择正确的体系结构。因此,我想捆绑32位和64位库,并在运行时自动检测体系结构。我发现我可以获得正确的JVM架构,如下所示: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
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之后。我可以在清单中设置它吗?如果是,怎么做?