我正在尝试从 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
我检查了我的工作罐子,所有课程都在那里。此外,我在伪分布式模式下使用 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 进行更改)。启动作业的命令现在看起来像这样。
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 传递它很奇怪(至少可以说)。我真的很好奇这个解释。