使用父进程类路径启动Java子进程

发布于 2024-08-17 18:26:20 字数 1084 浏览 4 评论 0原文

我想启动一个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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

吃→可爱长大的 2024-08-24 18:26:20

请参阅我的上一个问题 其中涵盖获取类路径以及如何启动子进程。

See my previous question which covers getting the classpath as well as how to launch a sub-process.

半窗疏影 2024-08-24 18:26:20

我想启动一个java子进程,与当前java进程具有相同的java类路径和动态加载的类。

您的意思是调用一个新的 JVM?

鉴于...

  • 可以将各种代理和工具插入到 JVM 中,该 JVM 可以在加载时转换类,
  • 可以采用字节数组并将其转换为
  • 类可能有复杂的类加载器层次结构,类之间的可见性不同,并且多次加载相同的类

......没有通用的、神奇的、包罗万象的和万无一失的方法来做到这一点。您应该设计您的应用程序及其类加载机制来实现此目标。如果您允许使用第 3 方插件,则必须记录其工作原理以及它们如何注册其库。

I want to launch a java subprocess, with the same java classpath and dynamically loaded classes as the current java process.

You mean invoke a new JVM?

Given that...

  • it is possible to plug in all sorts of agents and instrumentation into a JVM that can transform classes at load time
  • it is possible to take a byte array and turn it into a class
  • it is possible to have complex class loader hierarchies with varying visibility between classes and have the same classes loaded multiple times

...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.

新雨望断虹 2024-08-24 18:26:20

如果您查看 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文