2016-05-07 11 views
0

Ich habe ein Spark-Scala-Programm, das ein Glas lädt, schrieb ich in Java. Von diesem Jar wird eine statische Funktion aufgerufen, die versucht, ein serialisiertes Objekt aus einer Datei (Pattern.class) zu lesen, aber eine java.lang.ClassNotFoundException auslöst. Die Ausführung des Funke-Programms lokal funktioniert, aber auf den Cluster-Arbeitern nicht. Es ist besonders merkwürdig, denn bevor ich versuche, aus der Datei zu lesen, instanziiere ich ein Pattern Objekt und es gibt keine Probleme.java.lang.ClassNotFoundException beim Ausführen von Programm auf Funken-Cluster

Ich bin sicher, dass die Pattern Objekte, die ich in der Datei schrieb, die gleichen sind wie die Pattern Objekte, die ich versuche zu lesen.

Ich habe das Glas in der Slave-Maschine überprüft und die Pattern Klasse ist da.

Hat jemand eine Idee, was das Problem sein könnte? Ich kann mehr Details hinzufügen, wenn es benötigt wird.

Dies ist die Klasse Pattern

public class Pattern implements Serializable { 
private static final long serialVersionUID = 588249593084959064L; 

public static enum RelationPatternType {NONE, LEFT, RIGHT, BOTH}; 
RelationPatternType type; 
String entity; 
String pattern; 
List<Token> tokens; 
Relation relation = null; 

public Pattern(RelationPatternType type, String entity, List<Token> tokens, Relation relation) { 
    this.type = type; 
    this.entity = entity; 
    this.tokens = tokens; 
    this.relation = relation; 
    if (this.tokens != null) 
     this.pattern = StringUtils.join(" ", this.tokens.toString()); 
} 

}

ich die Datei aus dem S3 lese die folgende Art und Weise:

AmazonS3 s3Client = new AmazonS3Client(credentials); 
S3Object confidentPatternsObject = s3Client.getObject(new GetObjectRequest("xxx","confidentPatterns")); 
objectData = confidentPatternsObject.getObjectContent(); 
ois = new ObjectInputStream(objectData); 
confidentPatterns = (Map<Pattern, Tuple2<Integer, Integer>>) ois.readObject(); 

LE: überprüfte ich die Classpath zur Laufzeit und der Pfad zu dem Glas war nicht da. Ich habe es für die Executoren hinzugefügt, aber ich habe immer noch das gleiche Problem. Ich glaube nicht, dass es das war, da ich die Musterklasse innerhalb des Jar habe, die die readObject-Funktion aufruft.

+0

Haben Sie Ihre Klasse im Klassenpfad im Falle eines Clusters? –

+0

Muster ist deine eigene Klasse oder? es ist nicht der aus dem JDK? –

+0

Es ist in dem Glas, das im Cluster ausgeführt wird, also nehme ich an, dass es Zugriff darauf haben sollte – Tomy

Antwort

1

Würde vorschlagen, das diese Art Verfahren das Hinzufügen der Classpath Ressourcen vor Aufruf, um herauszufinden, um sicherzustellen, dass alles vom Anrufer Sicht in Ordnung ist

public static void printClassPathResources() { 
     final ClassLoader cl = ClassLoader.getSystemClassLoader(); 
     final URL[] urls = ((URLClassLoader) cl).getURLs(); 
     LOG.info("Print All Class path resources under currently running class"); 
     for (final URL url : urls) { 
      LOG.info(url.getFile()); 
     } 

    } 
  • Dies ist ein Beispielkonfiguration Funken 1,5

--conf "spark.driver.extraLibrayPath=$HADOOP_HOME/*:$HBASE_HOME/*:$HADOOP_HOME/lib/*:$HBASE_HOME/lib/htrace-core-3.1.0-incubating.jar:$HDFS_PATH/*:$SOLR_HOME/*:$SOLR_HOME/lib/*" \ --conf "spark.executor.extraLibraryPath=$HADOOP_HOME/*" \ --conf "spark.executor.extraClassPath=$(echo /your directory of jars/*.jar | tr ' ' ',')

  • Wie durch dieseTrouble shooting guide beschrieben: Klasse nicht gefunden: Classpath Probleme Ein weiteres häufiges Problem ist zu sehen Klasse nicht definiert, wenn Spark-Programme kompilieren dies ein wenig verwirrend Thema ist, weil Funken mehrere JVMs tatsächlich ausgeführt wird, wenn es Ihr Prozess ausführt und Der Pfad muss für jeden von ihnen korrekt sein. Normalerweise kommt es darauf an, Abhängigkeiten korrekt an die Executoren weiterzugeben. Stellen Sie sicher, dass Sie beim Ausführen ein fettes Jar mit all Ihren Abhängigkeiten (ich empfehle die Verwendung von sbt assembly) in das SparkConf-Objekt aufnehmen, mit dem Sie Ihren Spark-Kontext erstellen. Sie sollten auf das Schreiben einer Zeile wie diese in Ihrer Funken Anwendung beenden:

val conf = new SparkConf().setAppName(appName).setJars(Seq(System.getProperty("user.dir") + "/target/scala-2.10/sparktest.jar"))

Dies sollte die überwiegende Mehrheit der Klasse beheben Probleme nicht gefunden. Eine weitere Option besteht darin, Ihre Abhängigkeiten auf dem Standardklassenpfad auf allen Worker-Knoten im Cluster zu platzieren. Auf diese Weise müssen Sie kein großes Glas herumreichen.

Das einzige andere schwerwiegende Problem mit nicht gefundenen Klassenproblemen stammt von verschiedenen Versionen der verwendeten Bibliotheken.Wenn Sie beispielsweise in Ihrer Anwendung und auf dem Spark-Server keine identischen Versionen der allgemeinen Bibliotheken verwenden, werden Sie mit Klassenpfadproblemen konfrontiert. Dies kann auftreten, wenn Sie für eine Version einer Bibliothek (wie Spark 1.1.0) kompilieren und dann versuchen, gegen einen Cluster mit einer anderen oder veralteten Version (wie Spark 0.9.2) auszuführen. Stellen Sie sicher, dass Sie Ihre Bibliotheksversionen mit dem vergleichen, was auf den Executor-Klassenpfaden geladen wird. Ein gängiges Beispiel hierfür wäre das Kompilieren mit einem Alpha-Build des Spark Cassandra Connector, der dann versucht, Klassenpfadverweise auf eine ältere Version auszuführen.

+0

Ich habe den Klassenpfad damit ausgegeben. Der Weg zum Glas war nicht da. Ich habe es hinzugefügt, und ich habe immer noch das gleiche Problem. – Tomy

+0

Können Sie Ihren Befehl zum Senden von Funken hier einfügen? Welche Klassenpfadoptionen verwenden Sie wie driverClassPath, executorClassPath usw.? –

+0

~/spark/bin/spark-submit --jars /root/work/project-1.0-SNAPSHOT.jar --Klasse peoplegraph.Main --driver-memory 50g pipeline-1.0.jar und ich setze den Klassenpfad wie folgt: conf.set ("spark.executor.extraClassPath", "./") – Tomy

Verwandte Themen