Community
Participate
Working Groups
I am using the Jakarta Avalon open source project. I checked out jakarta- avalon-excalibur from the apache cvs tree, mounted all source folders in the project and imported the necessary libraries. I have a class that needs to use the org/apache/excalibur/fortress/util/ContextManager class. When I try to run my class or the unit test class org.apache.excalibur.fortress.test.ContainerProfile.java (any class that needs the ContextManager) I get the following Exception trace: java.lang.VerifyError: (class: org/apache/excalibur/fortress/util/ContextManager, method: initializeLoggerManager signature: ()V) Register 2 contains wrong type at org.apache.excalibur.fortress.test.ContainerProfile.testCompare_ECM_ContainerMan ager_UseageTime(ContainerProfile.java:106) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:324) at junit.framework.TestCase.runTest(TestCase.java:166) at junit.framework.TestCase.runBare(TestCase.java:140) at junit.framework.TestResult$1.protect(TestResult.java:106) at junit.framework.TestResult.runProtected(TestResult.java:124) at junit.framework.TestResult.run(TestResult.java:109) at junit.framework.TestCase.run(TestCase.java:131) at junit.framework.TestSuite.runTest(TestSuite.java:173) at junit.framework.TestSuite.run(TestSuite.java:168) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests (RemoteTestRunner.java:319) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run (RemoteTestRunner.java:215) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main (RemoteTestRunner.java:150) When running the excalibur build file using ant and the jdk1.4 compiler and then import the generated jar everything seems to work ok, so I attribute the error to the eclipse compiler. I also tried to change the order of the class path, which didn't help. I am running latest stable build M5 on Win2k and jdk1.4. The compiler compatibility settings are set to jdk1.4.
Could you provide the offending unit source for debug purpose ?
Here is a simpler test case: public class Test16279 { Logger logger; public static void main(String[] args) { } public void foo() { try { System.out.println(); } catch (Exception ce) { String s = null; try { return; } catch (Exception ex) { } s.hashCode(); } finally { if (this.logger == null) { LoggerManager loggerManager = null; } } } } The J9 doesn't complain even if you add -verify. Any JDK fails with: Exception in thread "main" java.lang.VerifyError: (class: Test16279, method: foo signature: ()V) Register 2 contains wrong type. It seems to be related to the subroutine code generation. For the above code, our bytecodes are: Method void foo() 0 getstatic #26 <Field java.io.PrintStream out> 3 invokevirtual #31 <Method void println()> 6 goto 31 9 astore_1 10 aconst_null 11 astore_2 12 jsr 37 15 return 16 astore_3 17 aload_2 <==== This seems to be the problem 18 invokevirtual #37 <Method int hashCode()> 21 pop 22 goto 31 25 astore_1 26 jsr 37 29 aload_1 30 athrow 31 jsr 37 34 goto 50 37 astore 4 39 aload_0 40 getfield #39 <Field Logger logger> 43 ifnonnull 48 46 aconst_null 47 astore_2 <==== This seems to be the problem 48 ret 4 50 return Exception table: from to target type 0 9 9 <Class java.lang.Exception> 12 16 16 <Class java.lang.Exception> 0 22 25 any The first attempt we can do in order to fix the problem is to avoid reusing the same slot between the first catch block and the finally block. Javac produces the following bytecodes: Method void foo() 0 getstatic #2 <Field java.io.PrintStream out> 3 invokevirtual #3 <Method void println()> 6 jsr 42 9 goto 56 12 astore_1 13 aconst_null 14 astore_2 15 jsr 42 18 return 19 astore_3 20 goto 23 23 aload_2 24 invokevirtual #5 <Method int hashCode()> 27 pop 28 jsr 42 31 goto 56 34 astore 4 36 jsr 42 39 aload 4 41 athrow 42 astore 5 44 aload_0 45 getfield #6 <Field Logger logger> 48 ifnonnull 54 51 aconst_null 52 astore 6 54 ret 5 56 return Exception table: from to target type 0 6 12 <Class java.lang.Exception> 0 9 34 any 12 18 34 any 19 31 34 any 34 39 34 any We can see that they never reuse any register for the locals. I will investigate this solution.
Jikes 1.15 compiles in a similar way we do compare to javac, but it doesn't reuse the same slots for the locals: Method void foo() 0 getstatic #21 <Field java.io.PrintStream out> 3 invokevirtual #26 <Method void println()> 6 jsr 41 9 goto 53 12 astore 4 14 aconst_null 15 astore 5 17 jsr 41 20 return 21 astore 6 23 aload 5 25 invokevirtual #34 <Method int hashCode()> 28 pop 29 jsr 41 32 goto 53 35 astore_1 36 jsr 41 39 aload_1 40 athrow 41 astore_2 42 aload_0 43 getfield #38 <Field Logger logger> 46 ifnonnull 51 49 aconst_null 50 astore_3 51 ret 2 53 return Exception table: from to target type 17 21 21 <Class java.lang.RuntimeException> 0 6 12 <Class java.lang.RuntimeException> 0 29 35 any I am not sure this is not a bug in the bytecode verifier. If you remove the latest if in the source code, then you can run the code fine. Anyway we have to fix this problem, because any JDK will fail running the code compiled by Eclipse.
The finally block needs to be shifted behind try and catch blocks for local variable allocation. We did shift against the try block, and missed the catch blocks shifting. Fixed
Verified. The source can now compile fine.
Verified in F2.
Verified.
*** Bug 19916 has been marked as a duplicate of this bug. ***