Sto avendo problemi con un'eccezione "ClassNotFound" con questo semplice esempio:Spark-presentare eccezione ClassNotFound
import org.apache.spark.SparkContext
import org.apache.spark.SparkContext._
import org.apache.spark.SparkConf
import java.net.URLClassLoader
import scala.util.Marshal
class ClassToRoundTrip(val id: Int) extends scala.Serializable {
}
object RoundTripTester {
def test(id : Int) : ClassToRoundTrip = {
// Get the current classpath and output. Can we see simpleapp jar?
val cl = ClassLoader.getSystemClassLoader
val urls = cl.asInstanceOf[URLClassLoader].getURLs
urls.foreach(url => println("Executor classpath is:" + url.getFile))
// Simply instantiating an instance of object and using it works fine.
val testObj = new ClassToRoundTrip(id)
println("testObj.id: " + testObj.id)
val testObjBytes = Marshal.dump(testObj)
val testObjRoundTrip = Marshal.load[ClassToRoundTrip](testObjBytes) // <<-- ClassNotFoundException here
testObjRoundTrip
}
}
object SimpleApp {
def main(args: Array[String]) {
val conf = new SparkConf().setAppName("Simple Application")
val sc = new SparkContext(conf)
val cl = ClassLoader.getSystemClassLoader
val urls = cl.asInstanceOf[URLClassLoader].getURLs
urls.foreach(url => println("Driver classpath is: " + url.getFile))
val data = Array(1, 2, 3, 4, 5)
val distData = sc.parallelize(data)
distData.foreach(x=> RoundTripTester.test(x))
}
}
In modalità locale, presentando come per i documenti genera un'eccezione "ClassNotFound" sulla linea 31, dove l'oggetto ClassToRoundTrip è deserializzato. Stranamente, l'uso in precedenza sulla linea 28 va bene:
spark-submit --class "SimpleApp" \
--master local[4] \
target/scala-2.10/simpleapp_2.10-1.0.jar
Tuttavia, se aggiungo i parametri aggiuntivi per "conducente-class-path" e "-jars", funziona benissimo, il locale.
spark-submit --class "SimpleApp" \
--master local[4] \
--driver-class-path /home/xxxxxxx/workspace/SimpleApp/target/scala-2.10/simpleapp_2.10-1.0.jar \
--jars /home/xxxxxxx/workspace/SimpleApp/target/scala-2.10/SimpleApp.jar \
target/scala-2.10/simpleapp_2.10-1.0.jar
Tuttavia, la presentazione di un maestro locale dev, genera sempre lo stesso problema:
spark-submit --class "SimpleApp" \
--master spark://localhost.localdomain:7077 \
--driver-class-path /home/xxxxxxx/workspace/SimpleApp/target/scala-2.10/simpleapp_2.10-1.0.jar \
--jars /home/xxxxxxx/workspace/SimpleApp/target/scala-2.10/simpleapp_2.10-1.0.jar \
target/scala-2.10/simpleapp_2.10-1.0.jar
posso vedere dall'output che il file JAR è essere recuperato dal l'esecutore.
registri per uno dei esecutore di qui:
stdout: http://pastebin.com/raw.php?i=DQvvGhKm
stderr: http://pastebin.com/raw.php?i=MPZZVa0Q
sto usando Spark 1.0.2. ClassToRoundTrip è incluso nel JAR. Preferirei non avere valori hardcode in SPARK_CLASSPATH o SparkContext.addJar. Qualcuno può aiutare?
Aggiornamento - Sono stato in grado di ovviare a questo impostando il 'spark.executor.extraClassPath' e rendendo la File JAR localmente disponibile su ciascun esecutore nel percorso. Non capisco perché sia necessario: il JAR viene prelevato dal server HTTP interno di Spark dall'esecutore e copiato nella directory di lavoro di ciascun esecutore. – puppet
Oggi vedo lo stesso problema. Jar è stato scaricato dall'esecutore e ha la classe che sta cercando anche se lancia ClassNotFoundException !! Sono su 1.0.2 btw – nir
Aggiornamento di nuovo - Penso che questo potrebbe avere qualcosa a che fare con la serializzazione. Abbiamo scoperto un paio di giorni fa che la modifica del metodo di serializzazione ha risolto il problema. Non sono ancora sicuro del perché, ma vale la pena provare. – puppet