(JAVA) 类加载器和库的使用
(JAVA) ClassLoader and use of libraries
美好的一天,
我想编写一个模块化程序并在每个模块中使用插件作为库。
通过 URLClassLoader 我已经完成了大部分。一切正常。
但问题是图书馆的使用。
当我想使用插件中的方法时,出现错误。
这是它的工作原理:
我的 directory/ModuleLoader.jar 加载 directory/ModuleLoader/Module.jar 文件。
一切正常。问题:Module.jar 找不到 ../ModuleLoader.jar 作为依赖项(因此当我扩展 class 时它无法启动)...
private static final ConcurrentMap<String, ModuleDescription> cache = Maps.newConcurrentMap();
public void loadModules() {
for (File file : Objects.requireNonNull(Main.getInstance().getDataFolder().listFiles())) {
if (!file.getName().substring(file.getName().lastIndexOf(".")).equalsIgnoreCase(".jar")) {
return;
}
registerModule(file);
URLClassLoader loader = null;
try {
loader = new URLClassLoader(new URL[] { file.toURI().toURL() });
Class<?> jarClass = loader.loadClass(cache.get(file.getName()).main);
Method method = jarClass.getMethod("initialise");
Object instance = jarClass.newInstance();
method.invoke(instance);
} catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException | MalformedURLException e) {
e.printStackTrace();
} finally {
if (loader != null) {
try {
loader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
public void stopModules() {
for (String module : cache.keySet()) {
File file = new File(Main.getInstance().getDataFolder() + "/" + module);
URLClassLoader loader = null;
try {
loader = new URLClassLoader(new URL[] { file.toURI().toURL() });
Class<?> jarClass = loader.loadClass(cache.get(file.getName()).main);
Method method = jarClass.getMethod("shutdown");
Object instance = jarClass.newInstance();
method.invoke(instance);
} catch (MalformedURLException | ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException e) {
e.printStackTrace();
} finally {
if (loader != null) {
try {
loader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
public void registerModule(File file) {
JarFile jarFile = null;
InputStream inputStream = null;
try {
jarFile = new JarFile(file);
JarEntry jarEntry = jarFile.getJarEntry("module.yml");
if (jarEntry == null) {
System.out.println("The file \"" + file.getName() + "\" is missing the \"module.yml\"!");
return;
}
inputStream = jarFile.getInputStream(jarEntry);
Map<String, Map<String, String>> values = new Yaml().load(inputStream);
ModuleDescription description = new ModuleDescription();
if (values.containsKey("name")) {
description.name = "" + values.get("name");
System.out.println("name: " + description.name);
}
if (values.containsKey("main")) {
description.main = "" + values.get("main");
System.out.println("main: " + description.main);
}
if (description.name == null || description.main == null) {
System.out.println("The \"module.yml\" is missing needed information's!");
return;
}
if (values.containsKey("version")) {
description.version = "" + values.get("version");
}
if (values.containsKey("author")) {
description.author = "" + values.get("author");
}
if (values.containsKey("description")) {
description.description = "" + values.get("description");
}
cache.put(file.getName(), description);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (jarFile != null) {
try {
jarFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
我发现问题所在:
我尝试使用所述模块中的 ClassLoader 加载我的模块。
但是要将 ModuleLoader 作为依赖项,我还必须使用 ModuleLoader 中的 ClassLoader....
美好的一天, 我想编写一个模块化程序并在每个模块中使用插件作为库。 通过 URLClassLoader 我已经完成了大部分。一切正常。 但问题是图书馆的使用。 当我想使用插件中的方法时,出现错误。
这是它的工作原理: 我的 directory/ModuleLoader.jar 加载 directory/ModuleLoader/Module.jar 文件。 一切正常。问题:Module.jar 找不到 ../ModuleLoader.jar 作为依赖项(因此当我扩展 class 时它无法启动)...
private static final ConcurrentMap<String, ModuleDescription> cache = Maps.newConcurrentMap();
public void loadModules() {
for (File file : Objects.requireNonNull(Main.getInstance().getDataFolder().listFiles())) {
if (!file.getName().substring(file.getName().lastIndexOf(".")).equalsIgnoreCase(".jar")) {
return;
}
registerModule(file);
URLClassLoader loader = null;
try {
loader = new URLClassLoader(new URL[] { file.toURI().toURL() });
Class<?> jarClass = loader.loadClass(cache.get(file.getName()).main);
Method method = jarClass.getMethod("initialise");
Object instance = jarClass.newInstance();
method.invoke(instance);
} catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException | MalformedURLException e) {
e.printStackTrace();
} finally {
if (loader != null) {
try {
loader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
public void stopModules() {
for (String module : cache.keySet()) {
File file = new File(Main.getInstance().getDataFolder() + "/" + module);
URLClassLoader loader = null;
try {
loader = new URLClassLoader(new URL[] { file.toURI().toURL() });
Class<?> jarClass = loader.loadClass(cache.get(file.getName()).main);
Method method = jarClass.getMethod("shutdown");
Object instance = jarClass.newInstance();
method.invoke(instance);
} catch (MalformedURLException | ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException e) {
e.printStackTrace();
} finally {
if (loader != null) {
try {
loader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
public void registerModule(File file) {
JarFile jarFile = null;
InputStream inputStream = null;
try {
jarFile = new JarFile(file);
JarEntry jarEntry = jarFile.getJarEntry("module.yml");
if (jarEntry == null) {
System.out.println("The file \"" + file.getName() + "\" is missing the \"module.yml\"!");
return;
}
inputStream = jarFile.getInputStream(jarEntry);
Map<String, Map<String, String>> values = new Yaml().load(inputStream);
ModuleDescription description = new ModuleDescription();
if (values.containsKey("name")) {
description.name = "" + values.get("name");
System.out.println("name: " + description.name);
}
if (values.containsKey("main")) {
description.main = "" + values.get("main");
System.out.println("main: " + description.main);
}
if (description.name == null || description.main == null) {
System.out.println("The \"module.yml\" is missing needed information's!");
return;
}
if (values.containsKey("version")) {
description.version = "" + values.get("version");
}
if (values.containsKey("author")) {
description.author = "" + values.get("author");
}
if (values.containsKey("description")) {
description.description = "" + values.get("description");
}
cache.put(file.getName(), description);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (jarFile != null) {
try {
jarFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
我发现问题所在: 我尝试使用所述模块中的 ClassLoader 加载我的模块。 但是要将 ModuleLoader 作为依赖项,我还必须使用 ModuleLoader 中的 ClassLoader....