NoClassDefFoundError с Gradle, Giraph и Hadoop

Итак, я много искал и не нашел хорошего ответа на свой вопрос, и это сводит меня с ума, поэтому я решил спросить здесь и, надеюсь, смогу получить помощь. Я пытаюсь провести автоматическое тестирование в проекте Giraph, используя gradle. Я новичок в Gradle. Просто для начала я скопировал тестовый код для класса SimpleShortestPathComputation в свой проект, чтобы убедиться, что я могу запустить тесты. Однако, когда я делаю gradle test, я получаю следующую ошибку:

$ gradle test --info
<skipping some output here...>

Successfully started process 'Gradle Test Executor 1'
Gradle Test Executor 1 started executing tests.
WCCTest > testToyData FAILED
    java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
        at org.apache.hadoop.conf.Configuration.<clinit>(Configuration.java:142)
        at WCCTest.testToyData(WCCTest.java:180)

    Caused by:
    java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
        at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
        ... 2 more

Gradle Test Executor 1 finished executing tests.
WCCTest > testOnShorterPathFound FAILED
    java.lang.NoClassDefFoundError: org.apache.hadoop.conf.Configuration
        at sun.reflect.GeneratedSerializationConstructorAccessor33.newInstance(Unknown Source)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
        at     org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:40)
        at org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:59)
        at org.mockito.internal.creation.jmock.ClassImposterizer.createProxy(ClassImposterizer.java:128)
        at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:63)
        at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:56)
        at org.mockito.internal.creation.CglibMockMaker.createMock(CglibMockMaker.java:23)
        at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:26)
        at org.mockito.internal.MockitoCore.mock(MockitoCore.java:51)
        at org.mockito.Mockito.mock(Mockito.java:1243)
        at org.mockito.Mockito.mock(Mockito.java:1120)
        at org.apache.giraph.utils.MockUtils$MockedEnvironment.<init>(MockUtils.java:68)
        at org.apache.giraph.utils.MockUtils.prepareVertexAndComputation(MockUtils.java:132)
        at WCCTest.testOnShorterPathFound(WCCTest.java:64)

WCCTest > testToyDataJson FAILED
    java.lang.NoClassDefFoundError: Could not initialize class org.apache.giraph.conf.GiraphConfiguration
        at WCCTest.testToyDataJson(WCCTest.java:127)

WCCTest > testOnNoShorterPathFound FAILED
    java.lang.NoClassDefFoundError: org.apache.hadoop.conf.Configuration
        at sun.reflect.GeneratedSerializationConstructorAccessor33.newInstance(Unknown Source)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
        at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:40)
        at org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:59)
        at org.mockito.internal.creation.jmock.ClassImposterizer.createProxy(ClassImposterizer.java:128)
        at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:63)
        at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:56)
        at org.mockito.internal.creation.CglibMockMaker.createMock(CglibMockMaker.java:23)
        at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:26)
        at org.mockito.internal.MockitoCore.mock(MockitoCore.java:51)
        at org.mockito.Mockito.mock(Mockito.java:1243)
        at org.mockito.Mockito.mock(Mockito.java:1120)
        at org.apache.giraph.utils.MockUtils$MockedEnvironment.<init>(MockUtils.java:68)
        at org.apache.giraph.utils.MockUtils.prepareVertexAndComputation(MockUtils.java:132)
        at WCCTest.testOnNoShorterPathFound(WCCTest.java:95)

4 tests completed, 4 failed
<more output...>
:test FAILED
:test (Thread[main,5,main]) completed. Took 1.663 secs.

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':test'.
> There were failing tests. See the report at: file:///...build/reports/tests/index.html

BUILD FAILED

Я использую полностью стандартную структуру каталогов проекта, и это мой файл build.gradle:

apply plugin: 'java'

repositories {
    mavenCentral()
}

