Hello!
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 {
| process("test.NoInner");
| process("test.WithInner");
| process("test.WithInner$NotStatic");
| process("test.WithInner$Static");
| }
|
| public static void process(String className) throws Exception {
| System.out.println("Processing class: " + className);
| ClassPool pool = ClassPool.getDefault();
|
| CtClass cc = pool.get(className);
| removeFinal(cc);
|
| if (Modifier.isFinal(cc.getModifiers())) {
| throw new IllegalStateException("Class '" + className +
"' is not final?!?");
| }
|
| cc.writeFile("/tmp/test_patched/patched");
| System.out.println("Class was written: " + className);
| System.out.println();
| }
|
| 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);
| clazz.setModifiers(notFinalModifier);
| }
|
| }
|
| }
|
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() {
| super();
| }
|
| 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
| 9c9
| < 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?
Regards
Martin
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4090308#...
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&a...