Edward Ross
Edward Ross

Reputation: 2774

Launching Java Subprocess using parent process Classpath

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);
    }
}

Upvotes: 2

Views: 2953

Answers (3)

McDowell
McDowell

Reputation: 108899

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.

Upvotes: 1

james
james

Reputation: 468

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.

Upvotes: 0

Robert Petermeier
Robert Petermeier

Reputation: 4152

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

Upvotes: 2

Related Questions