Using the IntelliJ decompiler for one instance shows:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.mkobit.libraryexample;

import com.cloudbees.groovy.cps.Builder;
import com.cloudbees.groovy.cps.MethodLocation;
import com.cloudbees.groovy.cps.NonCPS;
import com.cloudbees.groovy.cps.WorkflowTransformed;
import com.cloudbees.groovy.cps.impl.CpsCallableInvocation;
import com.cloudbees.groovy.cps.impl.CpsFunction;
import com.cloudbees.groovy.cps.sandbox.Trusted;
import com.mkobit.libraryexample.ExampleSrc._nonCpsDouble_closure1;
import groovy.lang.GroovyObject;
import groovy.lang.MetaClass;
import java.io.Serializable;
import java.util.List;
import java.util.Objects;
import org.codehaus.groovy.runtime.ArrayUtil;
import org.codehaus.groovy.runtime.ScriptBytecodeAdapter;
import org.codehaus.groovy.runtime.callsite.CallSite;
import org.jenkinsci.plugins.workflow.cps.CpsClosure2;
import org.jenkinsci.plugins.workflow.cps.Safepoint;

@WorkflowTransformed
public class ExampleSrc implements Serializable, GroovyObject {
  private final Object script;
  private static final CpsFunction ___cps___0;
  private static long __timeStamp;

  public ExampleSrc(Object script) {
    CallSite[] var2 = $getCallSiteArray();
    MetaClass var3 = this.$getStaticMetaClass();
    this.metaClass = var3;
    Object var4 = var2[0].call(Objects.class, script);
    this.script = var4;
  }

  @WorkflowTransformed
  public void sayHelloTo(String name) {
    CallSite[] var2 = $getCallSiteArray();
    throw (Throwable)var2[1].callConstructor(CpsCallableInvocation.class,
___cps___0, this, new Object[]{name});
  }

  @NonCPS
  public List<Integer> nonCpsDouble(List<Integer> integers) {
    CallSite[] var2 = $getCallSiteArray();
    return (List)ScriptBytecodeAdapter.castToType(var2[2].call(integers,
new _nonCpsDouble_closure1(this, this)), List.class);
  }

  @WorkflowTransformed
  private static final CpsFunction ___cps___0() {
    CallSite[] var0 = $getCallSiteArray();
    Builder b =
(Builder)ScriptBytecodeAdapter.castToType(var0[3].call(var0[4].call(var0[5].callConstructor(Builder.class,
var0[6].callConstructor(MethodLocation.class,
"com.mkobit.libraryexample.ExampleSrc", "sayHelloTo",
"/tmp/jenkinsTests.tmp/jenkins1133211585081614104test/jobs/project/builds/1/libs/testLibrary/src/com/mkobit/libraryexample/ExampleSrc.groovy")),
CpsClosure2.class), var0[7].callGetProperty(Trusted.class)),
Builder.class);
    return 
(CpsFunction)ScriptBytecodeAdapter.castToType(var0[8].callConstructor(CpsFunction.class,
ScriptBytecodeAdapter.createList(new Object[]{"name"}),
var0[9].call(b, var0[10].call(b, 14, Safepoint.class, "safepoint"),
var0[11].call(b, var0[12].call(b, ArrayUtil.createArray(14,
var0[13].call(b, 14, var0[14].call(b), "script"), var0[15].call(b,
"echo"), false, var0[16].call(b, 14, var0[17].call(b, var0[18].call(b,
14, "name")), var0[19].call(b, var0[20].call(b, "Hello there "),
var0[21].call(b, "")))))))), CpsFunction.class);
  }

  static {
    Long var0 = 0L;
    __timeStamp = var0;
    Object var1 = $getCallSiteArray()[22].callStatic(ExampleSrc.class);
    ___cps___0 = (CpsFunction)ScriptBytecodeAdapter.castToType(var1,
CpsFunction.class);
  }
}


And other class file:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.mkobit.libraryexample;

import com.cloudbees.groovy.cps.Builder;
import com.cloudbees.groovy.cps.MethodLocation;
import com.cloudbees.groovy.cps.NonCPS;
import com.cloudbees.groovy.cps.WorkflowTransformed;
import com.cloudbees.groovy.cps.impl.CpsCallableInvocation;
import com.cloudbees.groovy.cps.impl.CpsFunction;
import com.cloudbees.groovy.cps.sandbox.Trusted;
import com.mkobit.libraryexample.ExampleSrc._nonCpsDouble_closure1;
import groovy.lang.GroovyObject;
import groovy.lang.MetaClass;
import java.io.Serializable;
import java.util.List;
import java.util.Objects;
import org.codehaus.groovy.runtime.ArrayUtil;
import org.codehaus.groovy.runtime.ScriptBytecodeAdapter;
import org.codehaus.groovy.runtime.callsite.CallSite;
import org.jenkinsci.plugins.workflow.cps.CpsClosure2;
import org.jenkinsci.plugins.workflow.cps.Safepoint;

