2012-05-22 19 views
5

Estoy intentando ejecutar el ejemplo de rutas más cortas de la incubadora giraph (https://cwiki.apache.org/confluence/display/GIRAPH/Shortest+Paths+Example). Sin embargo, en lugar de ejecutar el ejemplo de giraph - * - dependencies.jar, he creado mi propio jar de trabajo. Cuando creé un solo archivo de empleo tal como se presenta en el ejemplo, que estaba recibiendoEjemplo de rutas más cortas Giraph ClassNotFoundException

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

entonces he movido las clases internas (SimpleShortestPathsVertexInputFormat y SimpleShortestPathsVertexOutputFormat) que separa los archivos y los rebautizado por si acaso (SimpleShortestPathsVertexInputFormat_v2, SimpleShortestPathsVertexOutputFormat_v2); las clases ya no son estáticas. Esto ha resuelto los problemas de clase no encontrados para SimpleShortestPathsVertexInputFormat_v2; sin embargo, sigo recibiendo el mismo error para SimpleShortestPathsVertexOutputFormat_v2. A continuación está mi rastro de pila.

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 

He inspeccionado mi jar de trabajo y todas las clases están allí. Además estoy usando hadoop 0.20.203 en un modo pseudo distribuido. La forma en que lanzo mi trabajo se presenta a continuación.

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 

También he definido HADOOP_CLASSPATH para el giraph - * - dependencies.jar. Puedo ejecutar el ejemplo de PageRankBenchmark sin ningún problema (directamente desde giraph - * - dependencies.jar), y el ejemplo de ruta de shortes también funciona (también directamente desde giraph - * - dependencies.jar). Otros trabajos de hadoop funcionan sin problemas (en algún lugar he leído para probar si mi "clúster" funciona correctamente). ¿Alguien se encontró con un problema similar? Cualquier ayuda será apreciada.


Solución (lo siento a publicarlo como este, pero no puedo responder a mi propia pregunta durante un par de horas más)

Para resolver este problema que tuve que añadir mi tarro de Trabajo de la -libjars (no se realizaron cambios en HADOOP_CLASSPATH). El comando para iniciar trabajo ahora se ve así.

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 

La lista de jarras debe estar separada en coma. Aunque esto ha resuelto mi problema. Todavía tengo curiosidad por saber por qué tengo que pasar mi jar de trabajo como parámetro de "classpath". ¿Puede alguien explicarme cuál es la razón detrás de esto? Como me pareció extraño (por decir lo menos) invocar mi jar de trabajo y luego volver a pasarlo como un jar "classpath". Tengo mucha curiosidad sobre la explicación.

Respuesta

3

Encontré una solución programática alternativa al problema. tenemos que modificar el método run() de la siguiente manera -

... 
@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() hará mirada hadoop para las clases que faltan en el mismo frasco que contiene la clase devuelta por getClass(), y lo haremos no es necesario agregar el nombre del jar del trabajo por separado a la opción -libjars.

Cuestiones relacionadas