问题描述
基本上我想从我正在处理的那个上运行一个外部.jar。
Basically I want to run an external .jar from the one I'm working on now.
即我想从bar.jar运行foo.jar
I.e. I want to run foo.jar from bar.jar
我尝试过使用运行时
和处理
执行java -jar foo.jar,但它会打开foo.jar然后立即关闭。任何提示?
I've tried using Runtime
and Process
to execute "java -jar foo.jar", but it opens foo.jar and then it closes immediately. Any tips?
推荐答案
最简单的解决方案()将jar作为构建时依赖项并从代码中静态调用它:
The easiest solution (as Thorn pointed out) would be to have the jar as a build-time dependency and invoke it statically from your code:
ExternalJarMainClass.main(new String[]{"arguments", "to", "main"});
但如果不可行,你可以使用 URLClassLoader
动态加载jar。如果jar确实可以运行,那么你可以从 META-INF / MANIFEST.MF
中读取主类并调用 main
通过反思。
But if that is not possible, you can use a URLClassLoader
to load the jar dynamically. If the jar is indeed runnable, then you can read the main class from META-INF/MANIFEST.MF
and invoke main
via reflection.
这是创建单独进程的另一种方法,因为外部代码将在与应用程序相同的进程中运行。也许这是可取的,也许不是 - 这取决于具体情况。
This is a different approach from creating a separate process, as the external code will run in the same process as your application. Perhaps this is desirable, perhaps not - that depends on the situation.
下面是一个(仓促编写和有缺陷的)样本助手类就是这样做的。
Below's a (hastily written and flawed) sample helper class that does just that.
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class JarRunner {
private final Method entryPoint;
public JarRunner(File jarFile) throws
ClassNotFoundException,
IOException,
NoSuchMethodException {
URL jarUrl = jarFile.toURI().toURL();
URLClassLoader loader = URLClassLoader.newInstance(
new URL[]{jarUrl});
URL manifestUrl = loader.findResource("META-INF/MANIFEST.MF");
String manifest = resourceToString(manifestUrl);
Class<?> clazz = loader.loadClass(findMainClassName(manifest));
entryPoint = clazz.getMethod("main", String[].class);
}
public void run(String[] argsToMain) throws
IllegalAccessException,
IllegalArgumentException,
InvocationTargetException {
entryPoint.invoke(null, (Object) argsToMain);
}
private static String resourceToString(URL url) throws IOException {
InputStream contentStream = url.openStream();
try {
BufferedReader r = new BufferedReader(
new InputStreamReader(contentStream));
StringBuilder sb = new StringBuilder();
String line = null;
do {
line = r.readLine();
if (line != null) {
sb.append(line).append('\n');
}
} while (line != null);
return sb.toString();
} finally {
contentStream.close();
}
}
private static String findMainClassName(String manifest) {
Matcher m = MAIN_CLASS_PATTERN.matcher(manifest);
if (m.find()) {
return m.group(1);
}
return null;
}
private static final Pattern MAIN_CLASS_PATTERN =
Pattern.compile("Main-Class: (.+)");
}
样本用法:
JarRunner jr = new JarRunner(new File("path/to/MyJar.jar"));
jr.run(new String[]{"arg1", "arg2"});
这篇关于如何从单独的jar文件运行jar文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!