@WorkflowTransformed
public class ExampleSrc implements Serializable, GroovyObject {
  private final Object script;
  private static final CpsFunction ___cps___3;
  private static long __timeStamp;

  public ExampleSrc(Object script) {
    CallSite[] var2 = $getCallSiteArray();
    MetaClass var3 = this.$getStaticMetaClass();
    this.metaClass = var3;
    Object var4 = var2[0].call(Objects.class, script);
    this.script = var4;
  }

  @WorkflowTransformed
  public void sayHelloTo(String name) {
    CallSite[] var2 = $getCallSiteArray();
    throw (Throwable)var2[1].callConstructor(CpsCallableInvocation.class,
___cps___3, this, new Object[]{name});
  }

  @NonCPS
  public List<Integer> nonCpsDouble(List<Integer> integers) {
    CallSite[] var2 = $getCallSiteArray();
    return (List)ScriptBytecodeAdapter.castToType(var2[2].call(integers,
new _nonCpsDouble_closure1(this, this)), List.class);
  }

  @WorkflowTransformed
  private static final CpsFunction ___cps___3() {
    CallSite[] var0 = $getCallSiteArray();
    Builder b =
(Builder)ScriptBytecodeAdapter.castToType(var0[3].call(var0[4].call(var0[5].callConstructor(Builder.class,
var0[6].callConstructor(MethodLocation.class,
"com.mkobit.libraryexample.ExampleSrc", "sayHelloTo",
"/tmp/jenkinsTests.tmp/jenkins8402738745313950554test/jobs/project/builds/1/libs/testLibrary/src/com/mkobit/libraryexample/ExampleSrc.groovy")),
CpsClosure2.class), var0[7].callGetProperty(Trusted.class)),
Builder.class);
    return 
(CpsFunction)ScriptBytecodeAdapter.castToType(var0[8].callConstructor(CpsFunction.class,
ScriptBytecodeAdapter.createList(new Object[]{"name"}),
var0[9].call(b, var0[10].call(b, 14, Safepoint.class, "safepoint"),
var0[11].call(b, var0[12].call(b, ArrayUtil.createArray(14,
var0[13].call(b, 14, var0[14].call(b), "script"), var0[15].call(b,
"echo"), false, var0[16].call(b, 14, var0[17].call(b, var0[18].call(b,
14, "name")), var0[19].call(b, var0[20].call(b, "Hello there "),
var0[21].call(b, "")))))))), CpsFunction.class);
  }

  static {
    Long var0 = 0L;
    __timeStamp = var0;
    Object var1 = $getCallSiteArray()[22].callStatic(ExampleSrc.class);
    ___cps___3 = (CpsFunction)ScriptBytecodeAdapter.castToType(var1,
CpsFunction.class);
  }
}


Comparing the two together in IntelliJ only really shows that a view names
and a path are different. This seems to be due to some specifics of how the
Jenkins Groovy compilation is working under the hood, but I don't know
enough about how it works to say exactly what it is doing.

Here is the diff when using javap, which basically shows the same thing: *diff
<(/usr/lib/jvm/java-8-oracle/bin/javap -p -c
build/jacoco/classpathdumps/com/mkobit/libraryexample/ExampleSrc.3c0445a9d0628854.class)
<(/usr/lib/jvm/java-8-oracle/bin/javap -p -c
build/jacoco/classpathdumps/com/mkobit/libraryexample/ExampleSrc.99203068b63d74ec.class)*
:

5c5
<   private static final com.cloudbees.groovy.cps.impl.CpsFunction
___cps___0;
---
>   private static final com.cloudbees.groovy.cps.impl.CpsFunction
___cps___3;
55c55
<       10: getstatic     #57                 // Field
___cps___0:Lcom/cloudbees/groovy/cps/impl/CpsFunction;
---
>       10: getstatic     #57                 // Field
___cps___3:Lcom/cloudbees/groovy/cps/impl/CpsFunction;
89c89
<   private static final com.cloudbees.groovy.cps.impl.CpsFunction
___cps___0();
---
>   private static final com.cloudbees.groovy.cps.impl.CpsFunction
___cps___3();
109c109
<       28: ldc           #98                 // String
/tmp/jenkinsTests.tmp/jenkins1133211585081614104test/jobs/project/builds/1/libs/testLibrary/src/com/mkobit/libraryexample/ExampleSrc.groovy
---
>       28: ldc           #98                 // String
/tmp/jenkinsTests.tmp/jenkins8402738745313950554test/jobs/project/builds/1/libs/testLibrary/src/com/mkobit/libraryexample/ExampleSrc.groovy
325c325
<       37: putstatic     #57                 // Field
___cps___0:Lcom/cloudbees/groovy/cps/impl/CpsFunction;
---
>       37: putstatic     #57                 // Field
___cps___3:Lcom/cloudbees/groovy/cps/impl/CpsFunction;
422c422
<      142: ldc_w         #263                // String ___cps___0
---
>      142: ldc_w         #263                // String ___cps___3

