Sie erhalten den Fehler in Bezug auf ClassID. Dies ist ein Konzept, das auf der Docs-Site von JaCoCo detailliert beschrieben wird. http://www.eclemma.org/jacoco/trunk/doc/classids.html. Dies ist ein wichtiger Schritt zur Unterstützung mehrerer Klassenversionen (z. B. eines Anwendungsservers) in derselben JVM.
Kopieren Teil ein Teil davon hier für Sichtbarkeit.
Was sind Klassen-IDs und wie werden sie erstellt?
Klassen-IDs sind 64-Bit-Integer-Werte, zum Beispiel in 0x638e104737889183 hex Notation. Ihre Berechnung gilt als Implementierungsdetail von JaCoCo. Derzeit werden IDs mit einer CRC64-Prüfsumme der rohen Klassendatei erstellt.
Was kann verschiedene Klassen-IDs verursachen?
Klassen-IDs identisch sind für die exakt gleiche Klassendatei nur (Byte-für-Byte). Es gibt einige Gründe, warum Sie verschiedene Klassendateien erhalten könnten. Zuerst kompilieren Java-Quelldateien werden in verschiedenen Klassendateien führen, wenn Sie eine andere Werkzeugkette verwenden:
Verschiedene Compiler-Anbieter (zB Eclipse vs. Oracle JDK)
Verschiedene Compiler-Versionen
Verschiedene Compiler-Einstellungen (zB Debug vs. nicht-debug)
Auch Post-Processing-Klassendateien (Verschleierung, AspectJ, etc.) werden in der Regel die Klassendateien ändern. JaCoCo funktioniert gut, wenn Sie zur Laufzeit und zur Analyse einfach die gleichen Klassendateien verwenden. Daher spielt die Werkzeugkette zum Erstellen dieser Klassendateien keine Rolle.
Auch wenn die Klassendateien im Dateisystem identisch sind, ist es möglich, dass Klassen, die vom JaCoCo-Laufzeit-Agent gesehen werden, sich sowieso unterscheiden. Dies geschieht normalerweise, wenn ein anderer Java-Agent konfiguriert wird, bevor der JaCoCo-Agent oder spezielle Klassenladeprogramme die Klassendateien vorverarbeiten.Typische Kandidaten sind:
- Mocking Frameworks
- Anwendungsserver
- Persistenz-Frameworks
Die gleiche Seite deckt mögliche Lösungen.
Welche Problemumgehungen gibt es, um mit Laufzeit-modifizierten Klassen umzugehen?
Wenn Klassen zur Laufzeit in Ihrem Setup geändert bekommen gibt es einige Workarounds JaCoCo sowieso funktioniert:
- Wenn Sie eine andere Java-Agenten machen verwenden sicher, dass das JaCoCo Mittel zunächst in der Befehlszeile angegeben wird. Auf diese Weise sollte der JaCoCo-Agent die ursprünglichen Klassendateien sehen.
- Geben Sie die Option classdumpdir des JaCoCo-Agenten an und verwenden Sie die dumped-Klassen bei der Berichterstellung. Beachten Sie, dass nur geladene Klassen ausgegeben werden, d. H. Klassen, die überhaupt nicht ausgeführt werden, erscheinen in Ihrem Bericht nicht als nicht abgedeckt.
- Verwenden Sie Offline-Instrumentierung, bevor Sie Ihre Tests ausführen. Auf diese Weise werden Klassen von JaCoCo instrumentiert, bevor irgendeine Laufzeitmodifikation stattfinden kann. Beachten Sie, dass in diesem Fall der Bericht mit den ursprünglichen Klassen generiert werden muss, nicht mit den instrumentierten.
Edited on 22-02-2017
Wie Offline-Instrumentation verwenden: Verwendung unter Aufgabe von Daniel Atallah zur Verfügung gestellt.
//Additional SourceSets can be added to the jacocoOfflineSourceSets as needed by
project.ext.jacocoOfflineSourceSets = [ 'main' ]
task doJacocoOfflineInstrumentation(dependsOn: [ classes, project.configurations.jacocoAnt ]) {
inputs.files classes.outputs.files
File outputDir = new File(project.buildDir, 'instrumentedClasses')
outputs.dir outputDir
doFirst {
project.delete(outputDir)
ant.taskdef(
resource: 'org/jacoco/ant/antlib.xml',
classpath: project.configurations.jacocoAnt.asPath,
uri: 'jacoco'
)
def instrumented = false
jacocoOfflineSourceSets.each { sourceSetName ->
if (file(sourceSets[sourceSetName].output.classesDir).exists()) {
def instrumentedClassedDir = "${outputDir}/${sourceSetName}"
ant.'jacoco:instrument'(destdir: instrumentedClassedDir) {
fileset(dir: sourceSets[sourceSetName].output.classesDir, includes: '**/*.class')
}
//Replace the classes dir in the test classpath with the instrumented one
sourceSets.test.runtimeClasspath -= files(sourceSets[sourceSetName].output.classesDir)
sourceSets.test.runtimeClasspath += files(instrumentedClassedDir)
instrumented = true
}
}
if (instrumented) {
//Disable class verification based on https://github.com/jayway/powermock/issues/375
test.jvmArgs += '-noverify'
}
}
}
test.dependsOn doJacocoOfflineInstrumentation
Jetzt generieren Bericht mit "gradlew test jacocoTestReport"
Befehl.
Hinzufügen, wie Ausführungsdaten ('$ {jacocoexec.filename}') generiert werden? Es sollte ein separates Ziel geben, das die Aufgabe 'jacoco: coverage' ausführt. Stellen Sie dieses Ziel auch in Frage. –
durch Hinzufügen von -javaagent Parameter beim Ausführen von Testfall: -javaagent: JaCoCoProject/lib/jacocoagent.jar = destfile = JaCoCoProject/jacoco.exec, output = Datei – anon
Bitte teilen Sie die vollständige Build-Datei. Alles was der Fehler sagt, ist, dass Sie ein jar instrumentiert haben, Tests ausgeführt haben. Diese Klassen stammen nicht von "./jar/abc.jar". Es ist nicht genug, die Klassen nach Namen zu sortieren. Sie müssen der "classID" von jacoco entsprechen. Das bedeutet, dass die Klassen auch dann unterschiedlich sind, wenn Sie sie neu kompilieren. – Jayan