|
View:
New views
3 Messages
—
Rating Filter:
Alert me
|
|
|
Warnings when instrumenting codeHello everybody.
I've wrote some time back saying that I get a few of "No line number information found for" types of warnings when I instrument my code, even though the code is compiled with debug true. I've done some testing since and I've come up with these partial results: - I've build cobertura from SVN - I'm using the latest 1.5 JDK 1.5.0_21 (I have to use Java 5) - I confirmed that the generated classes contain line numbers by decompiling them with jad and the -lnc option (output original line numbers as comments) - the warnings is generated only for some anonymous inner classes (ie. Foo$1). What makes these inner classes peculiar, is the fact that I can't see why their created. I managed to isolate a case when such inner classes are created (see the attached source) and it seems to be related to non-static inner classes (when I change the classes to "static", the compiler doesn't generate the $1 class any more). - I tried to decompile the $1.class file, however doesn't seem to contain any actual code. My questions would be: - why is the given class generated? - if it doesn't contain any code, would it be possible for cobertura to just skip them rather than issue warnings? Best regards. import java.io.FileInputStream; import java.io.PrintStream; import java.net.Socket; import java.util.*; public class TestMe { class LinkedList { private class ListElement { ListElement nextElement; LinkedList value; } private ListElement head; LinkedList() { head = new ListElement(); head.value = this; ListElement q = head; for (int i = 0; i < 1000; ++i) { q.nextElement = new ListElement(); q = q.nextElement; q.nextElement = null; q.value = this; } } } public static void main(String[] args) throws Exception { } } ------------------------------------------------------------------------------ Come build with us! The BlackBerry(R) Developer Conference in SF, CA is the only developer event you need to attend this year. Jumpstart your developing skills, take BlackBerry mobile applications to market and stay ahead of the curve. Join us from November 9 - 12, 2009. Register now! http://p.sf.net/sfu/devconference _______________________________________________ Cobertura-devel mailing list Cobertura-devel@... https://lists.sourceforge.net/lists/listinfo/cobertura-devel |
|
|
Re: Warnings when instrumenting codeYou are seeing a synthetic class used to bridge access rules with inner classes. You can see what's happening with the standard javap tool using: javap -c -private <classname>
In source you have a private inner class with a default constructor: private class ListElement { ListElement nextElement; LinkedList value; } But, if you examine the bytecode you'll see that ListElement actually has multiple constructors: private TestMe$LinkedList$ListElement(TestMe$LinkedList); Code: 0: aload_0 1: aload_1 2: putfield #2; //Field this$1:LTestMe$LinkedList; 5: aload_0 6: invokespecial #3; //Method java/lang/Object."<init>":()V 9: return TestMe$LinkedList$ListElement(TestMe$LinkedList, TestMe$1); Code: 0: aload_0 1: aload_1 2: invokespecial #1; //Method "<init>":(LTestMe$LinkedList;)V 5: return The constructor that gets the outer class reference is private, so it couldn't be called by LinkedList normally. Instead, a package-private constructor with that dummy class is used. In source, you instantiate with: head = new ListElement(); but in bytecode this is what really happens: 9: aload_0 10: new #3; //class TestMe$LinkedList$ListElement 13: dup 14: aload_0 15: aconst_null 16: invokespecial #4; //Method TestMe$LinkedList$ListElement."<init>":(LTestMe$LinkedList;LTestMe$1;)V 19: putfield #5; //Field head:LTestMe$LinkedList$ListElement; If you aren't used to reading bytecode, the source equivalent (which is not legal of course) would be: head = new ListElement(this, (TestMe$1)null); So, long story short, this can be fixed by changing ClassInstrumenter#visit(...) from: // Do not attempt to instrument interfaces or classes that // have already been instrumented if (((access & Opcodes.ACC_INTERFACE) != 0) || arrayContains(interfaces, hasBeenInstrumented)) { to: // Do not attempt to instrument interfaces, synthetic classes, or classes that // have already been instrumented if (((access & (Opcodes.ACC_INTERFACE | Opcodes.ACC_SYNTHETIC)) != 0) || arrayContains(interfaces, hasBeenInstrumented)) { -Jake 2009/10/21 Balazs Attila-Mihaly (Cd-MaN) <x_at_y_or_z@...> Hello everybody. ------------------------------------------------------------------------------ Come build with us! The BlackBerry(R) Developer Conference in SF, CA is the only developer event you need to attend this year. Jumpstart your developing skills, take BlackBerry mobile applications to market and stay ahead of the curve. Join us from November 9 - 12, 2009. Register now! http://p.sf.net/sfu/devconference _______________________________________________ Cobertura-devel mailing list Cobertura-devel@... https://lists.sourceforge.net/lists/listinfo/cobertura-devel |
|
|
Re: Warnings when instrumenting codeThankyou for the quick and very informative explanation. I've implemented the suggest solution and it works perfectly. I've attached a .patch with it for a committer to apply on the head.
Thanks again. Best regards. ------------------------------------------------------------------------------ Come build with us! The BlackBerry(R) Developer Conference in SF, CA is the only developer event you need to attend this year. Jumpstart your developing skills, take BlackBerry mobile applications to market and stay ahead of the curve. Join us from November 9 - 12, 2009. Register now! http://p.sf.net/sfu/devconference _______________________________________________ Cobertura-devel mailing list Cobertura-devel@... https://lists.sourceforge.net/lists/listinfo/cobertura-devel |
| Free embeddable forum powered by Nabble | Forum Help |