首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从jar文件动态运行java类

如何从jar文件动态运行java类
EN

Stack Overflow用户
提问于 2015-03-26 13:26:44
回答 2查看 2.3K关注 0票数 2

我正在处理一个java项目,它需要第三方java程序作为服务器运行。

通常情况下,我会:

代码语言:javascript
复制
java -cp jarfile1.jar:jarfile2.jar className arg1 arg2

然后我会运行我的java代码。这样就行了。

我想知道是否有任何方法,包括在我的项目中需要的两个.jars,直接从我的代码运行类,而不是手动启动它。

正如我在一些例子中看到的那样,我试图使用URLClassLoader,但要么我做错了,要么没有涵盖这个特定的用例。

代码语言:javascript
复制
URLClassLoader classLoader = URLClassLoader.newInstance(new URL[]{new URL("file:///tmp/jarfile1.jar"),new URL("file:///tmp/jarfile2.jar")});
Class<?> cls = classLoader.loadClass("className");
Method method = cls.getDeclaredMethod ("main");
Object instance = cls.newInstance();
Object result = method.invoke (instance);

收益率

代码语言:javascript
复制
Exception in thread "main" java.lang.NoClassDefFoundError: alice/tuprolog/lib/InvalidObjectIdException
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2615)
at java.lang.Class.getDeclaredMethod(Class.java:2007)
at pkg1.MainClass.main(MainClass.java:54)
Caused by: java.lang.ClassNotFoundException: alice.tuprolog.lib.InvalidObjectIdException
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    ... 4 more

请注意,我将.jars复制到/tmp以隔离故障原因。这些文件是存在的并且是可以访问的。

如何使它在java代码中运行上面指定的类?

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-03-26 14:16:14

我终于修好了!所做的事情:

  1. 我忘了将第二个jar添加到项目的类路径中(糟糕!)
  2. 因为所有东西都在项目类路径上,所以我只是重用了当前的类加载器。

最后工作守则:

代码语言:javascript
复制
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Class<?> cls = classLoader.loadClass("className");
Method method = cls.getDeclaredMethod("main", String[].class);
Object instance = cls.newInstance();
Object result = method.invoke(null, (Object)args);

感谢大家,特别感谢VGR和Joop在评论中指出了第二个jar的错误!

编辑:正如JB在注释中指出的那样,直接调用类的main()方法更简单:

代码语言:javascript
复制
className.main(args);

你就完蛋了

票数 0
EN

Stack Overflow用户

发布于 2015-03-26 13:42:09

如果类存在于不同的ClassLoader中,则需要使用反射来获得它:

代码语言:javascript
复制
ClassLoader classLoader = new URLClassLoader(
    new URL[] { firstJarURL, secondJarURL });

String[] args = { arg1, arg2 };

try {
    Class<?> mainClass = classLoader.loadClass("com.somepackage.ClassName");
    mainClass.getMethod("main", String[].class).invoke(null, args);
} catch (ReflectiveOperationException e) {
    throw new RuntimeException(e);
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29279676

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档