3 Replies Latest reply on May 9, 2005 1:13 PM by Shigeru Chiba

    Javassist and Java5's enumerations

    gpothier Newbie

      Hi, I have a problem with enumerations classes and Javassist: I'm getting a java.lang.NoClassDefFoundError when the VM tries to load an enumeration. Is Javassist supposed to support enumerations?
      The enumerations that cause problems are not created by Javassist but already exist. There is also something strange: when my project is compiled by the Eclipse compiler, there is no problem. The problem appears only when the project is compiled by javac.


        • 1. Re: Javassist and Java5's enumerations
          gpothier Newbie

          Sorry, the actual exception is a javassist.NotFoundException. Java's NoClassDefFound doesn't surface its root cause.
          Here is the stack trace:
          javassist.NotFoundException: [Lreflex.lib.logging.core.api.collector.BehaviourType;
          at javassist.ClassPool.get(ClassPool.java:301)
          at javassist.expr.MethodCall.getCtClass(MethodCall.java:76)
          at javassist.expr.MethodCall.getMethod(MethodCall.java:112)
          at reflex.core.model.expr.RMethodCallImpl.getMethod(RMethodCallImpl.java:69)


          BehaviourType being an enum.

          • 2. Re: Javassist and Java5's enumerations
            gpothier Newbie

            Ok, I found the problem. It is not specific to enumerations: Javassist doesn't properly handle array classes.
            For example, this code poses problems:

            String[] theStrings = {"A", "B"};
            theStrings = theStrings.clone();

            The problem is that in the class file, the method call is represented like that:
            16: invokevirtual #5; //Method "[Ljava/lang/String;".clone:()Ljava/lang/Object;

            So this is a call to method "clone" in class "[Ljava/lang/String;". And when trying to retrieve the target class, MethodCall.getCtClass passes this classname to ClassPool.get. But ClassPool.get doesn't understand this syntax: it expects something like java.lang.String[]

            So I see two ways to fix it:
            - Either change MethodCall.getClassName so that it transforms [Ljava.lang.String; to java.lang.String[]
            - Change ClassPool.get() so that it accepts [Ljava.lang.String;

            The reason why my original code worked with eclipse is that the eclipse compiler doesn't produce the same bytecode for enums in the values() method: Javac clones an array while eclipse instanciates a new array and does an arraycopy.

            • 3. Re: Javassist and Java5's enumerations
              Shigeru Chiba Expert

              For another request, I'll change ClassPool.get() to
              accept [L...;