hadoop - Giraph 最短路径示例 ClassNotFoundException

标签 hadoop classnotfoundexception shortest-path giraph

我正在尝试从 giraph 孵化器 (https://cwiki.apache.org/confluence/display/GIRAPH/Shortest+Paths+Example) 运行最短路径示例。但是,我没有执行 giraph-*-dependencies.jar 中的示例,而是创建了自己的作业 jar。当我创建示例中显示的单个作业文件时,我得到了

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

我检查了我的作业 jar ,所有类都在那里。此外,我在伪分布式模式下使用 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

我还为 giraph-*-dependencies.jar 定义了 HADOOP_CLASSPATH。我可以毫无问题地运行 PageRankBenchmark 示例(直接来自 giraph-*-dependencies.jar),短路径示例也可以正常工作(也直接来自 giraph-*-dependencies.jar)。其他 hadoop 工作没有问题(我已经阅读过某处以测试我的“集群”是否正常工作)。有没有人遇到过类似的问题?任何帮助将不胜感激。


解决方案(很抱歉像这样发布,但我不能再过几个小时回答我自己的问题)

为了解决这个问题,我必须将我的 Job jar 添加到 -libjars(没有对 HADOOP_CLASSPATH 进行任何更改)。启 Action 业的命令现在如下所示。

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

jar 列表必须以逗号分隔。虽然这已经解决了我的问题。我仍然很好奇为什么我必须将我的工作 jar 作为“类路径”参数传递?有人能解释一下这背后的原因是什么吗?正如我发现调用我的作业 jar 然后将其作为“类路径”jar 再次传递一样(至少可以说)很奇怪。我真的很好奇这个解释。

最佳答案

我找到了该问题的另一种编程解决方案。 我们需要按以下方式修改 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 在包含 getClass() 返回的类的同一个 jar 中查找丢失的类,我们不需要将作业 jar 名称单独添加到 -libjars 选项。

关于hadoop - Giraph 最短路径示例 ClassNotFoundException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10700853/

相关文章:

hadoop - 在脚本中运行脚本? - Hive(和其他 QL)

java - 在mahout频谱聚类中,亲和矩阵中的对角元素值应该是多少

android - 在运行 4.3/pre L 的 Android 上找不到类/NoClassDefFound 错误

java - 在html中集成applet?

algorithm - 无优先队列无向循环图的Dijkstra算法实现

sql - 在配置单元的指定条件下从单行创建多行

java - 为什么 HDFS 使用 Protocol Buffer 而不是 Java 序列化 API 进行序列化?

tomcat - 无法启动服务器。服务器实例未配置

postgresql - 带有公交线路和时间表的最短路径

sql - 如何在飞行路线表中获得最短路径