Jacoco — вызвано: java.lang.ClassNotFoundException: org.jacoco.agent.rt.internal_6da5971.Offline

Попытка получить покрытие через jacoco с использованием автономного инструментария (невозможно использовать инструментарий «на лету»: из-за тестовых случаев powermock) для проекта maven. Добавлен jacocoagent.jar в путь к классам в плагине surefire, как показано ниже. Переименовал «org.jacoco.agent-0.7.7.201606060606-runtime.jar» (из локального репозитория maven) в «jacocoagent.jar» и сохранил его в той же папке, где находится этот pom.xml. Я нажимаю ниже исключение даже после добавления его в путь к классам.

фрагмент pom.xml (surefire — конфигурация плагина)

       <plugin>
             <groupId>org.apache.maven.plugins</groupId>
             <artifactId>maven-surefire-plugin</artifactId>
             <configuration>
                     <forkmode>once</forkmode>
                    <additionalClasspathElements>
            <additionalClasspathElement>jacocoagent.jar</additionalClasspathElement>
                                        </additionalClasspathElements>
              </configuration>
     </plugin>

Исключение на консоли:

#############
Number of foreign imports: 1
import: Entry[import  from realm ClassRealm[maven.api, parent: null]]

-----------------------------------------------------

        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:166)
        ... 21 more
Caused by: java.lang.NoClassDefFoundError: org/jacoco/agent/rt/internal_6da5971/Offline
        at com.cisco.ise.ups.modelframework.hibernate.OracleNamingStrategy.$jacocoInit(OracleNamingStrategy.java)
        at com.cisco.ise.ups.modelframework.hibernate.OracleNamingStrategy.<clinit>(OracleNamingStrategy.java)
        at sun.misc.Unsafe.ensureClassInitialized(Native Method)
        at sun.reflect.UnsafeFieldAccessorFactory.newFieldAccessor(UnsafeFieldAccessorFactory.java:43)
        at sun.reflect.ReflectionFactory.newFieldAccessor(ReflectionFactory.java:142)
        at java.lang.reflect.Field.acquireFieldAccessor(Field.java:1082)
        at java.lang.reflect.Field.getFieldAccessor(Field.java:1063)
        at java.lang.reflect.Field.get(Field.java:387)
        at com.cisco.ise.ups.build.WorkflowRunnerMojo.namingStrategyInstance(WorkflowRunnerMojo.java:335)
        at com.cisco.ise.ups.build.WorkflowRunnerMojo.setupWorkflowEnvironment(WorkflowRunnerMojo.java:514)
        at com.cisco.ise.ups.build.WorkflowRunnerMojo.execute(WorkflowRunnerMojo.java:816)
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
        ... 21 more
Caused by: java.lang.ClassNotFoundException: org.jacoco.agent.rt.internal_6da5971.Offline
        at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:50)
        at org.codehaus.plexus.classworlds.realm.ClassRealm.unsynchronizedLoadClass(ClassRealm.java:271)
        at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:247)
        at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:239)
        ... 33 more
[ERROR]
###############

Выполненные действия:

  1. "сборка mvn" .
  2. "mvn org.jacoco:jacoco-maven-plugin:instrument"
  3. «mvn test» — на этом шаге возникло исключение.

Пожалуйста, дайте мне знать, как избавиться от этого исключения? Было ли это правильным местом для добавления пути к классам ?? (в плагине surefire) ИЛИ это должно быть указано где-то??

Спасибо.


person gthy    schedule 16.10.2016    source источник
comment
Бьюсь об заклад, если необходимо добавить библиотеки для тестирования, они должны быть указаны в разделе <dependencies> pom со значением scope=test.   -  person Little Santi    schedule 16.10.2016
comment
@LittleSanti: изменен pom.xml в соответствии с предложением. Тем не менее проблема (исключение) сохраняется. Добавлены эти строки на вкладке «зависимости». ‹dependency› ‹groupId›org.jacoco‹/groupId› ‹artifactId›org.jacoco.agent‹/artifactId› ‹scope›test‹/scope› ‹classifier›runtime‹/classifier› ‹version›0.7.7.201606060606‹/version › ‹/зависимость›. Файл jacocoagent.jar уже загружен и присутствует на диске. Просто нужно сделать это доступным в пути к классам, чтобы инструментальные классы могли его инициировать (eclemma.org/jacoco/trunk/doc/offline.html). Не уверен, чего еще не хватает!!!   -  person gthy    schedule 16.10.2016
comment
Я понимаю. Ну... Другое решение, о котором я думаю, состоит в том, чтобы установить эту зависимость в зависимостях плагина, потому что загрузчик классов плагинов может отличаться от загрузчика классов тестируемого кода.   -  person Little Santi    schedule 16.10.2016
comment
@LittleSanti: в приведенном выше фрагменте кода это уже упоминалось в ‹additionalClasspathElements›. Правильно ? Можете ли вы сказать мне, как добавить путь к классам в maven pom.xml? в основном, в рабочем случае команда выглядит так: (O/P of ps aux | grep java) jre/bin/java -javaagent:/root/.m2/repository/org/jacoco/org.jacoco. agent/0.7.7.201606060606/org.jacoco.agent-0.7.7.201606060606-runtime.jar=destfile=target/jacoco.exec -jar target/surefire/surefirebooter5305632.jar   -  person gthy    schedule 18.10.2016
comment
Единственные известные мне способы добавления jar-файлов в путь к классам в pom.xml — это два упомянутых ранее: узел dependencies и узел plugins/pugin/dependencies.   -  person Little Santi    schedule 18.10.2016


Ответы (2)


Материал classpath в плагине surefire не нужен. Вам нужно добавить зависимость к каждому модулю, имеющему тесты, например:

<dependency>
    <groupId>org.jacoco</groupId>
    <artifactId>org.jacoco.agent</artifactId>
    <classifier>runtime</classifier>
    <scope>test</scope>
    <version>${your.jacoco.version}</version>
</dependency>

Убедитесь, что вы не пропустили часть «классификатор», иначе это не сработает.

Полный пример из проекта PowerMock

person zman0900    schedule 11.08.2017

др. трансовая статья Макфейла о том, как получить Sonar + JaCoCo + PowerMock, помогла мне:

  <!-- Provide information for coverage per test -->
  <profile>
     <id>coverage-per-test</id>
     <build>
        <plugins>
           <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-surefire-plugin</artifactId>
              <version>2.20</version>
              <configuration>
                 <argLine>${argLine} -Xverify:none</argLine>
                 <properties>
                    <property>
                       <name>listener</name>
                       <value>org.sonar.java.jacoco.JUnitListener</value>
                    </property>
                 </properties>
              </configuration>
           </plugin>
        </plugins>
     </build>

     <dependencies>
        <dependency>
           <groupId>org.sonarsource.java</groupId>
           <artifactId>sonar-jacoco-listeners</artifactId>
           <version>4.9.0.9858</version>
           <scope>test</scope>
        </dependency>
     </dependencies>
  </profile>

Как упоминалось в разделе комментариев к сообщению в блоге:

Если ваша argLine по умолчанию не является «простой», вам может понадобиться использовать следующий фрагмент:

{argLine} -XX:-UseSplitVerifier

В противном случае вы можете столкнуться с ClassNotFoundException – например. java.lang.ClassNotFoundException: org.jacoco.agent.rt.RT

person Tihomir Mateev    schedule 17.05.2017