aot bug with multiple class loaders

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

aot bug with multiple class loaders

蒯微(麦庶)
Hi,
  Recently I tested aot feature in jdk10 and I think there's a bug in aot when aot method access classes from multiple class loaders.

  When a class is loaded, jvm try to iterate all aot code cache to find if it's a defined symbol of shared library. But it doesn't check class loader carefully, so a class in aot cache could incorrectly access class data in another loader . Please check my test case.

cat sub1/T1.java
public class T1{
  public int xadd(int a,int b){
    int r=a+b+T2.foo;
    System.out.println(r);
    return r;
  }
}
cat sub1/T2.java
public class T2{
  public static int foo=300;
  public static void change(int newVal) {foo=newVal;}
}

compile them in sub1 directory and make a copy as sub2. Create a aot library for T1.class
jaotc --output aot.so T1.class

put the aot.so into project directory and create a test file

cat Main.java

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
public class Main{
    public static void main(String[] args)throws Exception{
        File file1=new File("./sub1");
        File file2=new File("./sub2");
        URL url1 = file1.toURI().toURL();
        URL url2 = file2.toURI().toURL();
        changeT2(url1);  // run with loader1
        run(url2);            // run with loader2
    }
    public static void changeT2(URL url) throws Exception{
        URL [] urls={url};
        URLClassLoader ucl = new URLClassLoader(urls);
        Class<?> c2 = ucl.loadClass("T2");
        Constructor<?> conc = c2.getConstructor();
        Object obj = conc.newInstance();
        Method m = c2.getMethod("change", int.class);
        m.invoke(obj, 0); // change T2.foo=0
    }
    public static void run(URL url) throws Exception{
        URL [] urls={url};
        URLClassLoader ucl = new URLClassLoader(urls);
        Class<?> c1 = ucl.loadClass("T1");
        Constructor<?> conc = c1.getConstructor();
        Object obj = conc.newInstance();
        Method m = c1.getMethod("xadd", int.class, int.class);
        m.invoke(obj, 0, 0);
    }
}

The whole project is like this:
> ls -l *
-rw-r--r-- 1 kuaiwei.kw users 108329 Jul  9 14:55 aot.so
-rw-r--r-- 1 kuaiwei.kw users   1613 Jul  9 14:55 Main.class
-rw-r--r-- 1 kuaiwei.kw users   1241 Jul  9 14:55 Main.java
sub1:
total 16
-rw-r--r-- 1 kuaiwei.kw users 398 Jul  9 14:55 T1.class
-rw-r--r-- 1 kuaiwei.kw users 118 Jul  9 14:55 T1.java
-rw-r--r-- 1 kuaiwei.kw users 321 Jul  9 14:55 T2.class
-rw-r--r-- 1 kuaiwei.kw users 103 Jul  9 14:55 T2.java
sub2:
total 16
-rw-r--r-- 1 kuaiwei.kw users 398 Jul  9 14:55 T1.class
-rw-r--r-- 1 kuaiwei.kw users 118 Jul  9 14:55 T1.java
-rw-r--r-- 1 kuaiwei.kw users 321 Jul  9 14:55 T2.class
-rw-r--r-- 1 kuaiwei.kw users 103 Jul  9 14:55 T2.java
run without aot
> java Main
300

run with aot
> java -XX:+UseAOT -XX:AOTLibrary=./aot.so Main
0

Best Regards,
Kevin
Reply | Threaded
Open this post in threaded view
|

Re: aot bug with multiple class loaders

Vladimir Kozlov
Thank you, Kevin

Yes, this is Day One problem. I filed:

https://bugs.openjdk.java.net/browse/JDK-8206963

Regards,
Vladimir

On 7/9/18 12:05 AM, 蒯微(麦庶) wrote:

> Hi,
>    Recently I tested aot feature in jdk10 and I think there's a bug in aot when aot method access
> classes from multiple class loaders.
>
>    When a class is loaded, jvm try to iterate all aot code cache to find if it's a defined symbol of
> shared library. But it doesn't check class loader carefully, so a class in aot cache could
> incorrectly access class data in another loader . Please check my test case.
>
> cat sub1/T1.java
> public class T1{
>    public int xadd(int a,int b){
>      int r=a+b+T2.foo;
>      System.out.println(r);
>      return r;
>    }
> }
> cat sub1/T2.java
> public class T2{
>    public static int foo=300;
>    public static void change(int newVal) {foo=newVal;}
> }
>
> compile them in sub1 directory and make a copy as sub2. Create a aot library for T1.class
> jaotc --output aot.so T1.class
>
> put the aot.so into project directory and create a test file
>
> cat Main.java
>
> import java.io.File;
> import java.lang.reflect.Constructor;
> import java.lang.reflect.Method;
> import java.net.URL;
> import java.net.URLClassLoader;
> public class Main{
>      public static void main(String[] args)throws Exception{
>          File file1=new File("./sub1");
>          File file2=new File("./sub2");
>          URL url1 = file1.toURI().toURL();
>          URL url2 = file2.toURI().toURL();
>          changeT2(url1);  // run with loader1
>          run(url2);            // run with loader2
>      }
>      public static void changeT2(URL url) throws Exception{
>          URL [] urls={url};
>          URLClassLoader ucl = new URLClassLoader(urls);
>          Class<?> c2 = ucl.loadClass("T2");
>          Constructor<?> conc = c2.getConstructor();
>          Object obj = conc.newInstance();
>          Method m = c2.getMethod("change", int.class);
>          m.invoke(obj, 0); // change T2.foo=0
>      }
>      public static void run(URL url) throws Exception{
>          URL [] urls={url};
>          URLClassLoader ucl = new URLClassLoader(urls);
>          Class<?> c1 = ucl.loadClass("T1");
>          Constructor<?> conc = c1.getConstructor();
>          Object obj = conc.newInstance();
>          Method m = c1.getMethod("xadd", int.class, int.class);
>          m.invoke(obj, 0, 0);
>      }
> }
>
> The whole project is like this:
>  > ls -l *
> -rw-r--r-- 1 kuaiwei.kw users 108329 Jul  9 14:55 aot.so
> -rw-r--r-- 1 kuaiwei.kw users   1613 Jul  9 14:55 Main.class
> -rw-r--r-- 1 kuaiwei.kw users   1241 Jul  9 14:55 Main.java
> sub1:
> total 16
> -rw-r--r-- 1 kuaiwei.kw users 398 Jul  9 14:55 T1.class
> -rw-r--r-- 1 kuaiwei.kw users 118 Jul  9 14:55 T1.java
> -rw-r--r-- 1 kuaiwei.kw users 321 Jul  9 14:55 T2.class
> -rw-r--r-- 1 kuaiwei.kw users 103 Jul  9 14:55 T2.java
> sub2:
> total 16
> -rw-r--r-- 1 kuaiwei.kw users 398 Jul  9 14:55 T1.class
> -rw-r--r-- 1 kuaiwei.kw users 118 Jul  9 14:55 T1.java
> -rw-r--r-- 1 kuaiwei.kw users 321 Jul  9 14:55 T2.class
> -rw-r--r-- 1 kuaiwei.kw users 103 Jul  9 14:55 T2.java
> run without aot
>  > java Main
> 300
>
> run with aot
>  > java -XX:+UseAOT -XX:AOTLibrary=./aot.so Main
> 0
>
> Best Regards,
> Kevin