首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在运行时从模块(.jmod)文件加载类?

如何在运行时从模块(.jmod)文件加载类?
EN

Stack Overflow用户
提问于 2021-04-06 14:29:15
回答 1查看 430关注 0票数 1

我希望在运行时将类从模块(.jmod)文件加载到应用程序内存中。

我知道,我们可以使用:-)轻松地从(.jar)文件加载类。

代码语言:javascript
复制
ClassLoader loader = URLClassLoader.newInstance(new URL[]{
                jarFile.toURL()
            });

总代码片段可以在src omega.deassembler.JarLoader类中的这个-回购中找到。

但问题是URLClassLoader无法读取模块(.jmod)。

那么,是否还有其他内部类或库可以从模块(.jmod)文件中加载类。

实际上,我正在创建一个IDE,这个-repo是其中的一部分,用于加载内容辅助提示。

之前,我使用javap命令来解压缩和加载提示(参见关于github的总干事)。

但是这个技巧消耗了很多时间,所以我又写了一遍!

谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-04-08 15:31:06

这不是答案,而是一种使URLClassLoader在必须读取模块时可用的方法。

早期的URLClassLoader在试图读取模块文件(.jmod)时抛出此异常。

省略模块-info时

代码语言:javascript
复制
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

包括时,元信息

代码语言:javascript
复制
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,我们可以将它加载到类路径

然后可以立即删除文件。

,至少在我的例子中,会起作用。

这是代码片段

代码语言:javascript
复制
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");
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66970647

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档