RFR: 8335896: Source launcher should set TCCL

Jaikiran Pai jpai at openjdk.org
Mon Jul 15 16:17:52 UTC 2024


On Tue, 9 Jul 2024 10:52:46 GMT, Christian Stein <cstein at openjdk.org> wrote:

> Please review this change to set the context class loader of the current thread to the in-memory class loader when the `java` launcher is invoked in source mode. Having the source launcher set the TCCL to the in-memory classloader is benefical for scenarious depending on the TCCL being set to the application-loading loader.
> 
> For example, the single-argument taking [`ServiceLoader.load(Class)`](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/ServiceLoader.html#load(java.lang.Class)) method creates "a new service loader for the given service type, using the current thread's [context class loader](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Thread.html#getContextClassLoader())."

src/jdk.compiler/share/classes/com/sun/tools/javac/launcher/SourceLauncher.java line 204:

> 202:             ClassLoader loader = context.newClassLoaderFor(parentLoader, firstClassName);
> 203:             firstClass = Class.forName(firstClassName, false, loader);
> 204:             Thread.currentThread().setContextClassLoader(loader);

Hello Christian, a typical pattern for such Thread context classloader switches is to reset the context classloader back to the previous one, once the "work" is done. That way it doesn't influence the code after the completion of the work.

So something like the following might be more safer:


ClassLoader loader;
try {
    loader = context.newClassLoaderFor(parentLoader, firstClassName);
    firstClass = Class.forName(firstClassName, false, loader);
} catch (ClassNotFoundException e) {
    throw new Fault(Errors.CantFindClass(firstClassName));
}
final ClassLoader prevTCCL = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(loader);
try {
    Method mainMethod = MethodFinder.findMainMethod(firstClass);
    ... // rest of the existing code
    return mainClass;
} finally {
    Thread.currentThread().setContextClassLoader(prevTCCL);
}

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/20097#discussion_r1678086420


More information about the compiler-dev mailing list