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

(reflect) anonymous and inner classes cause errors in Class.getModifiers()

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P3
    • Resolution: Not an Issue
    • Affects Version/s: 1.2.0
    • Fix Version/s: None
    • Component/s: core-libs
    • Labels:

      Description



      Name: dbT83986 Date: 03/15/99


      I want to determine whether the class I have loaded is
      abstract.
      I wrote a FileClassLoader that extends ClassLoader. I load a
      class in a given directory,
      call the getModifiers() method and
      get an NoClassDefFoundError or IllegalAccessError if the class
      contains an anonymous class or an inner class.

      Under the JDK1.1.6, when I called the getModifiers() method, the
      interface java.awt.event.ActionListener was loaded, versus
      the name of the anonymous class; no problem.
      But now in JDK1.2, the anonymous class (with the
      enclosing class declared abstract) is attempted to be
      loaded and fails with java.lang.IllegalAccessError.
      An abstract class that has an inner class fails with
      java.lang.NoClassDefFoundError.

      +++++++++++++++++++++++++++++++++++++++++++++
      /// Source code that demonstrates the problem
      //
      // class that is being loaded by FileClassLoader (see code below)
      // this causes a java.lang.IllegalAccessError: try to access class
      // MyTextField$1 from class MyTextField
      public abstract class MyTextField extends TextField {

          public MyTextField() {
              super();
              addActionListener(new ActionListener() {
                  public void actionPerformed(ActionEvent e) {
                      System.out.println("Received " + e);
                  }
              });
              public abstract void someMethod();
          }
      }
      /////
      // this causes a java.lang.NoClassDefFoundError
      // for TestAbstract$MyListener
      //
      import java.awt.*;
      import java.awt.event.*;

      public abstract class TestAbstract extends TextField {

          public TestAbstract() {
              super();
              addActionListener(new MyListener());
          }
          private class MyListener implements ActionListener {

              public void actionPerformed(ActionEvent e) {
                  System.out.println("Received " + e);
              }
          }
      }
      ///

      // test program that loads class files from a directory
      // run the program on the directory where MyTextField.java and
      // TestAbstract.java were compiled.
      package util;

      import java.io.File;
      import java.io.FilenameFilter;
      import java.lang.reflect.Modifier;

      public class TestFileClassLoader {
          
          public void load(String dirName) {
              
              File dir = new File(dirName);
              if (!dir.isDirectory()) {
                  System.out.println("Please enter a folder/directory name");
                  System.exit(0);
              }
              
              String []names = dir.list(new FilenameFilter() {
                  public boolean accept(File d, String name) {
                      if (name.indexOf("$") >= 0 ||
                          !name.endsWith(".class")){
                          return (false);
                      }
                      return (true);
                  }
              });
               
              FileClassLoader loader = new FileClassLoader();
              
              
              for (int i=0;i<names.length; i++) {
                  try {
                      String filename = dir.getPath() + File.separatorChar + names[i];
                      Class c = loader.loadClass(filename);
                      System.out.println("Class name is " + c.getName());
                      if (Modifier.isAbstract(c.getModifiers())) {
                          System.out.println(c.getName() + " is abstract!");
                      }
                      else {
                          System.out.println(c.getName() + " is not abstract");
                      }
                  }catch (java.lang.Exception e) {
                      e.printStackTrace();
                  }catch (java.lang.Error e) {
                      e.printStackTrace();
                  }
                 
              }
              
          }
          public static void main(String []args) {
              
              if (args.length == 0) {
                  System.out.println("Usage: java util.TestFileClassLoader <dir name>");
                  System.exit(0);
              }
              
              TestFileClassLoader l = new TestFileClassLoader();
              l.load(args[0]);
               
          }
      }
              
                  
             
      /////
      // Class loader that loads a class from a file.
      package util;

      import java.io.*;
      import java.util.Hashtable;

      public class FileClassLoader extends ClassLoader {
          
          private Hashtable classHt;
          
          public FileClassLoader () {
              super();
              classHt = new Hashtable();
          }
          
          protected Class loadClass(String name, boolean resolve) throws
              java.lang.ClassNotFoundException,
              java.lang.ClassFormatError {
                  
              System.out.println("*** loadClass is called for " + name + ", resolve=" +
                  resolve);
                  
              Class c = (Class)classHt.get(name);
              
              if (c != null) {
                  System.out.println("Returning cached class " + name);
                  return (c);
              }
              
              try {
                  c = findSystemClass(name);
              } catch (java.lang.Throwable t) {
                  if (!(t instanceof java.lang.ClassNotFoundException)) {
                      t.printStackTrace();
                  }
              }
              if (c == null) {
                  String filename = name;
                  if (!name.endsWith(".class")) {
                      filename = name.replace('.', File.separatorChar) + ".class";
                  }
                  try {
                      byte []b = loadClassData(filename);
                      System.out.println("Got bytes from " + filename);
                      c = defineClass(null, b, 0,b.length);
                      if (c == null) {
                          throw new ClassNotFoundException(name);
                      }
                  } catch (java.io.IOException e) {
                      throw new ClassNotFoundException("Error reading " + filename);
                  }
              }
              if (resolve) {
                  resolveClass(c);
              }
              classHt.put(name, c);
              return (c);
          }
              
          private byte []loadClassData(String filename) throws java.io.IOException {
              File f = new File(filename);
              FileInputStream fs = new FileInputStream(filename);
              byte []b = new byte[(int)f.length()];
              fs.read(b);
              fs.close();
              return (b);
          }
      }
      // +++++++++++++++

      Stack Trace info:

      java.lang.NoClassDefFoundError: TestAbstract$MyLIstener
        at java.lang.Class.getModifiers<Native Method>
        at util.TestFileClassLoader.load<Compiled Code>
        at util.TestFileClassLoader.main<TestFileClassLoader.java:58>

      java.lang.IllegalAccessError: try to access class MyTextField$1 from class
      MyTextField
        at java.lang.Class.getModifiers<Native Method>
        at util.TestFileClassLoader.load<Compiled Code>
        at util.TestFileClassLoader.main<TestFileClassLoader.java:58>

      //++++++++
      java -fullversion
      JAVA.EXE full version "JDK-1.2-V"
      (Review ID: 55552)
      ======================================================================

        Attachments

          Activity

            People

            Assignee:
            apalanissunw Anand Palaniswamy (Inactive)
            Reporter:
            dblairsunw Dave Blair (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: