1 Reply Latest reply on Jul 16, 2008 7:00 AM by peter drag

    Removing final modifier of inner classes

    Martin Burger Newbie


      I've written a tool that removes the final modifier from class files. That works perfectly with "outer" classes, but with inner classes javassist seems to fail. Here is a small test case.

      The class FinalRemover does the job:

      package test;
      import javassist.ClassPool;
      import javassist.CtClass;
      import javassist.Modifier;
      public class FinalRemover {
       public static void main(String[] args) throws Exception {
       public static void process(String className) throws Exception {
       System.out.println("Processing class: " + className);
       ClassPool pool = ClassPool.getDefault();
       CtClass cc = pool.get(className);
       if (Modifier.isFinal(cc.getModifiers())) {
       throw new IllegalStateException("Class '" + className + "' is not final?!?");
       System.out.println("Class was written: " + className);
       protected static void removeFinal(CtClass clazz) {
       int modifiers = clazz.getModifiers();
       if (Modifier.isFinal(modifiers)) {
       System.out.println("Removing final modifier: " + clazz.getName());
       int notFinalModifier = Modifier.clear(modifiers, Modifier.FINAL);

      The class NoInner has no inner class:

      package test;
      public final class NoInner {

      Finally, the class WithInner has two inner classes:

      package test;
      public class WithInner {
       public WithInner() {
       public static final class Static {
       public static final String CONST = "Static inner class";
       public final class NotStatic {
       public static final String CONST = "Not static inner class";

      Running the tool writes the following output:

      Processing class: test.NoInner
      Removing final modifier: test.NoInner
      Class was written: test.NoInner
      Processing class: test.WithInner
      Class was written: test.WithInner
      Processing class: test.WithInner$NotStatic
      Removing final modifier: test.WithInner$NotStatic
      Class was written: test.WithInner$NotStatic
      Processing class: test.WithInner$Static
      Removing final modifier: test.WithInner$Static
      Class was written: test.WithInner$Static

      I decompiled the written class files using JAD. A diff between the original and the patched class NoInner shows the expected result:

      $ diff orig/NoInner.jad patched/NoInner.jad
      < public final class NoInner
      > public class NoInner

      But, between the original and the patched class WithInner, there is no difference:

      $ diff orig/WithInner.jad patched/WithInner.jad

      Thus, the final modifier was not removed from the byte code. Please note the IllegalStateException in my code: javassist thinks that modifier was removed, but it is still contained in the byte code written the the file.

      Any ideas?