Giraph最短パスの例ClassNotFoundException
-
13-12-2019 - |
質問
私は、Giraph Incubatorから最短パスの例を実行しようとしています( https://cwiki.apache.org/confluence/display/giraph/shortest + paths非サンプル)。ただし、Giraph * - Dependencies.jarから例を実行するのではなく、自分のジョブJARを作成しました。この例で提示されているように単一のジョブファイルを作成したとき、私は
を獲得していましたjava.lang.RuntimeException: java.lang.RuntimeException: java.lang.ClassNotFoundException: org.test.giraph.Test$SimpleShortestPathsVertexInputFormat
.
その後、Innerクラス(SimpleShortSpathServerSvertexOutputFormatとSimpleShortSpathEvertexOutputFormat)を移動してファイルを区切ってケースの場合にそれらを変更しました(SimpleShortSpathServerExinputFormat_v2、SimpleShortestPathSvertexOutputFormat_v2)。 は静的ではありません。これにより、SimpleShortSpathServerExInput_v2で見つからないクラスの問題が解決されましたが、SimpleShortSpathServertexOutputFormat_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 * - enesencencies.jarにhadoop_classpathを定義しました。 PagagerankBenchMarkの例を実行せずに(Giraph * - Dependencies.jarから直接)、Shortes Pathの例も同様に機能します(Giraph - * - 依存関係から直接)。他のHadoopの仕事は問題なく機能します(私の "クラスタ"が正しく機能するかどうかをテストするのを読みました)。誰もが同様の問題に出会ったことがありますか?どんな助けにも感謝されます。
解決策(このように投稿して申し訳ありませんが、私はもう数時間の質問に答えることはできません)
この問題を解決するために、私のジョブ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を "classpath"パラメータとして渡す必要がある理由私はまだ興味がありますか?誰かが私にこの背後にある合理的なものは何ですか?私の仕事のjarを呼び出してから「クラスパス」JARとしてそれを再度渡すことを見つけたように私はそれが不思議だと思った(最小を言うこと)。私は説明について本当に興味があります。
解決
私は問題に対する代替のプログラム的解決策を見つけました。 次のように実行()メソッドを変更する必要があります -
...
@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()は、getClass()によって返されたクラスを含む同じJAR内の不足しているクラスをHadoopにします。