Community
Participate
Working Groups
The test is: package temp; public class JodeTest { public static interface Foo1 { void foo(); } public static interface Foo2 { void foo(); } public static interface Foo3 { void foo(); } public static interface Foo4 { void foo(); } public static interface Foo5 { void foo(); } public static interface Foo6 { void foo(); } public static interface Foo7 { void foo(); } } package temp_other; import temp.JodeTest; public final class Bar implements JodeTest.Foo1 { public void foo() {} public JodeTest.Foo2 foo2() { return null; } public void foo3( JodeTest.Foo3 foo ) {} public void foo4() { JodeTest.Foo4 foo = null; } public void foo5() { new JodeTest.Foo5() { public void foo() {} }.foo(); } public static class Foo6 implements JodeTest.Foo6 { public void foo() {} } public void foo7() { Bar2.foo7().foo(); } } package temp_other; import temp.JodeTest; public class Bar2 { public static JodeTest.Foo7 foo7() { return null; } } Javac does (order of lines modified slightly): InnerClass: public #11= #10 of #7; //Foo6=class temp_other/Bar$Foo6 of class temp_other/Bar public abstract #20= #19 of #41; //Foo2=class temp/JodeTest$Foo2 of class temp/JodeTest public abstract #24= #23 of #41; //Foo3=class temp/JodeTest$Foo3 of class temp/JodeTest public abstract #43= #9 of #41; //Foo1=class temp/JodeTest$Foo1 of class temp/JodeTest public abstract #49= #38 of #41; //Foo7=class temp/JodeTest$Foo7 of class temp/JodeTest final #2; //class temp_other/Bar$1 The new eclipse compiler does: InnerClass: public #56= #54 of #1; //Foo6=class temp_other/Bar$Foo6 of class temp_other/Bar public abstract #49= #47 of #44; //Foo2=class temp/JodeTest$Foo2 of class temp/JodeTest public abstract #52= #50 of #44; //Foo3=class temp/JodeTest$Foo3 of class temp/JodeTest public abstract #46= #5 of #44; //Foo1=class temp/JodeTest$Foo1 of class temp/JodeTest public abstract #53= #39 of #44; //Foo7=class temp/JodeTest$Foo7 of class temp/JodeTest #25; //class temp_other/Bar$1 Javac flags the anonymous inner class Bar$1 as final, Eclipse does not. This seems to break jode as the flags in the InnerClass attribute do not match the actual class's flags. The disassembly of the Eclipse-generated Bar$1 class shows that Eclipse, too, makes the anonymous inner class final: Compiled from "Bar.java" final class temp_other.Bar$1 extends java.lang.Object implements temp.JodeTest$Foo5 SourceFile: "Bar.java" EnclosingMethod: length = 0x4 00 19 00 1B InnerClass: public abstract #32= #5 of #30; //Foo5=class temp/JodeTest$Foo5 of class temp/JodeTest #1; //class temp_other/Bar$1
If you check with javac 1.3.1, 1.4.2 and 1.5.0, the anonymous class is not set as final. With 1.6 it is set as final. I'll try to get more details to know why this has been changed.
We change the behavior that we had for bug 162296. But it seems that JDK6 agrees with what we had before. So we might want to revisit the fix for bug 162296. We were right to remove the private bit, but we should not clear the final bit if the target jdk is greater or equals to 1.6. Philippe, Any comment? Peter, could you please confirm you are using a 1.6 JDK?
Ok by me.
Looking at http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4777101, I wonder if this is not a bug introduced in JDK6. So even if the fix is trivial, I am not sure we should align with the javac behavior.
Yes, I am using JDK 1.6.0.
Regarding http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4777101, I don't believe we should change anything. So JODE should not expect final to be set. I'll keep investigating why this has changed since 1.6.
Created attachment 57609 [details] Proposed fix This requires update in the existing test. org.eclipse.jdt.core.tests.compiler.regression.InnerEmulationTest#test149
According to http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6520152, this is a bug in javac. So I'll preserve our existing behavior and I will add a regression test to make sure that we won't introduce this bug. Added regression test org.eclipse.jdt.core.tests.compiler.regression.InnerEmulationTest#test149 Closing as INVALID.