Community
Participate
Working Groups
BEA's JRockit JVM (version: 8.1sp2-1.4.1_05-Load10-viking-win32-sthqa29-20031105-1554) crashes on simple inter-type declarations. (Obviously I have also submitted this bug to BEA, but the AJ team may be able to shed some light on what is going on and where (if anywhere) BEA's JVM is behaving wrong.) The cannonical example lies below: public class SimpleClass { public static void main(String[] args) { SimpleClass simple = new SimpleClass(); } } public aspect SimpleAspect { public int SimpleClass.foo; } When running SimpleClass I get a JVM crash with the following thread stack trace. Thread Stack Trace: at _exprPush+112 ()@0082FF70 at COM.jrockit.vm.RNI.toNative(Native Method)@32520000 at COM.jrockit.vm.RNI.clinitTrampoline(Native Method)@325200FA at com.vms.adbase.jvmcrashtest.SimpleClass.<init>(SimpleClass.java:4)@344B0055 at com.vms.adbase.jvmcrashtest.SimpleClass.main(SimpleClass.java:6)@344B0034 --- End of stack trace Feel free to ask me for further details. JRockit can be downloaded at: http://commerce.bea.com/showallversions.jsp?family=WLJR. I reproduced this error on Windows XP, but it also happend on RedHat. Is it worth adding JRockit to AspectJ's compatibility test suite?
We need to investigate this in the 1.2 timeframe and if it can be fixed in AspectJ tree, do so.
Removed 1.2 milestone and changed priority to P4. This problem is unlikely to be addressed by the core AspectJ developers. However, we would welcome a patch from either BEA or the user community to address this. Rationale follows: AspectJ should always generate legal Java bytecode that can run on any correctly implemented JVM. If you can't run AspectJ generated bytecode then it is likely the result of a bug in your JVM. Any time AspectJ can be shown to generate illegal bytecode that is a high-priority bug and will usually be handled by the core team. I spent this morning fixing one such bug dealing with an interaction between around advice and Java's complicated rules for protected access: https://bugs.eclipse.org/bugs/show_bug.cgi?id=51929. The harder question is what to do about bugs in popular JVMs. These are not bugs in the implementation of AspectJ; however, they can cause problems for AspectJ's users. Your bug report appears to clearly show this as a problem with the JRockit VM and therefore a bug that it is BEA's job to fix. However, when resources are available we do try to fix these bugs on the AspectJ side. I do all of my testing and development work on SUN's JVMs and will develop workarounds to bugs in those VMs if needed (the infamous Miranda methods are one example where we've done this in the past). Several other core AspectJ developers work primarily on IBM's JVMs and will test and develop work-arounds for bugs found in those VMs. We don't currently have any developers who work with JRockit. We would love to accept patches and/or new developers who are focused on JRockit and can improve both testing and work-around any bugs in that platform. I'm also open to contract work to address these kinds of specific low-level challenges (http://hugunin.net/consulting.html) but I'm personally not going to spend my free time dealing with the bugs of yet another JVM.
I just discovered that I was actually running the compiler shipped with the 1.1.6 (development) AJDT release. I am a bit embarrassed. (I hadn't realized that the development AJDT came with a development compiler). Based on Jim’s compatibility stance, I am pursuing this bug with BEA/JRockit and hope that they will either prove that the bytecode is illegal or fix their bug. I'll leave this case open until this bug is fixed by one party or another (unless that's inconvenient).
Nick wrote: >>This means (as far as I know) AspectJ 1.1.1 (as distinct from >>AJDT-packaged-DEV 1.1.6) *does* work with JRockit. (Apologies for earlier >>statement to the contrary.) If you can verify that the AspectJ 1.1.1 generated .class file works ok, and can add both the offending class file and its 1.1.1 equivalent as attachments to this bug that would be very helpful in identifying the likely source of the problem and if nothing else enable us to give the JRocket guys a little more of a clue as to what the problem might be... Thanks, Adrian. -- assigning bug to me as I'm curious enough to do the next level of analysis given the attachments.
Created attachment 8138 [details] Files generated with 1.1.1 compiler: work These files were generated with the 1.1.1 compiler and work as expected (print 3 to standard out when SimpleClass's main is run)
Created attachment 8141 [details] Files generated with DEV compiler: crash These class files were generated with the development version of ajc downloaded in conjunction with AJDT 1.1.6. When I run SimpleClass, JRockit crashes. (Sun 1.4.2 works as expected)
I've attached the two cases, working and non. Thanks for looking into this Adrian.
Looking at the disassembled bytecode, we have the following. In the working case the static initializer looks like this: static {}; Code: 0: invokestatic #12; //Method ajc$postClinit:()V 3: return In the failing case (where we try and cope with exceptions in ajc$postClinit) - it looks like this: static {}; Code: 0: invokestatic #14; //Method ajc$postClinit:()V 3: goto 9 6: putstatic #16; //Field ajc$initFailureCause:Ljava/lang/Throwable; 9: return Exception table: from to target type 0 3 6 Class java/lang/Throwable There is much more logic in it now. But this looks valid and indeed runs in the JVMs in which we've tried it. Interestingly I have two decompilers that cannot make sense of the code in this method. So, now, if we code the Java that is equivalent to what we are trying to achieve: static { try { ajc$postClinit(); } catch (Throwable t) { ajc$initFailureCause = t; } } And compile it with javac, then disassemble that, we have: static {}; Code: 0: invokestatic #10; //Method ajc$postClinit:()V 3: goto 11 6: astore_0 7: aload_0 8: putstatic #6; //Field ajc$initFailureCause:Ljava/lang/Throwable; 11: return Exception table: from to target type 0 3 6 Class java/lang/Throwable Notice the 'extra' astore_0, aload_0. This appears to be a pattern that we aren't following in the code we are generating. If I add the generation of astore and aload to AspectJ then I generate a static initializer that looks just like the one above *and* both of my decompilers can make sense of it and show me what I expect to see. I'm attaching a zip containing a SimpleAspect.class and SimpleClass.class built using my patched AspectJ. Nick, can you possibly try running the classes from that zip on a JRockit JVM? thanks, Andy.
Created attachment 8267 [details] Zip containing class files generated by a patched AspectJ Contains a new SimpleAspect.class and SimpleClass.class - let me know if they work on JRockit. thanks.
Adding myself to cc:
I tested the classes compiled by the patched AspectJ. They passed on both sp1 and sp2 JRockit JVMs. I also had at least two decompilers (cavaj and decafe) crash on SimpleAspect before the patch. They can both digest the class file comfortably now. As far as I'm concerned, this particular bug is fixed--though there may be other instances of similar code generated by AspectJ elsewhere. I'll let you know if we run into any. Test runs: C:\ajtest\simple>\bea\jrockit81sp1_141_03\bin\java -cp . SimpleClass 3 C:\ajtest\simple>\bea\jrockit81sp2_141_05\bin\java -cp . SimpleClass 3
Thanks for testing those classes :) I've just checked the fixes in - they should be available from our brand new best-so-far download process in about 5- 6 hours time. I don't think we've made this kind of change anywhere else in AspectJ in the run up to 1.2 so hopefully all the rest of our generated bytecode will still be working fine in JRockit and the various decompilers.
I'm glad Andy was able to come up with a work-around for this bug in JRockit. I hope that the folks at BEA are still working on fixing this bug in their VM as well. This bug reminds me of another decompiler bug -- #46298. This is another case where AspectJ is generating bytecode that confuses some disassemblers and has to do with exception handlers as well. Nick - If you have the time could you run Ron's test case on JRockit to see if the same problem is present here as well. If so that might raise the priority of fixing that bug.
Fixed by Andy Clement, as per his comment on Mar 02.
updating target flag to indicate inclusion in 1.2 release.