something strange in $jacocoInit(),hope someone can explain

44 views
Skip to first unread message

dazhe...@gmail.com

unread,
Sep 14, 2020, 10:05:54 AM9/14/20
to JaCoCo and EclEmma Users
hey,guys~

   I checked the generated probe code,which is the $jacocoInit$() method. 
private static /* synthetic */ boolean[] $jacocoInit() {
            boolean[] arrbl = $jacocoData;
            if ($jacocoData == null) {
                Object[] arrobject = new Object[]{-4939888610684879937L, "org/jacoco/examples/CoreTutorial$MemoryClassLoader", 6};
                UnknownError.$jacocoAccess.equals(arrobject);
                arrbl = $jacocoData = (boolean[])arrobject[0];
            }
            return arrbl;
        }

When I saw the code   
arrbl = $jacocoData = (boolean[])arrobject[0];

I was really confused.Why a variable of type "long" can be cast to a boolean array type? So I did a test:
public class TestJacocoInit {
    private static transient /* synthetic */ boolean[] $jacocoData;

   
public static /* synthetic */ boolean[] $jacocoInit() {
        boolean[] arrbl = $jacocoData;
       
if ($jacocoData == null) {
            Object[] arrobject = new Object[]{4824536285859479710L, "org/jacoco/examples/CoreTutorial$TestTarget", 6};
           
//UnknownError.$jacocoAccess.equals(arrobject);
            arrbl
= $jacocoData = (boolean[])arrobject[0];
       
}
        return arrbl;
   
}

    public static void main(String[] args){
        $jacocoInit();
   
}
}

The program occured error when executed:

objc[25273]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/bin/java (0x10bd1e4c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x10ddc04e0). One of the two will be used. Which one is undefined.
Connected to the target VM, address: '127.0.0.1:54961', transport: 'socket'
Exception in thread "main" java.lang.ClassCastException: java.lang.Long cannot be cast to [Z
at org.jacoco.examples.TestJacocoInit.$jacocoInit(TestJacocoInit.java:16)
at org.jacoco.examples.TestJacocoInit.main(TestJacocoInit.java:22)
Disconnected from the target VM, address: '127.0.0.1:54961', transport: 'socket'



Can somebody explain these jacoco generated codes?


Thanks~

zhen da

unread,
Sep 14, 2020, 10:22:38 AM9/14/20
to JaCoCo and EclEmma Users
https://www.jacoco.org/jacoco/trunk/doc/implementation.html
I found the error occured because I deleted the codeline "UnknownError.$jacocoAccess.equals(arrobject);", but what happend behind the equals method?

Marc Hoffmann

unread,
Sep 14, 2020, 3:43:03 PM9/14/20
to jac...@googlegroups.com
Hi,

we use the equals method as an “API” to the JaCoCo runtime. See “Coverage Runtime Dependency” here: https://www.jacoco.org/jacoco/trunk/doc/implementation.html

Regards,
-marc




--
You received this message because you are subscribed to the Google Groups "JaCoCo and EclEmma Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jacoco+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jacoco/2bceb343-d07c-4905-b8b8-71ff901acd93n%40googlegroups.com.

zhen da

unread,
Sep 20, 2020, 11:18:49 PM9/20/20
to JaCoCo and EclEmma Users
Thank your for your reply~ Recently I have been studied the original code.  I read the page " https://www.jacoco.org/jacoco/trunk/doc/implementation.html" , but  I noticed the most tricky part is not shown  in "Coverage RunTime Dependency" section. I still confused about the equals method. 
So Question 1 is: When the code "access.equals(args)"  is executed, what happenned on earth?Could you explain it in detail please?

//begin
Object access = ... // Retrieve instance

Object[] args = new Object[3];
args[0] = Long.valueOf(8060044182221863588); // class id
args[1] = "com/example/MyClass"; // class name
args[2] = Integer.valueOf(24); // probe count

access.equals(args);
boolean[] probes = (boolean[]) args[0];
//end

 By the way, I found there is an equals method overridden in class  RuntimeData, but  I  couldn't find the place it called. I don't think it has something to do with the call  "access.equals(args);"  , because   the variable "access" is not an instance fo RunTimeData.
So Question 2 is : Where and When will the RunTimeData.equals() method be called?

Regards,

Marc Hoffmann

unread,
Sep 21, 2020, 3:05:44 AM9/21/20
to jac...@googlegroups.com
Hi,

Answer 1:

The method RuntimeData.equals() will be called. You find the implementation here: https://github.com/jacoco/jacoco/blob/master/org.jacoco.core/src/org/jacoco/core/runtime/RuntimeData.java#L161

Answer 2:

Instrumented classes will call equals() on a instance of RuntimeData. There are different strategies to get access to a instance shared with the runtime.


It is described in https://www.jacoco.org/jacoco/trunk/doc/implementation.html in section “Coverage Runtime Dependency”.

We do this “magic” to avoid direct dependencies on JaCoCo classes from instrumented classes which will fail in situations where app classes are separated with a different class loader.

Regards,
-marc


Reply all
Reply to author
Forward
0 new messages