dependencies {
    compile files('$GIRAPH_HOME/giraph-core/target/giraph-1.1.0-SNAPSHOT-for-hadoop-0.20.203.0-jar-with-dependencies.jar')
    compile files('$GIRAPH_HOME/giraph-examples/target/giraph-examples-1.1.0-SNAPSHOT-for-hadoop-0.20.203.0-jar-with-dependencies.jar')
    compile files('$HADOOP_HOME/hadoop-core-0.20.203.0.jar')

    testCompile group: 'junit', name: 'junit', version: '4.+'
    testCompile group: 'org.mockito', name: 'mockito-all', version: '1.9.5'
}

Он компилируется без проблем, и файлы jar, которые я включаю в качестве зависимостей, включают классы, для которых указано NoClassDefFoundError (согласно jar tf). Любые идеи, что я делаю неправильно? Заранее спасибо.


person Matthew Saltz    schedule 07.07.2014    source источник


Ответы (2)


попробуйте добавить следующее в свой build.gradle

    println("HADOOP_HOME=$HADOOP_HOME")
    compile files("$HADOOP_HOME/hadoop-core-0.20.203.0.jar")
    println("System.env.HADOOP_HOME=$System.env.HADOOP_HOME")
    compile files("$System.env.HADOOP_HOME/hadoop-core-0.20.203.0.jar")
person Bill Lin    schedule 07.07.2014
comment
Эй, спасибо за помощь. Итак, на самом деле: $ jar tf hadoop-core-0.20.203.0.jar | grep Configur выводит: org/apache/hadoop/conf/Configurable.class org/apache/hadoop/conf/Configuration$1.class org/apache/hadoop/conf/Configuration$IntegerRanges$Range.class org/apache/hadoop/conf/Configuration$IntegerRanges.class org/apache/hadoop/conf/Configuration.class Плюс еще кое-что. Также, когда я использую эту группу компиляции, я получаю другие ошибки: java.lang.ClassNotFoundException: org.apache.commons.configuration.Configuration javax.security.auth.login.LoginException: java.lang.NoClassDefFoundErroretc - person Matthew Saltz; 08.07.2014
comment
Не уверен в соблюдении этикета, должен ли я добавить полный новый вывод в исходный пост? - person Matthew Saltz; 08.07.2014
comment
Кроме того, не могли бы вы рассказать об использовании $HADOOP_HOME? Вы имеете в виду, что вот так поместите это внутрь compile files($HADOOP_HOME)? Если я это сделаю, кажется, что он вообще ничего не включает, и я все равно должен включить основную банку. Я очень ценю помощь, кстати - person Matthew Saltz; 08.07.2014
comment
Извините, мой предыдущий ответ неверен. Я обновил свой ответ. Не могли бы вы попробовать? обратите внимание: используйте двойные кавычки, а не одинарные - person Bill Lin; 08.07.2014
comment
Что ж, для первых двух строк HADOOP_HOME не определено (я просто добавил это в код своего примера, чтобы скрыть фактический путь в моей файловой системе). Вторые две строки работают, но это просто дает то же самое, что у меня уже было, поэтому я получаю те же ошибки. - person Matthew Saltz; 08.07.2014
comment
Вы можете попробовать использовать org.apache.hadoop.conf.Configuration где-нибудь в своем Java-коде, чтобы увидеть, компилируется ли он? Я чувствую, что это не так - person Bill Lin; 08.07.2014
comment
Я; отсюда и ошибка NoClassDefFound. Он компилируется нормально. Вот что так сбивает с толку - person Matthew Saltz; 08.07.2014

Оказалось, что мне просто нужно было добавить несколько jar-файлов из каталога $HADOOP_HOME/lib в зависимости, и это сработало. Как только я добавил зависимость для org/apache/commons/logging/LogFactory, она устранила ошибку для класса конфигурации Hadoop, а затем мне просто пришлось добавить другие необходимые файлы jar позже.

person Matthew Saltz    schedule 08.07.2014