Сбой тестов Tycho из-за ошибки java.lang.NoClassDefFoundError: junit/framework/AssertionFailedError

Я совершенно смущен и ошеломлен этим. В моем понимании, это должно работать, но я не знаю, почему.

У меня есть сборка Tycho, которая просто запускает несколько тестов в рабочей среде eclipse. Однако все мои тесты терпят неудачу с таким исключением:

java.lang.NoClassDefFoundError: junit/framework/AssertionFailedError
at org.grails.ide.eclipse.commands.test.AbstractCommandTest.tearDown(AbstractCommandTest.java:112)
at junit.framework.TestCase.runBare(TestCase.java:140)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:243)
at junit.framework.TestSuite.run(TestSuite.java:238)
at junit.framework.TestSuite.runTest(TestSuite.java:243)
at junit.framework.TestSuite.run(TestSuite.java:238)
at org.springsource.ide.eclipse.commons.tests.util.ManagedTestSuite.run(ManagedTestSuite.java:231)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175)
at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:123)
at org.eclipse.tycho.surefire.osgibooter.OsgiSurefireBooter.run(OsgiSurefireBooter.java:84)
at org.eclipse.tycho.surefire.osgibooter.AbstractUITestApplication$1.run(AbstractUITestApplication.java:35)
at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3529)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3182)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1022)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:916)
at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:86)
at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:585)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:540)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:124)
at org.eclipse.tycho.surefire.osgibooter.UITestApplication.runApplication(UITestApplication.java:31)
at org.eclipse.tycho.surefire.osgibooter.AbstractUITestApplication.run(AbstractUITestApplication.java:114)
at org.eclipse.tycho.surefire.osgibooter.UITestApplication.start(UITestApplication.java:37)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:353)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:180)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:629)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:584)
at org.eclipse.equinox.launcher.Main.run(Main.java:1438)
at org.eclipse.equinox.launcher.Main.main(Main.java:1414)

Caused by: java.lang.ClassNotFoundException: junit.framework.AssertionFailedError
at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:501)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:421)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:412)
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
... 54 more

Это не имеет смысла для меня. org.junit и org.junit4 являются зависимостями пакета, выполняющего тесты, а также пакета, содержащего AbstractCommandTest. Эти тесты проходят при запуске в моем рабочем пространстве, так почему же maven/tycho не может загрузить классы junit?

Я буду рад предоставить дополнительную информацию, например, ссылку на репозиторий github, если это поможет.


РЕДАКТИРОВАТЬ: Предоставление более подробной информации

Репозиторий github находится здесь: https://github.com/grails/grails-sts-tests

Вы можете видеть, что это простой плагин, который просто запускает некоторые тесты. Набор тестов состоит из тестов, поступающих от плагинов в других репозиториях, которые указаны как зависимости. Обратите внимание, что тестовые плагины, расположенные в других репозиториях, запускаются на другом сервере CI и не имеют проблемы NoClassDefFoundError. Я взглянул на другой CI-сервер и не заметил ничего другого (к сожалению, этот CI-сервер не находится в открытом доступе, поэтому я не могу поделиться ссылкой на него).

Задание сборки hudson, показывающее проблему, находится здесь: http://hudson.grails.org/job/grails-sts-tests-2.0.x/17/console


person Andrew Eisenberg    schedule 06.07.2012    source источник
comment
Пожалуйста, попробуйте предоставить более подробную информацию о том, как вы настроили Tycho/тестовые проекты. По моему опыту, ошибки сборки в Tycho чаще возникают из-за незначительного непонимания модели подключаемых модулей по умолчанию.   -  person Zoltán Ujhelyi    schedule 10.07.2012
comment
Спасибо. Предоставление более подробной информации.   -  person Andrew Eisenberg    schedule 10.07.2012
comment
java.lang.NoClassDefFoundError вызывается всякий раз, когда зависимость класса не найдена или не может быть загружена. Поскольку вы говорите, что плагины компилируются на другом сервере CI, я подозреваю, что он работает на другой версии JVM. Можете ли вы вставить полную трассировку стека?   -  person melix    schedule 10.07.2012
comment
Это происходит при тестировании всего проекта или одного класса?   -  person Doszi89    schedule 10.07.2012
comment
@melix Я добавил полную трассировку стека. Это не очень интересно. Класс JUnit находится где-то в пути к классам, но загрузчик классов для тестового пакета не может его загрузить. Это проблема OSGi, и я не уверен, почему это происходит, поскольку для моих тестовых пакетов требуются пакеты JUnit.   -  person Andrew Eisenberg    schedule 10.07.2012
comment
@Doszi89 Doszi89 Это происходит для каждого теста JUnit, который я запускаю, и он всегда выдает ошибку в одном и том же классе.   -  person Andrew Eisenberg    schedule 10.07.2012


