У меня мультипроектная сборка Maven. Я использую Powermock для имитации классов для написания модульных тестов. Итак, чтобы получить покрытие jacoco, я использую автономные инструменты Jacoco и устанавливаю sonar.dynamicAnalysis = reuseReports, чтобы получить покрытие сонара. Когда я пытаюсь это сделать, я получаю ошибки от Jacoco и Sonar:
[INFO] Analysing C:\Program Files (x86)\Jenkins\workspace\Test\target\jacoco.exec
[WARNING] Exception during analysis of file C:\Program Files (x86)\Jenkins\workspace\Test\target\classes\cache\TestClass.class
java.io.IOException: Error while analyzing
C:\Program Files (x86)\Jenkins\workspace\Test\target\classes\cache\TestClass.class
at org.jacoco.core.analysis.Analyzer.analyzerError(Analyzer.java:155)
at org.jacoco.core.analysis.Analyzer.analyzeClass(Analyzer.java:130)
at org.jacoco.core.analysis.Analyzer.analyzeClass(Analyzer.java:147)
at org.sonar.plugins.jacoco.JacocoReportReader.analyzeClassFile(JacocoReportReader.java:139)
at org.sonar.plugins.jacoco.JacocoReportReader.analyzeFiles(JacocoReportReader.java:114)
at org.sonar.plugins.jacoco.AbstractAnalyzer.readExecutionData(AbstractAnalyzer.java:133)
at org.sonar.plugins.jacoco.AbstractAnalyzer.analyse(AbstractAnalyzer.java:102)
at org.sonar.plugins.jacoco.JaCoCoSensor.execute(JaCoCoSensor.java:87)
at org.sonar.scanner.sensor.SensorWrapper.analyse(SensorWrapper.java:53)
at org.sonar.scanner.phases.SensorsExecutor.executeSensor(SensorsExecutor.java:88)
at org.sonar.scanner.phases.SensorsExecutor.execute(SensorsExecutor.java:82)
at org.sonar.scanner.phases.SensorsExecutor.execute(SensorsExecutor.java:68)
at org.sonar.scanner.phases.AbstractPhaseExecutor.execute(AbstractPhaseExecutor.java:88)
at org.sonar.scanner.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:180)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:144)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:129)
at org.sonar.scanner.scan.ProjectScanContainer.scan(ProjectScanContainer.java:286)
at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:281)
at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:279)
at org.sonar.scanner.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:259)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:144)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:129)
at org.sonar.scanner.task.ScanTask.execute(ScanTask.java:48)
at org.sonar.scanner.task.TaskContainer.doAfterStart(TaskContainer.java:84)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:144)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:129)
at org.sonar.scanner.bootstrap.GlobalContainer.executeTask(GlobalContainer.java:121)
at org.sonar.batch.bootstrapper.Batch.doExecuteTask(Batch.java:118)
at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:72)
at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:46)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
at com.sun.proxy.$Proxy19.execute(Unknown Source)
at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:171)
at org.sonarsource.scanner.api.EmbeddedScanner.execute(EmbeddedScanner.java:128)
at org.sonarsource.scanner.maven.bootstrap.ScannerBootstrapper.execute(ScannerBootstrapper.java:63)
at org.sonarsource.scanner.maven.SonarQubeMojo.execute(SonarQubeMojo.java:108)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:132)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:120)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:347)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:154)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:582)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:214)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:158)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
Caused by: java.lang.IllegalStateException:cache\TestClass is already instrumented.
at org.jacoco.core.internal.instr.InstrSupport.assertNotInstrumented(InstrSupport.java:176)
Я не уверен, почему jacoco снова пытается инструментировать класс, чтобы получить покрытие сонара. Я застрял с этой проблемой какое-то время. Любая помощь была бы замечательной.
Пример использования PowerMock с JaCoCo Offline Instrumentation и Maven в нашем репозитории: github.com/powermock/powermock-examples-maven/tree/master/…. Затем вы можете импортировать покрытие в SonarQube любым подходящим способом.
@VaL Я могу получить файл данных, созданный Жакоко. Проблема в том, что в Jenkins, когда я пытаюсь запустить сонар как часть CI, он выдает ошибку. Я не уверен, почему сонар снова пытается инструментировать классы.
@ G.Ann-SonarSourceTeam Версия SonarJava: 4.14.0.11784
Согласно http://www.jacoco.org/jacoco/trunk/doc/instrument-mojo.html:
Performs offline instrumentation. Note that after execution of test you must restore original classes with help of "restore-instrumented-classes" goal.
Сообщение об исключении already instrumented
вводит в заблуждение, но именно это сообщение выдается при попытке проанализировать инструментированные классы вместо исходных.
<execution><id>default-instrument</id><goals> <goal> инструмент </goal> </goals> </ ex ecution> <execution> < id> default-restore-i nstrumented-classes < / id> <goals> <goal> res tore-Instrumented-cl asses </goal> </goals> </execution>. Я также добавил "классы с инструментами восстановления". Я вижу проблему, когда сонар пытается проанализировать файл данных.
Анализ \ target \ jacoco.exec [ВНИМАНИЕ] Исключение при анализе файла \ cache \ TestClass.class. И ошибка вызвана тем, что он снова пытается инструментировать TestClass. Я вижу, что он анализирует jacoco.exec, а затем анализирует целевой класс и пытается его инструментировать.
@FarheeAslam, как разработчик JaCoCo и SonarQube, могу заверить вас, что во время анализа никогда не выполняется контрольно-измерительная аппаратура. Еще раз - сообщение об ошибке и трассировка стека четко указывают на то, что вы пытаетесь анализировать инструментированный класс, тогда как необходимо проанализировать оригинал и все. Безумная догадка - может, вы просто забыли сделать clean
после добавления restore-instrumented-classes
?
В Jenkins я выполняю следующие инструкции: 1) mvn clean install -DskipTests 2) mvn clean test 3) mvn -Psonar org.sonarsource.scanner.maven: sonar-maven-plugin: 3.4.0.905: s onar -Dsonar.projectKey = TestProject. Подскажите, пожалуйста, какой из шагов здесь не так? @Godin
проблема для меня - когда я выполняю третью команду «mvn -Psonar org.sonarsource.scanner.maven: sonar-maven-plugin: 3.4.0.905: s onar -Dsonar.projectKey = TestProject»
@FarheeAslam согласно уже упомянутой документации (jacoco.org/jacoco/trunk/doc/…) restore-instrumented-classes
по умолчанию привязывается к prepare-package
, который идет после test
- см. maven.apache.org/guides/introduction/… Поэтому не выполняется, когда вы выполняете mvn clean test
, и почти уверен, что журналы показывают, что он не выполняется. Это будет выполнено, например, в случае mvn clean verify
.
Я не уверен, что происходит в вашем случае, но мне удалось создать покрытие PowerMock с помощью Jacoco, используя powermock-module-javaagent
.
Только не забудьте поставить powermock agent после jacoco agent:
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<useSystemClassLoader>true</useSystemClassLoader>
<argLine>${jacocoArgLine} -javaagent:${settings.localRepository}/org/powermock/powermock-module-javaagent/${powermock.version}/powermock-module-javaagent-${powermock.version}.jar -noverify</argLine>
...
Если вы хотите увидеть пример, взгляните на этот проект: https://github.com/jfcorugedo/sonar-scanner
Здесь вы можете видеть, что сонар учитывает статические методы и операторы new
, издевательские PowerMock:
Если вы хотите имитировать заявления new
, убедитесь, что вы используете PowerMockRule
вместо PowerMockRunner
.
Взгляните на этот тест
Пожалуйста, редактировать ваш вопрос, чтобы включить версию SonarJava, которая находится в Администрировании -> Marketplace в версиях 6.7+ и в Администрировании -> Система -> Центр обновлений в 6.6 и ниже.