On Sun, Feb 18, 2018 at 2:51 PM Marc Hoffmann <hoffm...@mountainminds.com>
wrote:

> Hi,
>
> do you have an idea what is the actual difference between the class
> files?
>
> You can decompile the different class versions with javap -p -c and diff
> the result.
>
> Regards,
> -marc
>
>
> On 2018-02-17 00:21, mko...@gmail.com wrote:
> > I'm working on a Gradle plugin
> > (
> https://github.com/mkobit/jenkins-pipeline-shared-libraries-gradle-plugin)
> > that makes it simple to build and test Jenkins Shared Libraries.
> > Jenkins Shared Libraries operate on source code instead of compiled
> > code. Jenkins itself embeds Groovy for compilation of various pipeline
> > scripts. It performs some manipulations before execution. The code
> > that comes out seems to be deterministic from what I can tell.
> >
> > I am trying to figure out a way to coverage for these source Groovy
> > files when they are compiled and executed in a Jenkins runtime. I've
> > documented my journey so far in
> >
> https://github.com/mkobit/jenkins-pipeline-shared-libraries-gradle-plugin/issues/32
> > but here is a summary of where I am currently at:
> >
> >
> > * I can get execution data for the classes
> > * Dumping classpath shows multiple instances of the library classes (1
> > per test they are used in)
> > * Attempting to get a report fails with
> > `java.lang.IllegalStateException: Can't add different class with same
> > name: com/mkobit/libraryexample/ExampleSrc`. There are a few other
> > duplicates as well
> > * Filtering down the report to only a single specific file allows me
> > to generate a coverage report, but I only get it for the test was
> > filtered
> > (
> https://github.com/mkobit/jenkins-pipeline-shared-libraries-gradle-plugin/issues/32#issuecomment-366371128
> )
> >
> > What I want to try and figure out is, what is the right way forward to
> > "merge" the execution data together for the original source file? It
> > sounds similar-ish to https://github.com/jacoco/jacoco/issues/197 so
> > I'll add a comment there as well.
> >
> > Here are some reproduction steps:
> >
> > 1. `git clone -b 'mk/coverage-investigation'
> > https://github.com/mkobit/jenkins-pipeline-shared-library-example.git`
> <https://github.com/mkobit/jenkins-pipeline-shared-library-example.git>
> > 2. `cd jenkins-pipeline-shared-library-example`
> > 3. `./gradlew integrationTest jacocoIntegrationTestReport -s ==> See
> > error mentioned above about duplicate classnames
> > 4. `find
> > build/jacoco/classpathdumps/com/mkobit/libraryexample/ExampleSrc.* |
> > head -n 1 | xargs -n 1 basename` ==> this will get one of the classes.
> > for me this time, it was "ExampleSrc.99203068b63d74ec.class"
> > 5. Replace the class name at
> >
> https://github.com/mkobit/jenkins-pipeline-shared-library-example/blob/6d268d56c86c626312bc76a9e00051c5749c28d1/build.gradle.kts#L52
> > with the class name above and uncomment the line
> > 6. `./gradlew jacocoIntegrationTestReport` ==> Generate report for
> > single class
> > 7. Open HTML report at
> > build/reports/jacoco/jacocoIntegrationTestReport/html/index.html and
> > see results for class
> > 8. find
> > build/jacoco/classpathdumps/com/mkobit/libraryexample/ExampleSrc.* |
> > tail -n 1 | xargs -n 1 basename ==> get name for other class
> > 9. Repeat steps 4-7 with result from other class to see different
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "JaCoCo and EclEmma Users" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/jacoco/-zTg9Bt5964/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> jacoco+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/jacoco/ebabe3aff26f96248b1994370f627290%40mountainminds.com
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jacoco/CALELY9HB0ceYR%3DWve2jYuG2zMV9KomJr1YFnWtP7h8gEubAyLg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to