Пример кратчайших путей Giraph ClassNotFoundException

Я пытаюсь запустить пример кратчайших путей из инкубатора giraph ( https://cwiki.apache.org/confluence/display/GIRAPH/Shortest+Paths+Example). Однако вместо того, чтобы выполнить пример из giraph-*-dependencies.jar, я создал свой собственный jar задания. Когда я создал один файл Job, как показано в примере, я получал

java.lang.RuntimeException: java.lang.RuntimeException: java.lang.ClassNotFoundException: org.test.giraph.Test$SimpleShortestPathsVertexInputFormat

Затем я переместил внутренние классы (SimpleShortestPathsVertexInputFormat и SimpleShortestPathsVertexOutputFormat) в отдельные файлы и переименовал их на всякий случай (SimpleShortestPathsVertexInputFormat_v2, SimpleShortestPathsVertexOutputFormat_v2); классы больше не статичны. Это решило проблемы класса, не найденного для SimpleShortestPathsVertexInputFormat_v2, однако я все еще получаю ту же ошибку для SimpleShortestPathsVertexOutputFormat_v2. Ниже мой след стека.

INFO mapred.JobClient: Running job: job_201205221101_0003
INFO mapred.JobClient:  map 0% reduce 0%
INFO mapred.JobClient: Task Id : attempt_201205221101_0003_m_000005_0, Status : FAILED
    java.lang.RuntimeException: java.lang.RuntimeException: java.lang.ClassNotFoundException: org.test.giraph.utils.SimpleShortestPathsVertexOutputFormat_v2
            at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:898)
            at org.apache.giraph.graph.BspUtils.getVertexOutputFormatClass(BspUtils.java:134)
            at org.apache.giraph.bsp.BspOutputFormat.getOutputCommitter(BspOutputFormat.java:56)
            at org.apache.hadoop.mapred.Task.initialize(Task.java:490)
            at org.apache.hadoop.mapred.MapTask.run(MapTask.java:352)
            at org.apache.hadoop.mapred.Child$4.run(Child.java:259)
            at java.security.AccessController.doPrivileged(Native Method)
            at javax.security.auth.Subject.doAs(Subject.java:415)
            at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1059)
            at org.apache.hadoop.mapred.Child.main(Child.java:253)
    Caused by: java.lang.RuntimeException: java.lang.ClassNotFoundException: org.test.giraph.utils.SimpleShortestPathsVertexOutputFormat_v2
            at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:866)
            at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:890)
            ... 9 more

Я осмотрел свою рабочую банку и все классы там. Кроме того, я использую hadoop 0.20.203 в псевдораспределенном режиме. Способ, которым я запускаю свою работу, представлен ниже.

hadoop jar giraphJobs.jar org.test.giraph.Test -libjars /path/to/giraph-0.2-SNAPSHOT-jar-with-dependencies.jar /path/to/input /path/to/output 0 3

Также я определил HADOOP_CLASSPATH для giraph-*-dependencies.jar. Я могу запустить пример PageRankBenchmark без проблем (непосредственно из giraph-*-dependencies.jar), и пример с кратчайшим путем тоже работает (также непосредственно из giraph-*-dependencies.jar). Другие задания Hadoop работают без проблем (где-то я прочитал, чтобы проверить, правильно ли работает мой "кластер"). Кто-нибудь сталкивался с подобной проблемой? Любая помощь будет оценена.


Решение (извините за публикацию, но я не могу ответить на свой вопрос еще пару часов)

Чтобы решить эту проблему, мне нужно было добавить мой Job jar в -libjars (без изменений в HADOOP_CLASSPATH, где он был сделан). Команда для запуска задания теперь выглядит следующим образом.

hadoop jar giraphJobs.jar org.test.giraph.Test -libjars /path/to/giraph-0.2-SNAPSHOT-jar-with-dependencies.jar,/path/to/job.jar /path/to/input /path/to/output 0 3

Список баночек должен быть через запятую. Хотя это решило мою проблему. Мне все еще любопытно, почему я должен передать свою рабочую банку в качестве параметра "classpath"? Может кто-нибудь объяснить мне, что является рациональным за этим? Как мне показалось странным (если не сказать больше) вызывать мою рабочую банку, а затем снова передавать ее как банку "classpath". Мне действительно любопытно объяснить.

1 ответ

Решение

Я нашел альтернативное программное решение проблемы. Нам нужно изменить метод run() следующим образом -

...
@Override
public int run(String[] argArray) throws Exception {
    Preconditions.checkArgument(argArray.length == 4,
        "run: Must have 4 arguments <input path> <output path> " +
        "<source vertex id> <# of workers>");

    GiraphJob job = new GiraphJob(getConf(), getClass().getName());
    // This is the addition - it will make hadoop look for other classes in the same     jar that contains this class
    job.getInternalJob().setJarByClass(getClass());
    job.setVertexClass(getClass());
    ...
}

setJarByClass () заставит hadoop искать недостающие классы в том же jar-файле, который содержит класс, возвращаемый getClass(), и нам не нужно будет добавлять имя jar-задания отдельно к параметру -libjars.

Другие вопросы по тегам