Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8280772

newInstanceFromSystemProperty() loads class in different ClassLoader with javac

XMLWordPrintable

    • b13
    • 12
    • generic
    • generic

      A DESCRIPTION OF THE PROBLEM :
      When we launch a Java class with "java FunBug.java", the Java class is loaded in the com.sun.tools.javac.launcher.Main$MemoryClassLoader. Furthermore, if we load the same class using reflectively using newInstanceFromSystemProperty() inside the ForkJoinPool, for example when we specify a threadFactory, then it will use the same class that we have loaded in the MemoryClassLoader and create an
      instance to use as a thread factory. However, if we compile the class, and then run the Java class with "java FunBug.java", then the Java class is loaded in the MemoryClassLoader as before, but the class for the thread factory is loaded in the AppClassLoader. This means that we now have multiple class instances and
      any static variables would be defined twice. It works fine if we run the Java class with "java FunBug" (without the .java extension) or if we do not compile it and run it with "java FunBug.java" (with the .java extension).

      In Java 11, this condition caused the following error:

      java -Djava.util.concurrent.ForkJoinPool.common.threadFactory=FunBug FunBug.java
      Created FunBug class in jdk.internal.loader.ClassLoaders$AppClassLoader@77556fd
              of jdk.internal.loader.ClassLoaders$PlatformClassLoader@3270d194
      error: class found on application class path: FunBug

      Since Java 12, it would instead load the class twice, giving mysterious bugs

      REGRESSION : Last worked in version 11.0.14

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Compile the FunBug.java file with javac.
      2. Run the code with java -Djava.util.concurrent.ForkJoinPool.common.threadFactory=FunBug FunBug.java


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Either:

      Created FunBug class in com.sun.tools.javac.launcher.Main$MemoryClassLoader@35e2d654
              of jdk.internal.loader.ClassLoaders$AppClassLoader@77556fd
              of jdk.internal.loader.ClassLoaders$PlatformClassLoader@14cd1699

      or

      Created FunBug class in jdk.internal.loader.ClassLoaders$AppClassLoader@5c29bfd
              of jdk.internal.loader.ClassLoaders$PlatformClassLoader@3a4afd8d
      ACTUAL -
      Created FunBug class in com.sun.tools.javac.launcher.Main$MemoryClassLoader@6b0c2d26
              of jdk.internal.loader.ClassLoaders$AppClassLoader@75b84c92
              of jdk.internal.loader.ClassLoaders$PlatformClassLoader@646be2c3
      Created FunBug class in jdk.internal.loader.ClassLoaders$AppClassLoader@75b84c92
              of jdk.internal.loader.ClassLoaders$PlatformClassLoader@646be2c3
      Exception in thread "main" java.lang.NullPointerException
              at FunBug.newThread(FunBug.java:21)
              at java.base/java.util.concurrent.ForkJoinPool.createWorker(ForkJoinPool.java:1328)
              at java.base/java.util.concurrent.ForkJoinPool.tryAddWorker(ForkJoinPool.java:1352)
              at java.base/java.util.concurrent.ForkJoinPool.signalWork(ForkJoinPool.java:1476)
              at java.base/java.util.concurrent.ForkJoinPool.externalPush(ForkJoinPool.java:1903)
              at java.base/java.util.concurrent.ForkJoinTask.fork(ForkJoinTask.java:704)
              at java.base/java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:306)
              at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:746)
              at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
              at java.base/java.util.concurrent.ForkJoinTask.doInvoke(ForkJoinTask.java:408)
              at java.base/java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:736)
              at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateParallel(ForEachOps.java:159)
              at java.base/java.util.stream.ForEachOps$ForEachOp$OfInt.evaluateParallel(ForEachOps.java:188)
              at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
              at java.base/java.util.stream.IntPipeline.forEach(IntPipeline.java:439)
              at java.base/java.util.stream.IntPipeline$Head.forEach(IntPipeline.java:596)
              at FunBug.main(FunBug.java:28)


      ---------- BEGIN SOURCE ----------
      import java.util.concurrent.ForkJoinPool;
      import java.util.concurrent.ForkJoinWorkerThread;
      import java.util.concurrent.locks.LockSupport;
      import java.util.stream.IntStream;

      public class FunBug implements ForkJoinPool.ForkJoinWorkerThreadFactory {
          static {
              System.out.println("Created FunBug class in " +
                      FunBug.class.getClassLoader());
              ClassLoader parent = FunBug.class.getClassLoader().getParent();
              while (parent != null) {
                  System.out.println("\tof " + parent);
                  parent = parent.getParent();
              }
          }

          private static ForkJoinPool.ForkJoinWorkerThreadFactory defaultFactory;

          @Override
          public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
              return defaultFactory.newThread(pool);
          }

          public static void main(String... args) {
              defaultFactory = ForkJoinPool.defaultForkJoinWorkerThreadFactory;
              IntStream.range(0, Runtime.getRuntime().availableProcessors() * 8)
                      .parallel()
                      .forEach(i -> LockSupport.parkNanos(100_000_000));
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Don't run the javac launcher with compiled classes. Use either "java FunBug" with compiled classes or "java FunBug.java" without compiled classes

      FREQUENCY : always


            asotona Adam Sotona
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: