如何从jar文件动态运行java类
我正在从事一个java项目,该项目需要一个作为服务器运行的第三方java程序 通常,我会:如何从jar文件动态运行java类,java,jar,classloader,Java,Jar,Classloader,我正在从事一个java项目,该项目需要一个作为服务器运行的第三方java程序 通常,我会: java -cp jarfile1.jar:jarfile2.jar className arg1 arg2 然后我会运行我的java代码。这样就行了 我想知道是否有任何方法可以直接从我的代码运行这个类,而不必手动启动它,包括在我的项目中需要的两个.jar 正如我在一些示例中看到的那样,我尝试使用URLClassLoader,但要么我做得不对,要么没有涉及这个特定用例 URLClassLoader cl
java -cp jarfile1.jar:jarfile2.jar className arg1 arg2
然后我会运行我的java代码。这样就行了
我想知道是否有任何方法可以直接从我的代码运行这个类,而不必手动启动它,包括在我的项目中需要的两个.jar
正如我在一些示例中看到的那样,我尝试使用URLClassLoader
,但要么我做得不对,要么没有涉及这个特定用例
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);
请注意,我将.jars复制到/tmp以隔离故障原因。这些文件存在并且可以访问
如何让它在java代码中运行上面指定的类
谢谢 如果该类存在于不同的类加载器中,则需要使用反射来访问它:
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);
}
ClassLoader ClassLoader=新的URLClassLoader(
新URL[]{firstJarURL,secondJarURL});
字符串[]args={arg1,arg2};
试一试{
Class mainClass=classLoader.loadClass(“com.somepackage.ClassName”);
getMethod(“main”,String[].class).invoke(null,args);
}捕捉(反射操作异常e){
抛出新的运行时异常(e);
}
我终于修好了!所做的事情:
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);
你已经做完了对不起,我不明白。将代码保存为可运行的.jar文件如何避免我运行第三方类?你能详细介绍一下吗?
ClassName.main(“arg1”、“arg2”)代码>?向我们展示带有URLClassLoader
的代码以及您遇到的错误哦,很好。这会在一个单独的线程上工作吗(这样主线程就不会被阻塞)?如果是这样,请发布一个答案,这样我就可以接受:)不,它不会在单独的线程中执行。但是没有什么可以阻止你启动一个线程来调用它。如果包含类名的jar文件位于类路径中,则不需要单独的类加载器(除非您特别想要隔离),我担心它不起作用,它生成了与我问题中的编辑相同的错误:(您是否验证了“alice/tuprolog/lib/InvalidObjectIdException.class”存在于一个jar文件中?这至少解决了对main
的正确调用。但是,首先尝试查找类alice.tuprolog.lib.invalidobjectIndexception
,并使用类似代码。首先使用jar中的zip工具查看。您还可以将当前类加载器/类作为第二个参数添加到URLClassLoaderLoader.getSystemClassLoader()
。是的,它在第二行,因为类名在Java代码中是硬编码的,为什么要使用反射。为什么不简单地用className.main(args)
替换您的5行代码?另外,您不应该创建className的实例来调用main().main()是一个静态方法。请将null作为method.invoke()的第一个参数传递。如果为True,我将把它添加到答案中
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);
className.main(args);