tôi đang gặp vấn đề với một "ClassNotFound" ngoại lệ sử dụng ví dụ đơn giản này:Spark-nộp ClassNotFound ngoại lệ
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))
}
}
Trong chế độ địa phương, nộp theo các tài liệu tạo ra một "ClassNotFound" ngoại lệ trên dòng 31, nơi đối tượng ClassToRoundTrip được deserialized. Kỳ lạ thay, việc sử dụng trước đây về dòng 28 là okay:
spark-submit --class "SimpleApp" \
--master local[4] \
target/scala-2.10/simpleapp_2.10-1.0.jar
Tuy nhiên, nếu tôi thêm thông số bổ sung cho "tài xế-lớp-path", và "-jars", nó hoạt động tốt, trên địa phương.
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
Tuy nhiên, trình một bậc thầy dev địa phương, vẫn tạo ra cùng một vấn đề:
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
tôi có thể nhìn thấy từ đầu ra rằng các file JAR đang được tải xuống bởi người thi hành.
Logs cho một trong những người thi hành của đang ở đây:
stdout: http://pastebin.com/raw.php?i=DQvvGhKm
stderr: http://pastebin.com/raw.php?i=MPZZVa0Q
Tôi đang sử dụng Spark 1.0.2. ClassToRoundTrip được bao gồm trong JAR. Tôi không muốn phải mã hóa các giá trị trong SPARK_CLASSPATH hoặc SparkContext.addJar. Có ai giúp được không?
Update - Tôi đã có thể làm việc này bằng cách thiết lập các 'spark.executor.extraClassPath' và làm cho Tệp JAR cục bộ có sẵn trên mỗi người thực hiện tại đường dẫn. Tôi không hiểu tại sao điều này là cần thiết: JAR đang được lấy từ máy chủ HTTP nội bộ của Spark bởi người thi hành và được sao chép vào thư mục làm việc của mỗi người thi hành. – puppet
Tôi cũng thấy cùng một vấn đề hôm nay. Jar đang được lấy bởi thực thi và nó có lớp tìm kiếm của nó mặc dù nó ném ClassNotFoundException !! Tôi đang trên 1.0.2 btw – nir
Cập nhật một lần nữa - Tôi nghĩ rằng điều này có thể có một cái gì đó để làm với serialization. Chúng tôi tìm thấy một vài ngày trước rằng việc thay đổi phương pháp tuần tự hóa đã làm cho vấn đề biến mất. Tôi vẫn không chắc tại sao, nhưng nó đáng để thử. – puppet