- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
总体思路:我正在为 java 编写一个加载器,它允许动态重新加载类以允许更改实现,而无需重新启动整个程序以保持主应用程序运行并最大限度地减少停机时间。每个外部代码段都按“模块”分组,每个模块都有一个带有“onEnable、postEnable、onDisable”入口/导出点的主类,并且可以包含任意数量的类。要加载模块,需要指定包含入口点的类,然后加载。我将在下面将它们称为“模块”和“附加类”,“模块”是通过实现“公共(public)接口(interface)模块”包含上述功能的类,“附加类”是指模块将使用的所有内容运行时但本身并不是一个模块(例如,我们有一个名为“Car Implements Module”的模块,该模块需要一个“Engine”类才能运行 ->“Car”是模块,“Engine”是一个附加类” )
我最初加载模块的代码(名称是包含完整类名(包括路径)的字符串,稍后给出示例):
Class<?> clazz = mainLoader.loadClass(name);
Module module = (Module) clazz.newInstance();
addLoadedModule(module);
enableLoadedModule(module);
下面是我如何在模块已经存在时重新加载模块,以便我可以覆盖实现。 “m”是应该重新加载的模块的当前实现的实例。
boolean differs = false;
Class<?> newClass = null;
try (URLClassLoader cl = new URLClassLoader(urls, mainLoader.getParent()))
{
// Try to load the class and check if it differs from the already known one
newClass = cl.loadClass(m.getClass().getName());
differs = m.getClass() != newClass;
}
catch (IOException | ClassNotFoundException e)
{
// Class couldn't be found, abort.
e.printStackTrace();
return;
}
if (!differs)
{
// New class == old class -> no need to reload it
return;
}
Module module = null;
try
{
// Try to instantiate the class
module = (Module) newClass.newInstance();
}
catch (InstantiationException | IllegalAccessException e)
{
// Can't instantiate, abort
e.printStackTrace();
return;
}
// Check versions, only reload if the new implementation's version differs from the current one. Version is a custom annotation, don't worry about that; the version check works fine
Version oldVersion = m.getClass().getAnnotation(Version.class);
Version newVersion = module.getClass().getAnnotation(Version.class);
if (oldVersion.equals(newVersion))
{
return;
}
// And if everything went well, disable and remove the old module from the list, then add and enable the new module.
disableModule(m);
modules.remove(m);
modules.put(module, false);
enableLoadedModule(module);
这是mainLoader,urls是一个URL[],指向包含要加载的外部类的位置:
mainLoader = new URLClassLoader(urls, this.getClass().getClassLoader());
当我尝试重新加载需要多个类的实现时,问题就出现了:
A 类模块需要 B 类才能运行。这就是当我尝试动态加载然后重新加载类 A 时发生的情况:
加载 A -> “当然,但我需要 B。” -> 自动加载 B -> “好了,A 现在工作正常了。”重新加载 A -> “当然,但我需要 B。” -> 由于找不到 B 而崩溃
两个类都位于完全相同的文件夹中,结构如下:
我使用 load("com.foo.bar.A") 调用该函数,该函数在第一次尝试加载它时有效,但在尝试如上所述重新加载它时失败。
当尝试加载“单类模块”时它工作正常,当模块依赖于额外的外部类时就会出现问题。我尝试使用不同的类加载器在重新加载过程中用作 URLClassLoader 的父级,这些类加载器是 sysloader、Module.class.getClassLoader()、mainLoader(使用该类加载器,它永远不会找到新的类定义,因为它已经知道它,因此甚至不会再次尝试从驱动器加载它)和 mainLoader.getParent()、旧模块的类加载器以及模块类加载器的父级。
我可能只是在监督一些明显的事情,但我不明白为什么它第一次会设法加载“额外”类,但当我重新加载基类时失败......
如果您需要任何调试输出或确切的错误,请告诉我,我用解释什么作用的注释替换了调试输出,因此我得到了有关何时发生的情况的相当详细的日志,但我似乎没有必要,因为它很好地完成了整个“检查然后加载”过程,但在尝试启用模块时它崩溃了。模块的“onEnable”方法需要额外的类 B,这就是它失败的地方。正如我所说,如果您需要实现类 A 和 B、模块、任何其他代码或调试输出,请告诉我,我将根据要求添加它们。
最佳答案
您可以尝试以下几种方法:
关于java - URLClassLoader 在同一文件夹中找到 X 但找不到 Y,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43089597/
我想使用 URLClassLoader 从 jar 存档中加载特定目录中的类。 项目结构如下 / application.jar /lib/ mysql.jar log4j.jar .
我在一个目录中有多个来自不同包的已编译 Java 类文件,如下所示。 C:/classes/package/A.class C:/classes/package/B.class C:/classes/
我正在使用 URLClassLoader 从外部 jar 文件加载类,由此加载的类可能已经存在于我的 Web 应用程序类加载器中,假设 URL 类加载器已加载版本 1 的类 A 和 Web 应用程序使
我想在目录 F:/badge-dao/bin/com/badge/dao/impl/ 中加载一个名为 BadgeDaoImpl 的文件。我正在编写和测试以下代码。 如果我更改目录或类名,它会抛出异常。
我编写了一个程序来管理以 jar 形式提供的插件。 我使用 URLClassLoader 加载插件类,它按预期工作。我添加了一些存储在插件 jar 中的资源(XML 文件)。 如果我调用不使用资源的方
在我之前的问题中,我询问了如何加载远程 jar 文件。我当前的代码是这样的: //f is the path to the jar URLClassLoader loader = new URLCla
我有一个非常奇怪的问题。 我正在使用 URLClassLoader 从目录中动态导入文件。如果我使用文字字符串,代码可以正常工作,如果我将变量用于文字字符串,代码也可以正常工作,但这不是我需要的。 p
我有相当简单的场景: 我的应用程序具有包含我的应用程序逻辑的核心 jar 文件。这个核心 jar 应该在运行时动态监视文件夹,当插件 jar 被放到那里时,它应该加载它并准备好使用它。可能有很多插件j
所以我正在制作一个服务器,很像 IRC,只是为了了解更多信息,这就是我的问题。 我有每个人都可以根据自己的权限调用的命令,并且每个“命令”都有自己的类,所有类都位于一个目录中。我将所有类加载到 Has
我在互联网上浏览了很多 URLClassLoader 内存泄漏解决方案,但我还没有找到任何完全工作的代码和精确的解决方案。我找到的最接近的解决方案是 this 任何功能齐全的代码或链接,它使用 Wea
我有一个相当复杂的 Java 软件,它必须动态加载一个类、创建一个对象并调用其方法之一。事实证明,在某些情况下,如果加载的类引用了另一个类,则会引发 NoClassDefFoundError(由 Cl
这是我的代码: File folder = /* the folder with a.txt file */ final URL[] urls = new URL[] { folder.toURI
在开发一个 ant 任务以使用注释为项目自动生成一些 gui 代码时,因为我更喜欢声明性方法,所以我使用 java.net.URLClassLoader动态添加类到我的类路径。 当扫描类的类级别注释时
我正在尝试编写一段在运行时动态加载类的代码 public class URLDynClassLoader { public URLDynClassLoader(){ try{
我有一个 java 项目,它使用 URLClassLoader 在运行时从另一个 jar 文件加载类,就像插件系统一样。让我给你一个简化版本的问题:假设在我的 main 方法中,我将创建 ClassL
所以我知道如何使用 URLClassLoader,并且我知道它的作用,我想知道它到底是如何做到的。 基本上我在问:这是直播吗?或者它会临时下载并在本地读取类吗? 因此,如果您不断地从使用 URLCla
我有以下代码片段 URL url = new File("c:/work/projects/jars/").toURI().toURL(); URL[] urls = new URL[]{url};
在哪种情况下,可以使用 URLClassLoader 从指定路径中的特定 jar 加载类? 例如。 URL url = new URL("file:///path/to/customClasses.j
假设我正在创建一些加载外部目录中所有 jar 的东西,以动态向应用程序添加可选功能。 我迭代该目录中的所有 jar 并确认它们是 jar 并将它们作为 URL 加载到 URLCLassLoader 中
我正在尝试编写一个可以从命令行传递任意文件的 Java 1.7 应用程序。该文件将被添加到类加载器中,以便可以将其用作资源。 将文件添加到 URLClassLoader 似乎可行,但是添加到 Clas
我是一名优秀的程序员,十分优秀!