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

interaction of VM and ClassLoader doesn't correspond to specs

XMLWordPrintable

    • 1.2beta4
    • sparc
    • solaris_2.5
    • Not verified



      Name: szC45993 Date: 03/21/97



      In certain cases JDK1.1's VM uses ClassLoader differently comparing with JDK1.0.2
      and JVM and API specification books.

      Particularly,

      (1) VM makes class resolving not through "loadClass" method with resolve=true argument;
      (2) VM resolves superclasses not through "loadClass" method with resolve=true argument;

      More details:

      (1)
      The Java API, Volume 1, Core Packages, 1.4 Class ClassLoader says:

      "The methods and constructors of objects created by a class
      loader may reference other classes. To determine the class(es)
      referred to, the Java Virtual Machine calls the loadClass
      method (I-1.4.4) of the class loader that originally created
      the class. If the Java Virtual Machine only needs to determine
      if the class exists to know its superclass, the resolve flag is
      set to false. However, if an instance of the class is being
      created or any of its methods are being called, the class must
      also be resolved. In this case the resolve flag is set to true
      (for loadClass), and the resolveClass method (I-1.4.5) should
      be called.".

      Test below loads class "Intrmdt" using "myClassLoader.loadClass()"
      method with resolve flag is set to false. Then instance of the "Intrmdt"
      class is created using newInstance() which causes JVM to resolve the "Intrmdt"
      class. Note, that JVM spec doesn't specify explicitlty JVM behaviour in this
      case: is this resolving legal or illegal? In any case it is done not through
      the myClassLoader.loadClass().

      (2)

      The JVM Specification [5.1.2 Current Class or Interface Loaded by a Class Loader,
      p.145-146], says:

      "Linking and initializing a class or interface created by a
      class loader is very similar to linking and initializing a
      class or interface without a class loader (steps 2-4 of 5.1.1):

      First, the superclass of the class or interface is linked and
      initialized by calling the loadClass method of the class loader
      with the fully qualified name of the superclass as the first
      argument, and true as the second argument. Linking and
      initialization may result in the superclass's own superclass
      being linked and initialized."

      Again as in the first case JDK1.1's JVM makes resolving of "clss" directly
      and doesn't call "myClassLoader.loadClass()" at all.



      novo7% java -version
      java version "JDK1.1.1C"
      novo7% java -verify javasoft.sqe.tests.vm.constantpool._tmp.ClassInterf03601.ClassInterf03601
      ********ClassInterf03601.run*********
      Begin loadClass: javasoft.sqe.tests.vm.constantpool._tmp.ClassInterf03601.Intrmdt false
      Begin loadClassData: Intrmdt
      End loadClassData: Intrmdt
      Begin defineClass: Intrmdt
      Begin loadClass: javasoft.sqe.tests.vm.constantpool._tmp.ClassInterf03601.clss false
      Begin loadClassData: clss
      End loadClassData: clss
      Begin defineClass: clss
      Begin loadClass: java.lang.Object false
      Begin findSystemClass: java.lang.Object
      End findSystemClass: java.lang.Object
      End loadClass: java.lang.Object false
      End defineClass: clss
      End loadClass: javasoft.sqe.tests.vm.constantpool._tmp.ClassInterf03601.clss false
      End defineClass: Intrmdt
      End loadClass: javasoft.sqe.tests.vm.constantpool._tmp.ClassInterf03601.Intrmdt false
      Begin loadClass: java.lang.System false
      Begin findSystemClass: java.lang.System
      End findSystemClass: java.lang.System
      End loadClass: java.lang.System false
      Begin loadClass: java.io.PrintStream false
      Begin findSystemClass: java.io.PrintStream
      End findSystemClass: java.io.PrintStream
      End loadClass: java.io.PrintStream false
              clss INITIALIZING begin
              clss INITIALIZING end
      Begin loadClass: java.lang.Runnable false
      Begin findSystemClass: java.lang.Runnable
      End findSystemClass: java.lang.Runnable
      End loadClass: java.lang.Runnable false
              Intrmdt INITIALIZING begin
      Begin loadClass: java.lang.String false
      Begin findSystemClass: java.lang.String
      End findSystemClass: java.lang.String
      End loadClass: java.lang.String false
              Intrmdt INITIALIZING end
      ********Intrmdt.run*********
      ********clss.prc*********



      novo7% java -version
      java version "1.0.2"
      novo7% java -verify javasoft.sqe.tests.vm.constantpool._tmp.ClassInterf03601.ClassInterf03601
      ********ClassInterf03601.run*********
      Begin loadClass: javasoft.sqe.tests.vm.constantpool._tmp.ClassInterf03601.Intrmdt false
      Begin loadClassData: Intrmdt
      End loadClassData: Intrmdt
      Begin defineClass: Intrmdt
      Begin loadClass: javasoft.sqe.tests.vm.constantpool._tmp.ClassInterf03601.clss false
      Begin loadClassData: clss
      End loadClassData: clss
      Begin defineClass: clss
      Begin loadClass: java.lang.Object false
      Begin findSystemClass: java.lang.Object
      End findSystemClass: java.lang.Object
      End loadClass: java.lang.Object false
      End defineClass: clss
      End loadClass: javasoft.sqe.tests.vm.constantpool._tmp.ClassInterf03601.clss false
      End defineClass: Intrmdt
      End loadClass: javasoft.sqe.tests.vm.constantpool._tmp.ClassInterf03601.Intrmdt false
      java.lang.NoSuchMethodError
      at javasoft.sqe.tests.vm.constantpool._tmp.ClassInterf03601.ClassInterf03601.run(ClassInterf03601.java:128)
      at javasoft.sqe.tests.vm.constantpool._tmp.ClassInterf03601.ClassInterf03601.main(ClassInterf03601.java:146)



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


      --------------------- ClassInterf03601.java
      package javasoft.sqe.tests.vm.constantpool._tmp.ClassInterf03601;

      import java.io.PrintStream;
      import java.io.*;
      import java.lang.*;
      import java.util.*;

      class myClassLoader extends java.lang.ClassLoader {
        Hashtable cache = new Hashtable();

        private byte loadClassData(String name)[] {
      String pckg = "/javasoft/sqe/tests/vm/constantpool/_tmp/ClassInterf03601/";
      String str_1;
      String str_2;
      String str1 = "";
      String str2 = ""+pckg;
      byte bt[];
      int length;
      int index = 0;
      Properties prpr = System.getProperties();

      System.out.println("Begin \t loadClassData: \t"+name);
      str_1 = prpr.getProperty("java.class.path");
      str2 = str2.concat(name);
      str2 = str2.concat(".class");
      str1 = str1.concat(str_1.substring(str_1.indexOf(":")+1));
      try{
      index = str_1.indexOf(":");
      str_1 = str_1.substring(0,index);
      } catch (Exception e) {System.out.println(e);return null;};
      str_2 = str_1.concat(pckg+"Intrmdt.class");
      str_1 = str_1.concat(str2);

      while (true) {
      File fl1;
      fl1 = new File(str_2);
      if (fl1.isFile()) {
      break;
      } else {
      str_1 = "";
      try{
      index = str1.indexOf(":");
      str_1 = str_1.concat(str1.substring(0,index));
      } catch (Exception e) {System.out.println(e);return null;};
      str1 = str1.substring(str1.indexOf(":")+1);
      str_2 = str_1.concat(pckg+"Intrmdt.class");
      str_1 = str_1.concat(str2);
      }
      }

      try{
      FileInputStream fl3;
      fl3 = new FileInputStream(str_1);
      length = fl3.available();
      bt = new byte[length];
      fl3.read(bt);
      fl3.close();
      } catch (java.io.IOException e) {System.out.println(e);return null;};

      System.out.println("End \t loadClassData: \t"+name);
      return bt;

        }

        public synchronized Class loadClass(String name, boolean resolve) {
      Class c = (Class) cache.get(name);
      String s1 = "Intrmdt";
      String s2 = "clss";
      String s3 = "ClassInterf03601";
      String s4 = "Runnable";
      String name1;

      System.out.println("Begin \t loadClass: \t"+name+" "+resolve);

      if (name.indexOf(s1) != -1) {
      name1 = s1;
      } else if (name.indexOf(s2) != -1) {
      name1 = s2;
      } else {
      name1 = name;
      }

      if (name1.indexOf(".") != -1) {
      if (c == null) {
      try{
      System.out.println("Begin \t findSystemClass: \t"+name);
      c = findSystemClass(name1);
      System.out.println("End \t findSystemClass: \t"+name);
      }
      catch (java.lang.ClassNotFoundException e) {
      System.out.println(e);
      return null;
      };
      cache.put(name, c);
      }
      } else {
      if (c == null) {
      byte data[] = loadClassData(name1);
      System.out.println("Begin \t defineClass: \t"+name1);
      c = defineClass(data,0,data.length);
      System.out.println("End \t defineClass: \t"+name1);
      cache.put(name, c);
      }
      }
      if (resolve) {
      System.out.println("Begin \t resolveClass: \t"+c);
      resolveClass(c);
      System.out.println("End \t resolveClass: \t"+c);
      }

      System.out.println("End \t loadClass: \t"+name+" "+resolve);
      return c;
        }

      }

      public class ClassInterf03601 {

        public static int run(String argv[], PrintStream out) {
      myClassLoader mcl = new myClassLoader();
      Object obj = null;

      try{
      out.println("********ClassInterf03601.run*********");
      obj = mcl.loadClass( "javasoft.sqe.tests.vm.constantpool._tmp.ClassInterf03601.Intrmdt", false).newInstance();
      }
      catch (java.lang.IllegalAccessException e) {
      out.println(e);
      return 0;
      }
      catch (java.lang.InstantiationException e) {
      out.println(e);
      return 0;
      };

      ((Runnable) obj).run();

      return 2;

        }

        public static void main(String argv[]) {
      System.exit(run(argv, System.out) + 95/*STATUS_TEMP*/);
        }
      }
      --------------------- Intrmdt.java
      package javasoft.sqe.tests.vm.constantpool._tmp.ClassInterf03601;

      import java.io.PrintStream;
      import java.lang.*;

      public class Intrmdt extends clss implements Runnable{
      static String str = "Class Intrmdt is linked";

      static {
       System.out.println(" Intrmdt INITIALIZING begin");
       str = str.concat(clss.str);
       System.out.println(" Intrmdt INITIALIZING end");
      }

        public void run() {
      System.out.println("********Intrmdt.run*********");
      super.run();
        }
      }
      --------------------- clss.java
      package javasoft.sqe.tests.vm.constantpool._tmp.ClassInterf03601;

      import java.io.PrintStream;
      import java.io.*;
      import java.lang.*;

      public class clss{

      static String str;

      static {
       System.out.println(" clss INITIALIZING begin");
       str = " and initialized!";
       System.out.println(" clss INITIALIZING end");
      }

        public void run() {

      System.out.println("********clss.prc*********");
        }
      }
      -----------------------------------------------------------------------


      ======================================================================

            sliangsunw Sheng Liang (Inactive)
            zsssunw Zss Zss (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: