使用父进程类路径启动Java子进程
我想启动一个java子进程,与当前java进程具有相同的java类路径和动态加载的类。以下内容还不够,因为它不包含任何动态加载的类:
String classpath = System.getProperty("java.class.path");
目前我正在使用下面的代码搜索每个需要的类。但是,在某些机器上,这对于某些类/库会失败,源变量为空。是否有更可靠、更简单的方法来获取当前 jvm 进程使用的库的位置?
String stax = ClassFinder.classPath("javax.xml.stream.Location");
public static String classPath(String qualifiedClassName) throws NotFoundException {
try {
Class qc = Class.forName( qualifiedClassName );
CodeSource source = qc.getProtectionDomain().getCodeSource();
if ( source != null ) {
URL location = source.getLocation();
String f = location.getPath();
f = URLDecoder.decode(f, "UTF-8"); // decode URL to avoid spaces being replaced by %20
return f.substring(1);
} else {
throw new ClassFinder().new NotFoundException(qualifiedClassName+" (unknown source, likely rt.jar)");
}
} catch ( Exception e ) {
throw new ClassFinder().new NotFoundException(qualifiedClassName);
}
}
I want to launch a java subprocess, with the same java classpath and dynamically loaded classes as the current java process. The following is not enough, because it doesn't include any dynamically loaded classes:
String classpath = System.getProperty("java.class.path");
Currently I'm searching for each needed class with the code below. However, on some machines this fails for some classes/libs, the source variable is null. Is there a more reliable and simpler way to get the location of libs that are used by the current jvm process?
String stax = ClassFinder.classPath("javax.xml.stream.Location");
public static String classPath(String qualifiedClassName) throws NotFoundException {
try {
Class qc = Class.forName( qualifiedClassName );
CodeSource source = qc.getProtectionDomain().getCodeSource();
if ( source != null ) {
URL location = source.getLocation();
String f = location.getPath();
f = URLDecoder.decode(f, "UTF-8"); // decode URL to avoid spaces being replaced by %20
return f.substring(1);
} else {
throw new ClassFinder().new NotFoundException(qualifiedClassName+" (unknown source, likely rt.jar)");
}
} catch ( Exception e ) {
throw new ClassFinder().new NotFoundException(qualifiedClassName);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
请参阅我的上一个问题 其中涵盖获取类路径以及如何启动子进程。
See my previous question which covers getting the classpath as well as how to launch a sub-process.
您的意思是调用一个新的 JVM?
鉴于...
......没有通用的、神奇的、包罗万象的和万无一失的方法来做到这一点。您应该设计您的应用程序及其类加载机制来实现此目标。如果您允许使用第 3 方插件,则必须记录其工作原理以及它们如何注册其库。
You mean invoke a new JVM?
Given that...
byte
array and turn it into a class...there is no general, magic, catch-all and foolproof way to do this. You should design your application and its class loading mechanisms to achieve this goal. If you allow 3rd party plug-ins, you'll have to document how this works and how they have to register their libraries.
如果您查看 Class.getClassLoader 的 javadoc,您会发现“引导”类加载器通常表示为 null。 “String.class.getClassLoader()”将在正常的 sun jvm 实现上返回 null。我认为这个实现细节会延续到 CodeSource 的内容中。因此,我认为只要您的子进程使用与当前进程相同的 jvm impl,您就不需要担心来自引导类加载器的任何类。
If you look at the javadoc for Class.getClassLoader, you'll see that the "bootstrap" classloader is typically represented as the null. "String.class.getClassLoader()" will return null on the normal sun jvm implementations. i think this implementation detail carries over into the CodeSource stuff. As such, I wouldn't imagine you would need to worry about any class which comes from the bootstrap classloader as long as your sub-process uses the same jvm impl as the current process.