问题标签 [urlclassloader]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - 在运行时动态添加 jar 文件时出现 NoClassDefFoundError
更新:我认为问题可能是由于 TestFramework.jar 依赖于 JUnit 并且在它(TestFramework)加载时以某种方式找不到junit jar。仍然不确定解决方案,如果我是对的,我需要一种方法来指定 jar 的加载顺序。
首先是我正在做的一些背景:我正在尝试创建一个工具,该工具将允许用户指定一个 java 源文件,该文件是 JUnit TestCase 的扩展,并在名为 getTestData 的方法中包含测试数据。然后,该工具将编译 java 文件,将生成的类文件放在“classes”目录中,加载类并访问 getTestData 方法,生成表示测试数据的 XML 文件。
显然,通过允许用户指定源文件,我还必须确保在编译时该文件的所有依赖项都包含在类路径中。所以现在我已经硬编码了一个我试图用于测试目的的特定文件的依赖关系。当前正在编译用户文件,但加载生成的类会导致一些问题。同样很明显,要加载类,我需要确保它所依赖的所有文件都在我拥有的类路径上。不知何故,在加载类的过程中,它仍然找不到所需的类,并给了我一个 NoClassDefFoundError。
以下是我用来创建 URLClassLoader 的方法,该 URLClassLoader 包含“lib”目录中每个 jar 文件的 URL。请注意,加载器是一个类变量,因此它可用于我的所有方法,但仅在此方法中初始化。
这是实际定位已编译的类文件并加载它的代码。第一个参数是要在其中搜索的目录,第二个参数是用户想要为其生成 XML 文件的所有已编译类文件的列表。
其他需要注意的可能很重要的一点是,并非用户选择的源文件的所有依赖项都是 jar,有些是其他源文件,它们也被编译并放置在“类”目录中。“类”目录通过项目设置包含在运行时类路径中(我使用 Netbeans 来简化 GUI 创建)。由于我希望用户能够将 jar 动态添加到“lib”目录中,因此我没有在项目设置中指定 jar。
关于输出和我在这里遇到的问题是我在运行代码时在控制台中看到的:
XmlDataGenerator.java 第 299 行是读取的行IvrTest testCase = (IvrTest) Class.forName(fullClassName,true,loader).newInstance();
在这一点上,我不知所措,因为我已经尝试了我能想到的一切,例如:
- 将 junit.jar 添加到运行时类路径(在项目设置中)以确保此错误消失,它确实如此。这无助于解决问题,因为我想动态加载 jars。
- 仅指定 junit.jar 而不是尝试加载目录中的所有 jar。这仍然会导致与上述相同的失败。
- 从项目配置中删除“类”目录并使用相同的代码引入这些类。这可以引入已编译的源代码,但不能解决 jar 问题。
- 在 URL 中使用相对路径而不是绝对路径。这无济于事。
- 在尝试加载 jar 之前和之后添加额外的 System.out - 结果与我在创建 URLClassLoader 期间打印 URL 列表时相同,在我第一次创建它和尝试加载之后之间没有任何变化。
我唯一能想到的是,不知何故我试图使用的 URLClassLoader 没有被使用,但我不知道为什么会发生这种情况。任何帮助将不胜感激。谢谢你的时间。
java - URLClassLoader、“热交换”jar 文件和 ClassFormatError - 奇怪的行为
从头开始重写@ 5 月 25 日星期五,格林威治标准时间 16:00 左右
(现在代码更干净了,bug可以重现,问题更清楚了)
原始问题:我正在编写一个服务器应用程序,它需要通过网络接受来自客户端的文件并使用某些类处理它们,这些类是通过 URLClassLoader 从本地存储的 .jar 文件加载的。几乎一切正常,但是这些 jar 文件会不时地热交换(无需重新启动服务器应用程序)以应用修补程序,如果我们不幸同时更新 .jar 文件,则来自它的类是正在加载,ClassFormatError
被抛出,并带有关于“截断类”或“末尾多余字节”的注释。这是意料之中的,但是整个应用程序变得不稳定并且在那之后开始表现得很奇怪——这些ClassFormatError
异常一直在发生当我们尝试从更新的同一个 jar 再次加载类时,即使我们使用 URLClassLoader 的新实例并且它发生在不同的应用程序线程中。
该应用程序在 Debian Squeeze 6.0.3/Java 1.4.2 上运行和编译,迁移不在我的能力范围内。
这是一个模仿应用程序行为并粗略描述问题的简单代码:
1) 主应用程序和每个客户端线程的类:
2) JarLoader - 用于从 .jar 加载类的包装器,扩展了 Thread。这里我们加载一个实现某个接口a的类:
3) IJarPlugin - 可插入 .jar 的简单接口:
4)实际插件:
为了重现该错误,我们需要使用相同的类名编译几个不同的 .jar,它们的唯一区别是“这是第 N 个插件:”中的数字。然后启动主应用程序,然后将加载的名为“1.jar”的插件文件快速替换为其他.jar,然后返回,模仿热插拔。同样,ClassFormatError
在某些时候是可以预料的,但即使 jar 被完全复制(并且没有以任何方式损坏),它也会继续发生,有效地杀死任何试图加载该文件的客户端线程;摆脱这个循环的唯一方法是用另一个插件替换插件。看起来真的很奇怪。
实际原因:
一旦我进一步简化了我的代码并摆脱了clientThread
类,这一切都变得清晰起来,只需实例化并JarLoader
在. 当被抛出时,它不仅将堆栈跟踪打印出来,而且实际上使整个 JVM 崩溃(以代码 1 退出)。原因并不像现在看起来那么明显(至少不适合我):extends , not . 因此它通过并且JVM由于未捕获的异常/错误而退出,但是因为我产生了导致另一个产生的(客户端)线程出错的线程,只有那个线程崩溃了。我想这是因为 Linux 处理 Java 线程的方式,但我不确定。while
main
ClassFormatError
ClassFormatError
Error
Exception
catch(Exception E)
(临时)解决方案:
一旦未捕获的错误原因变得清晰,我试图在“clientThread”中捕获它。它有点工作(我删除了堆栈跟踪打印输出并打印了我自己的消息),但主要问题仍然存在:ClassFormatError
即使正确捕获,在我替换或删除有问题的 .jar 之前一直发生。所以我大胆猜测某种缓存可能是罪魁祸首,并通过将其添加到 clientThreadtry
块来强制 URLClassLoader 引用失效和垃圾收集:
令人惊讶的是,它似乎有效!现在错误只发生一次,然后文件类正常加载,因为它应该。但是由于我只是做了一个假设,但没有理解真正的原因,我仍然担心 - 它现在可以工作,但不能保证它以后会在更复杂的代码中工作。
那么,对Java有更深入了解的人能否告诉我真正的原因是什么,或者至少尝试给出一个方向?也许这是一些已知的错误,甚至是预期的行为,但它已经太复杂了,我自己无法理解——我还是个新手。我真的可以依靠强制GC吗?
java - URLClassLoader.addURL(URL) 是否尊重 META-INF/MANIFEST.MF
如果我有一个 jar,其中包含MANIFEST.MF
. 如果我将 jar 添加到 a URLClassLoader
,Class-Path
条目中的 jar 是否也添加到classloader
?我是否需要内省我想添加到的罐子classloader
以检测到这一点并调用addURL
它们中的每一个(递归地)?
java - Java JAR 保护
我编写了一个 Java 应用程序,并计划在线分发它。每个版本都将使用我制作的秘密序列号进行锁定。
我需要从反编译器等保护我的 jar 文件。这是我到目前为止所做的:
- 用户在表单中输入他的序列号
- 串行通过 php 脚本发送到我的开发服务器
- 该脚本生成一个新的 jar bin 文件,该文件以 AES 128 加密
- 我的“加载器”将 jar 文件作为字节下载并解密。
- 它调用 main 方法。
- 用户可以随心所欲地使用该应用程序
- 用户关闭应用
- 缓存被清除,一切都返回到第 1 步或之前。
我已经完成了步骤 1 到 3,但我需要知道是否可以制作一个自定义类加载器,从 HTTP 中获取字节,解密它们并调用 main 方法。由于文件是完全加密的(在 PHP 服务器上保存为 bin),我不能使用基本的类加载器。关于第 8 步,是否可以从计算机内存中卸载内容?
java - 带有锁定 jar 的 Java 类加载器困境
我正在玩 Java 中的 classLoaders 并注意到一件奇怪的事情。如果一个类加载器从一个 jar 加载一个类,即使你取消引用你的类加载器,这个 jar 也会被无限期锁定。
在下面的示例中,jar 包含一个名为 HelloWorld 的类。我所做的是尝试通过动态添加 jar 的 classLoader 加载 jar 中包含的类。如果设置skip
为true
不调用Class.forName
,则可以删除 jar,但如果不跳过,即使取消引用classLoader
( classLoader = null
),也无法删除 jar,直到 JVM 退出。
这是为什么?
PS:我使用的是 java 6,代码非常冗长,用于测试目的
java - 使用 JarOutputStream 创建的 jar 的 URLClassLoader 问题
URLClassLoader 类无法从使用下面列出的代码以编程方式创建的 jar 加载类,而当我使用jar cf %jarname% %sources%创建具有相同类的 jar 时,它工作正常。使用jar cf和JarOutputStream创建的 jar 之间是否有区别。
最好的问候, 凯沙夫
java - OneJar 和动态类加载
我们目前正在调查我们的应用程序中 OneJar 的使用(出于多种原因),但我们的应用程序使用了一些 customURLClassloader
来加载应用程序扩展。
当捆绑为“OneJar”Jar 时,我们会遇到ClassNotFound
异常。有问题的类驻留在捆绑的 Jar 中,我们只是依靠类加载器机制来解决父/子关系。
那是。我们有一个通用interface
的存储在捆绑的 Jar 中(应该在父类加载器上下文中)。扩展实现了这一点interface
(允许我们调用扩展)并依赖子类加载器使用父类加载器的资源查找功能的能力。
有没有人对此有任何经验或阐明我们如何解决它。
我会对其他类似的机制感兴趣(用于将我们的库 Jar 捆绑到单个 Jar 资源中,不需要使用将所有内容和 Jar 解压缩到单个文件中)
java - 在tomcat中重新加载类文件
我在运行时创建一个类文件。
我想用类加载器中的更新的类文件替换现有的类文件。
它类似于避免服务器重新启动和重新部署的热交换(例如 JRebel)。
我找到了用于上下文重新加载的 tomcat 的 context.xml 方法。但在生产环境中它不是很有用。
我们可以在运行时向 ClassLoader 注册类吗?请建议是否有任何替代方法可以在运行时重新加载类。
我正在使用以下代码来检索当前的类加载器。
下面是加载类方法的实现。
要重新加载课程,我正在使用以下代码。
我的类加载器的重载方法是
重新加载后,如果我创建 LoggingAspect 的新实例,它仍然会给我旧实例。请建议。
我仍然得到旧实例。
请建议为什么类加载器不加载修改后的类?
java - URLClassLoader : 如何设置 URL
假设在tomcat中,有两个应用:app1和app2,文件夹结构如下 tomcat6 -webapps -app1 -WEB-INF -lib -test1.jar -app2 -WEB-INF -lib -test2.jar 现在在test1中。 jar,它有一个类需要加载test2.jar中的类,如何实现?我知道在java中,它有可以加载远程类的URLClassLoader,但是如何设置URL?谢谢
java - URLClassLoader 找不到类
我想使用 URLClassLoader 从 jar 存档中加载特定目录中的类。
项目结构如下
该 jar 具有以下清单:
我目前所做的是遍历其中的所有文件/myClasses/
并尝试加载该特定类(它们都有相同的包),如下所示:
但是,即使这些文件显然存在,我总是会收到java.lang.ClassNotFoundException: de.myClasses.class1
错误消息。我究竟做错了什么?