繁体   English   中英

从外部JAR读取图像

[英]Reading images from external JAR

我有一个简单的插件系统,可将外部JAR插件加载到主应用程序中。 我正在使用Mountainblade Modular这样做。 不确定他们是如何“幕后”做的,但这可能是标准的东西。

这很好,我从外部jar实例化类,并且一切正常。 除了某些插件附带图标/图像。 我不确定如何从该外部JAR加载/引用图像(该代码位于该外部JAR中,因为它是在主JAR的上下文中运行的)

我应该如何处理?

这个问题并不像看起来那样简单。

从外部jar加载类时,它们会“加载”到JVM中。 “加载”到JVM是指JVM负责它们在内存中的存储。 通常这样做是这样的:

ClassLoader myClassLoader = new MyClassLoader(jarFileContent);
Class myExtClass = myClassLoader.loadClass(myClassName);

使用以下命令可以轻松访问类路径jar中的资源

InputStream resourceStream = myClass.getResourceAsStream("/myFile.txt");

您可以这样做,因为这些罐子位于类路径中,这意味着它们的位置是已知的。 这些文件未存储在内存中。 访问资源后,JVM可以在类路径jar中搜索它(例如,在文件系统上)。

但是对于外部罐子,情况则完全不同:罐子来自无处,一旦被加工和遗忘。 JVM不会从内存中加载资源。 为了访问这些文件,您必须手动组织它们的存储。 我已经做了一次,所以我可以共享代码。 它将帮助您理解基本概念(但可能对您的特定库没有帮助)。

// Method from custom UrlClassLoader class. 
// jarContent here is byte array of loaded jar file.
// important notes:
// resources can be accesed only with this custom class loader
// resource content is provided with the help of custom URLStreamHandler 
@Override
protected URL findResource(String name) {       
    JarInputStream jarInputStream;
    try {
        jarInputStream = new JarInputStream(new ByteArrayInputStream(jarContent));
        JarEntry jarEntry;
        while (true) {
            jarEntry = jarInputStream.getNextJarEntry();
            if (jarEntry == null) {
                break;
            }
            if (name.equals(jarEntry.getName())) {
                final byte[] bytes = IOUtils.toByteArray(jarInputStream);
                return new URL(null, "in-memory-bytes", new URLStreamHandler() {
                    @Override
                    protected URLConnection openConnection(URL u) throws IOException {
                        return new URLConnection(u) {
                            @Override
                            public void connect() throws IOException {
                                // nothing to do here
                            }
                            @Override
                            public InputStream getInputStream() throws IOException {
                                return new ByteArrayInputStream(bytes);
                            }
                        };
                    }
                });
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM