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

ClassLoader defineClass does not define the package

XMLWordPrintable

      FULL PRODUCT VERSION :
      java version "1.8.0_152-ea"
      Java(TM) SE Runtime Environment (build 1.8.0_152-ea-b05)
      Java HotSpot(TM) 64-Bit Server VM (build 25.152-b05, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      Linux pellet 4.10.0-35-generic #39-Ubuntu SMP Wed Sep 13 07:46:59 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux


      A DESCRIPTION OF THE PROBLEM :
      Calling defineClass(String name, byte[] b, int off, int len) loads the class but not any associated packages.
      In Java9, the behaviour is that the package is loaded.

      This makes it impossible to write class transformation code that works on both java8 and java9

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the TestDefineClass with
      java -cp classes TestDefineClass

      You need a minimal class org.example.Something.class and a minimal org.example.package-info.class

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      loadClass: class org.example.Something
      org.example
      defineClass: class org.example.Something
      org.example

      ACTUAL -
      loadClass: class org.example.Something
      org.example
      defineClass: class org.example.Something


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.io.File;
      import java.io.FileInputStream;
      import java.io.InputStream;
      import java.net.URL;
      import java.net.URLClassLoader;
      import java.util.Arrays;


      public class TestDefineClass
      {
          private static final class TestLoader extends URLClassLoader
          {
              private TestLoader(URL[] urls)
              {
                  super(urls,null);
              }

              public Class<?> testDefineClass(String name, byte[] b, int off, int len)
              {
                  return defineClass(name,b,off,len);
              }
              
              @Override
              public Package getPackage(String name)
              {
                  // TODO Auto-generated method stub
                  return super.getPackage(name);
              }

              @Override
              public Package[] getPackages()
              {
                  // TODO Auto-generated method stub
                  return super.getPackages();
              }
          }

          public static void main(String[] args) throws Exception
          {
              File classes = new File("./classes").getAbsoluteFile();

              TestLoader loader = new TestLoader(new URL[] {classes.toURI().toURL()});
              Class<?> c = loader.loadClass("org.example.Something");

              System.err.println("loadClass: "+c);
              Arrays.asList(loader.getPackages()).stream().map(Package::getName).filter(s->s.startsWith("org.")).forEach(System.err::println);
              loader.close();
              

              loader = new TestLoader(new URL[] {classes.toURI().toURL()});
              File classfile = new File("./classes/org/example/Something.class");
              int len=(int)classfile.length();
              byte[] data = new byte[len];
              try(InputStream in = new FileInputStream(classfile))
              {
                  int pos=0;
                  while (pos<len)
                      pos += in.read(data,pos,len-pos);
              }

              c = loader.testDefineClass("org.example.Something",data,0,len);

              System.err.println("defineClass: "+c);
              Arrays.asList(loader.getPackages()).stream().map(Package::getName).filter(s->s.startsWith("org.")).forEach(System.err::println);
              loader.close();


          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      run java 9

        1. package-info.java
          0.1 kB
          Pallavi Sonal
        2. Something.java
          0.1 kB
          Pallavi Sonal
        3. TestDefineClass.java
          2 kB
          Pallavi Sonal

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: