2012-05-22 12 views
5

Ich versuche, die kürzesten Wege Beispiel aus dem giraph Inkubator (https://cwiki.apache.org/confluence/display/GIRAPH/Shortest+Paths+Example) ausführen. Anstatt jedoch das Beispiel aus der giraph - * - dependencies.jar auszuführen, habe ich mein eigenes Job-Jar erstellt. Wenn ich eine einzelne Job-Datei erstellt, wie im Beispiel dargestellt, war ich immerGira Shortest Paths Beispiel ClassNotFoundException

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

Dann habe ich die inneren Klassen (SimpleShortestPathsVertexInputFormat und SimpleShortestPathsVertexOutputFormat) bewegte Dateien trennen und umbenannt sie nur im Fall (SimpleShortestPathsVertexInputFormat_v2, SimpleShortestPathsVertexOutputFormat_v2); Die Klassen sind nicht mehr statisch. Dies hat die Probleme der Klasse gelöst, die für SimpleShortestPathsVertexInputFormat_v2 nicht gefunden wurde, aber ich bekomme immer noch den gleichen Fehler für SimpleShortestPathsVertexOutputFormat_v2. Unten ist mein Stack-Trace.

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 

Ich habe mein Job Glas überprüft und alle Klassen sind da. Desweiteren benutze ich hanoop 0.20.203 in einem Pseudo-verteilten Modus. Die Art und Weise, wie ich meinen Job starte, ist unten dargestellt.

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 

Auch ich habe HADOOP_CLASSPATH für die giraph - * - dependencies.jar definiert. Ich kann das PageRankBenchmark-Beispiel problemlos ausführen (direkt von der giraph - * - dependencies.jar), und auch das kurze Pfadbeispiel funktioniert (auch direkt von der giraph - * - dependencies.jar). Andere Hadoop-Jobs funktionieren ohne Probleme (irgendwo habe ich gelesen, um zu testen, ob mein "Cluster" korrekt funktioniert). Ist jemand auf ein ähnliches Problem gestoßen? Jede Hilfe wird geschätzt.


Lösung (sorry es so zu schreiben, aber ich kann meine eigene Frage für ein paar mehr Stunden nicht antworten)

Um dieses Problem zu lösen, musste ich meinen Job jar addieren, -libjars (es wurden keine Änderungen an HADOOP_CLASSPATH vorgenommen). Der Befehl zum Starten des Jobs sieht jetzt so aus.

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 

Liste der Gläser muss durch Komma getrennt sein. Obwohl das mein Problem gelöst hat. Ich bin immer noch neugierig, warum ich mein Jobglas als "Klassenpfad" -Parameter übergeben muss? Kann mir jemand erklären, was dahinter steckt? Ich fand es seltsam (um es milde auszudrücken), um mein Job-Jar aufzurufen und es dann erneut als "Classpath" -Jar zu übergeben. Ich bin wirklich neugierig auf die Erklärung.

Antwort

3

Ich fand eine alternative programmatische Lösung für das Problem. Wir brauchen die Methode run() in der folgenden Art und Weise ändern -

... 
@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() wird hadoop sucht die fehlenden Klassen in dem gleichen Glas machen, die die Klasse von getClass() zurückgegeben enthalten, und wir werden Sie müssen den Job-Jar-Namen nicht separat zur Option -libjars hinzufügen.