我希望在运行时将类从模块(.jmod)文件加载到应用程序内存中。
我知道,我们可以使用:-)轻松地从(.jar)文件加载类。
ClassLoader loader = URLClassLoader.newInstance(new URL[]{
jarFile.toURL()
});总代码片段可以在src omega.deassembler.JarLoader类中的这个-回购中找到。
但问题是URLClassLoader无法读取模块(.jmod)。
那么,是否还有其他内部类或库可以从模块(.jmod)文件中加载类。
实际上,我正在创建一个IDE,这个-repo是其中的一部分,用于加载内容辅助提示。
之前,我使用javap命令来解压缩和加载提示(参见关于github的总干事)。
但是这个技巧消耗了很多时间,所以我又写了一遍!
谢谢。
发布于 2021-04-08 15:31:06
这不是答案,而是一种使URLClassLoader在必须读取模块时可用的方法。
早期的URLClassLoader在试图读取模块文件(.jmod)时抛出此异常。
当省略模块-info时
Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/javafx/event/DirectEvent (wrong name: classes/com/sun/javafx/event/DirectEvent)
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1010)
etc当包括时,元信息
Exception in thread "main" java.lang.NoClassDefFoundError: classes/module-info is not a class because access_flag ACC_MODULE is set这意味着无法识别jmod文件中的目录系统。
因此,正如我们所知道的,一个简单的jar文件只包含类和资源(不包括meta)。
在模块文件(.jmod)中,所有类都放在类文件夹中,所有资源都放在资源文件夹中。
因此,我们可以使用模块文件中的类和资源的内容创建一个临时jar文件,称为“模块化-jar.jar”,
然后使用标准的URLClassLoader,我们可以将它加载到类路径
然后可以立即删除文件。
,至少在我的例子中,会起作用。
这是代码片段
public static synchronized JarLoader prepareModule(String modulePath){
try{
ZipFile moduleFile = new ZipFile(modulePath);
ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream("readable-module-data.jar"));
for(Enumeration enums = moduleFile.entries(); enums.hasMoreElements();){
ZipEntry entry = (ZipEntry)enums.nextElement();
String name = entry.getName();
if((name.startsWith("classes") && !name.contains("module-info")) || name.startsWith("resources")){
zipOutputStream.putNextEntry(new ZipEntry(name.substring(name.indexOf('/') + 1)));
InputStream in = moduleFile.getInputStream(entry);
while(in.available() > 0)
zipOutputStream.write(in.read());
zipOutputStream.flush();
}
}
zipOutputStream.close();
}
catch(Exception e){
e.printStackTrace();
}
return new JarLoader("readable-module-data.jar");
}https://stackoverflow.com/questions/66970647
复制相似问题