Ответы (4)


У нас были очень похожие проблемы. Причина в том, что инфраструктура junit пытается создать и использовать собственный загрузчик классов, и это не очень хорошо работает с загрузчиками классов плагинов eclipse. Есть некоторые рекомендации по запуску модульных тестов с Tycho, которым мы сейчас следуем.

  1. Ваши модульные тесты находятся во фрагменте плагина. Фрагмент модульного теста зависит от JUnit.
  2. ваш pom должен отключить использование загрузчика системных классов для модульных тестов. Это то, что приводит к потере тестовых классов junit.
  3. Затем вы используете ту же упаковку, что и стандартный плагин (если быть точным, eclipse-plugin).

Итак, простой POM (для нас) выглядит так:

<?xml version="1.0" encoding="UTF-8"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <artifactId>master</artifactId>
    <groupId>mgws</groupId>
    <version>0.0.1-SNAPSHOT</version>
    <relativePath>../../mgws/build-environment/pom.xml</relativePath>
  </parent>
  <groupId>mgws</groupId>
  <artifactId>mgws.spectral.test</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>eclipse-plugin</packaging>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.12</version>
        <executions>
          <execution>
            <id>JUnitTest</id>
            <goals>
              <goal>test</goal>
            </goals>
            <phase>install</phase>
            <configuration>
              <useSystemClassLoader>false</useSystemClassLoader>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

Это заставляет среду модульного тестирования использовать загрузчики классов плагинов eclipse, и теперь она находит все классы.

person Zagrev    schedule 10.07.2012
comment
Я удивлен этим. Почему вы не запускаете свои тесты с помощью плагина tycho-surefire? Раздел конфигурации плагина tycho-surefire выглядит совсем иначе. Но спасибо за подсказку по использованию SystemClassLoader. Я пробую это прямо сейчас. - person Andrew Eisenberg; 11.07.2012
comment
У нас было требование запускать модульные тесты как тесты без плагинов. Не помню почему, прошло несколько лет. - person Zagrev; 11.07.2012
comment
Мне пришлось добавить это в конфигурацию, чтобы запустить тесты: ‹testClassesDirectory›target/classes‹/testClassesDirectory› - person Max Hohenegger; 27.11.2017

Вещи, которые я бы сделал, чтобы проверить:

  1. Проверьте причину NoClassDefFoundError. Существуют различные причины, такие как UnSupportedClassVersionError и ExceptionINinitializationError, которые являются наиболее распространенными.
  2. Используйте параметр JVM -verbose:class, чтобы получить журналы загрузки классов и проверить, загружаются ли классы из ожидаемых артефактов для требуемых классов.
person Suraj Chandran    schedule 09.07.2012
comment
OSGi выдает ошибку NoClassDefFoundError, поскольку класс не может быть найден в загрузчике классов для тестового пакета. Я только что добавил параметр -verbose:class и просматриваю журналы. Пока ничего особо интересного... - person Andrew Eisenberg; 10.07.2012

Я столкнулся с аналогичной проблемой при запуске тестов junit в проекте Android, который зависел от нескольких сторонних jar-файлов, и проблема заключалась в том, что один из зависимых jar-файлов был построен с помощью jdk v1.5, а все остальное было 1.6. Я обновил одну библиотеку до более новой версии, которая была собрана с 1.6, после чего ошибка исчезла.

Не знаю, та же ли это проблема, или вы можете настроить ее или обновить, но, возможно, стоит посмотреть .....

person Ovi Tisler    schedule 10.07.2012

До сих пор никто не может ответить на вопрос, но спасибо за информацию, даже если она не была непосредственно полезной.

Я добился определенного прогресса. Сейчас у меня 45 из 60 тестов. Я просто добавил несколько дополнительных зависимостей, подобных этой, в область конфигурации tycho-surefire-pluign:

                <dependencies>
                    <dependency>
                        <type>p2-installable-unit</type>
                        <artifactId>org.junit</artifactId>
                        <version>0.0.0</version>
                    </dependency>
                    ...
                </dependencies>

К сожалению, остальные тесты по-прежнему не работают с тем же NoClassDefFoundError. Возможно, мне нужно добавить еще какие-то зависимости и все будет работать.

person Andrew Eisenberg    schedule 17.07.2012