Uploaded image for project: 'Harmony'
  1. Harmony
  2. HARMONY-5180

[drlvm][kernel][geronimo] Annotations get loaded with wrong classloader

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Critical
    • Resolution: Fixed
    • None
    • None
    • None

    Description

      Consider the following test:

      Test.java:

      import java.net.*;
      public class Test {
      public static void main(String[] args) {
      try {
      ClassLoader loader = new URLClassLoader(new URL[]

      { new URL("file:run.jar") }

      );
      loader.loadClass("Run").getMethod("run").invoke(null);
      System.out.println("SUCCESS");
      } catch (Exception e)

      { e.printStackTrace(System.out); }

      }
      }

      Run.java:

      import java.lang.annotation.*;
      import java.lang.reflect.*;
      import java.net.*;
      public class Run {
      public static void run() throws Exception {
      ClassLoader loader = new URLClassLoader(new URL[]

      { new URL("file:foo.jar") }

      );
      Class cls = loader.loadClass("Foo");
      Field field = cls.getDeclaredField("field");
      Annotation ann = field.getDeclaredAnnotations()[0];
      Class annClass = ann.getClass();
      Method method = annClass.getMethod("value");
      Class ret = (Class) method.invoke(ann);
      System.out.println("Ann: " + ret.getName());
      }
      }

      @Retention(RetentionPolicy.RUNTIME)
      @interface Ann {
      Class<? extends Bar> value();
      }

      class Bar {}

      class Foo {
      @Ann(Bar.class) int field;
      }

      Use the following sequence to build and run:

      $ javac Test.java Run.java
      $ jar cvf run.jar Run.class
      $ jar cvf foo.jar Foo.class Bar.class
      $ rm Run.class Foo.class Bar.class
      $ java Test

      Make sure to remove all class files except Test.class and Ann.class, or the test would behave incorrectly.

      Output on RI:

      Ann: Bar
      SUCCESS

      Output on DRLVM:

      java.lang.reflect.InvocationTargetException
      at java.lang.reflect.VMReflection.invokeMethod(VMReflection.java)
      at java.lang.reflect.Method.invoke(Method.java:317)
      at Test.main(Test.java:6)
      Caused by: java.lang.reflect.InvocationTargetException
      at java.lang.reflect.VMReflection.invokeMethod(VMReflection.java)
      at java.lang.reflect.Method.invoke(Method.java:317)
      at Run.run(Run.java:12)
      at java.lang.reflect.VMReflection.invokeMethod(VMReflection.java)
      ... 2 more
      Caused by: java.lang.TypeNotPresentException: Type Bar not present
      at org.apache.harmony.lang.annotation.AnnotationMember.rethrowError(AnnotationMember.java:298)
      at org.apache.harmony.lang.annotation.AnnotationMember.validateValue(AnnotationMember.java:341)
      at org.apache.harmony.lang.annotation.AnnotationFactory.invoke(AnnotationFactory.java:311)
      at .$Proxy0.value(Unknown Source)
      at java.lang.reflect.VMReflection.invokeMethod(VMReflection.java)
      ... 5 more
      Caused by: java.lang.NoClassDefFoundError: Bar
      at org.apache.harmony.vm.VMGenericsAndAnnotations.getDeclaredAnnotations(VMGenericsAndAnnotations.java)
      at java.lang.reflect.Field$FieldData.getAnnotations(Field.java:457)
      at java.lang.reflect.Field.getDeclaredAnnotations(Field.java:42)
      at Run.run(Run.java:9)
      at java.lang.reflect.VMReflection.invokeMethod(VMReflection.java)
      ... 2 more
      Caused by: java.lang.ClassNotFoundException: Bar
      at java.net.URLClassLoader.findClass(URLClassLoader.java:894)
      at java.lang.ClassLoader.loadClass(ClassLoader.java:575)
      at java.lang.ClassLoader$SystemClassLoader.loadClass(ClassLoader.java:963)
      at java.lang.ClassLoader.loadClass(ClassLoader.java:319)
      at org.apache.harmony.vm.VMGenericsAndAnnotations.getDeclaredAnnotations(VMGenericsAndAnnotations.java)
      ... 6 more

      We have the following 5 classes:

      Test: loads and accesses Run
      Run: loads and accesses Foo
      Foo: is annotated by Ann
      Ann: has a value of class Bar
      Bar: dummy

      loaded by the following 3 class loaders:

      System: Test, Ann
      run.jar: Run
      foo.jar: Foo, Bar

      The problem is when resolving the field annotation value, DRLVM uses the class loader of the annotation class Ann (in this test, system class loader, which has no access to Bar), instead of the class loader of the containing class Foo.

      This issue prevents Apache Geronimo 2.0 from starting on Harmony.

      Attachments

        Issue Links

          Activity

            People

              varlax Alexey Varlamov
              vmz Vasily Zakharov
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: