[英]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.