【发布时间】:2014-04-16 22:32:50
【问题描述】:
我编写了一个应用程序来管理几个以 jar 形式提供的插件。我使用 URLClassLoader 加载插件类,它按预期工作。
但是现在我正在编写一个插件来加载一些存储在 jar 中的资源。如果我将此插件作为独立应用程序启动,一切正常,但如果我从我的应用程序内部启动它,当我尝试打开资源 InputStream 时,我会得到一个 NullPointerException。
我这样打开流:
this.getClass().getResourceAsStream("/templates/template.html");
我的 Eclipse 项目结构如下:
src
|
+ My source files
resources
|
+ templates
|
+ template.html
以下加载我的插件:
private List<Class<?>> loadClasses(final File[] jars) {
List<Class<?>> classes = new ArrayList<Class<?>>();
URL[] urls = getJarURLs(jars);
URLClassLoader loader = new URLClassLoader(urls);
for (File jar : jars) {
JarFile jarFile = null;
try {
jarFile = new JarFile(jar);
} catch (IOException e) {
// Skip this jar if it can not be opened
continue;
}
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
if (isClassFile(entry.getName())) {
String className = entry.getName().replace("/", ".").replace(".class", "");
Class<?> cls = null;
try {
cls = loader.loadClass(className);
} catch (ClassNotFoundException e) {
// Skip this jar if a class inside it can not be loaded
continue;
}
classes.add(cls);
}
}
try {
jarFile.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
loader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return classes;
}
/**
* Checks if a path points to a class file or not.
*
* @param path the filename to check
* @return {@code true} if the path points to a class file or {@code false}
* if not
*/
private boolean isClassFile(final String path) {
return path.toLowerCase().endsWith(".class") && !path.toLowerCase().contains("package-info");
}
然后我使用 newInstance() 从这些类中创建实例。
我认为插件 jar 的根路径与应用程序的根路径不同,或者没有加载 jar 文件的所有内容或两者兼而有之......
有人可以帮我吗?
【问题讨论】:
-
this.getClass().getResource("/templates/template.html);在尝试访问 jar 中的内容时对我来说很好。