为什么在Java中这么做呢?如果您想拥有任何类型的模块系统,您需要能够动态加载jar.我被告知有一种方法可以通过编写自己的方式来完成它ClassLoader,但这对于应该(至少在我看来)像调用一个以jar文件作为参数的方法一样容易的事情来做很多工作.
这样做的简单代码的任何建议?
瑞安DELUCCHI问这里的评论#3 汤姆Hawtin的回答是:
为什么Class.newInstance()"邪恶"?
这是为了响应代码示例:
// Avoid Class.newInstance, for it is evil.
Constructor<? extends Runnable> ctor = runClass.getConstructor();
Runnable doRun = ctor.newInstance();
Run Code Online (Sandbox Code Playgroud)
那么,为什么它是邪恶的?
我需要为应用程序的某些部分添加插件功能到现有应用程序.我希望能够在运行时添加一个jar,应用程序应该能够从jar加载一个类而无需重新启动应用程序.到现在为止还挺好.我使用URLClassLoader在线发现了一些样本,它工作正常.
我还希望能够在jar的更新版本可用时重新加载同一个类.我再次找到了一些示例和实现这一点的关键,据我所知,我需要为每个新加载使用一个新的类加载器实例.
我写了一些示例代码但是遇到了NullPointerException.首先让我告诉你们代码:
package test.misc;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import plugin.misc.IPlugin;
public class TestJarLoading {
public static void main(String[] args) {
IPlugin plugin = null;
while(true) {
try {
File file = new File("C:\\plugins\\test.jar");
String classToLoad = "jartest.TestPlugin";
URL jarUrl = new URL("jar", "","file:" + file.getAbsolutePath()+"!/");
URLClassLoader cl = new URLClassLoader(new URL[] {jarUrl}, TestJarLoading.class.getClassLoader());
Class loadedClass = cl.loadClass(classToLoad);
plugin = (IPlugin) loadedClass.newInstance();
plugin.doProc();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
Thread.sleep(30000);
} catch (InterruptedException …Run Code Online (Sandbox Code Playgroud) 这是发布在以下问题的延续:如何在运行时加载jar文件
我不确定如何继续方法调用级别.根据我的理解,从clazz对象,我将使用getMethod或getDeclaredMethod来获取一个Method对象,我将从该对象调用invoke.当然,调用需要一个实例.这会是示例代码中所谓的doRun吗?
我是否需要执行doRun.run()方法调用,即使我想执行一个不同于main的方法(假设它是在运行调用调用的doRun对象上的主要方法)?
为了进一步澄清原帖,我问:doRun.run()是否启动了一个新线程来执行clazz类型的类对象的实例?
感谢您帮我解决这个问题.
我确实看过"how-should-i-load-jars-dynamic-at-runtime"(抱歉,只允许一个超链接),但这看起来违反了我引用的第一篇文章中的Class.newInstance邪恶警告.
当我第一次使用apache守护进程为windows开发java服务时,我使用了JVM我非常喜欢的模式.您指定您的类并启动\ stop(静态)方法.但是对于Linux,Jsvc看起来并没有相同的选择.我真的很想知道为什么?!
无论如何如果我要使用Linux的init系统,我试图找到一种类似的方法来完成相同的行为,无论如何都要启动应用程序,但要停止它,我将不得不在类中调用一个方法.
我的问题是,在启动jar之后,我如何使用jvm库或其他任何东西来调用我的应用程序中的方法(它会尝试优雅地停止我的应用程序).
另一个问题,如果一个应用程序启动并且该应用程序具有静态方法,如果我使用java命令行在一个main方法中运行一个方法,如果那个应用程序类,那么main方法,这static将调用我在类中的另一个静态方法想要发出终止信号的信号,是否可以通过相同的方式呼叫JVM?
如何在运行时从android应用程序的assets文件夹加载jar文件.从资产文件夹加载是我的要求.有没有办法做到这一点.请帮忙 ..
有没有办法在运行时更新系统类加载器?在我动态加载jar文件之后,有什么办法可以将从这个jar加载的类/包添加到我的系统类加载器中吗?
我试图这样做的原因是,虽然我通过在我自己的代码中传递我新创建的ClassLoader取得了一些成功,但我遇到了第三方库(apache-WSIF)的问题似乎正在使用传递的ClassLoader.
我正在为我的项目的更新功能,它的工作的伟大,直到我希望它重新启动,基本上我下载新的文件,并与旧的替换它,然后我想再次运行它,现在由于某种原因,不会运行,我没有任何错误...
这是完整的更新类:http: //dl.dropbox.com/u/38414202/Update.txt
这是我用来运行.jar文件的方法:
String currDir = new File("(CoN).jar").getAbsolutePath();
Process runManager = Runtime.getRuntime().exec("java -jar " + currDir);
Run Code Online (Sandbox Code Playgroud) 简介: 从正在运行的Java程序加载jar会NoClassDefFoundError导致由ClassNotFoundException类间依赖性(例如import语句)引起的.我怎么能绕过它呢?
问题更详细:
我试图以编程方式加载一个jar文件 - 让我们称之为"服务器" - 通过我自己的Java程序进入Java虚拟机 - 让我们称之为"ServerAPI" - 并使用扩展和一些其他技巧来修改行为和服务器交互.ServerAPI依赖于Server,但如果Server不存在,ServerAPI仍然必须能够从网站运行和下载Server.
为了避免因ServerAPI加载而导致的错误而不满足Server的依赖性,我制作了一个启动器 - 让我们称之为"Launcher" - 这是为了下载Server并根据需要设置ServerAPI,然后加载Server和ServerAPI,然后运行ServerAPI.
但是,当我尝试从Launcher加载jar时,我会收到错误,因为ClassLoaders无法解析文件中其加载的类所依赖的其他类.简而言之,如果我尝试加载Class A,它会在A导入时抛出错误,B因为我还没有加载B.但是,如果B还要导入A,我会陷入困境,因为我无法弄清楚如何一次加载两个类或如何在没有JVM运行其验证的情况下加载类.
为什么所有的限制都让我遇到了这个问题:
我试图修改并添加到Server的行为,但由于复杂的法律原因,我无法直接修改程序,所以我创建了依赖的ServerAPI,可以从外部调整Server的行为.
但是,出于更复杂的法律原因,Server和ServerAPI不能简单地一起下载.Launcher(见上文)必须与ServerAPI一起下载,然后Launcher需要下载Server.最后,可以使用Server作为依赖项运行ServerAPI.这就是为什么这个问题如此复杂的原因.
此问题也适用于项目的后续部分,该部分将涉及基于插件的API接口,该接口需要能够在运行时从jar文件加载和卸载插件.
关于这个问题的研究我已经做过:
我已经阅读并且未能得到以下方面的帮助:
和更多.没有任何效果.
//编辑: 我到目前为止所做的尝试:
我一直在使用URLClassLoaders加载使用的jar试图JarEntries从JarFile类似这样的问题.我既使用和调用试过这种URLClassLoader的loadClass(String)方法,并通过使扩展一个类URLClassLoader,这样我可以利用loadClass(String, boolean resolve),试图迫使 …
java ×9
jar ×5
classloader ×4
runtime ×4
android ×1
class ×1
constructor ×1
dependencies ×1
dynamic ×1
init ×1
jvm ×1
ubuntu-12.04 ×1