2014-09-05 20 views
15

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?

+2

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

+0

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

+0

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

Trả lời

12

Tôi gặp vấn đề tương tự. Nếu master là local thì chương trình chạy tốt cho hầu hết mọi người. Nếu họ đặt nó (cũng xảy ra với tôi) "spark: // myurl: 7077" nếu không hoạt động. Hầu hết mọi người gặp lỗi vì một lớp ẩn danh không được tìm thấy trong quá trình thực thi. Nó được giải quyết bằng cách sử dụng SparkContext.addJars ("Path to jar").

Hãy chắc chắn rằng bạn đang làm những điều sau đây: -

  • SparkContext.addJars ("Path to jar tạo từ maven [gợi ý: gói mvn]").
  • Tôi đã sử dụng SparkConf.setMaster ("spark: // myurl: 7077") trong mã và đã cung cấp cùng một đối số trong khi gửi lệnh để kích hoạt qua dòng lệnh.
  • Khi bạn chỉ định lớp trong dòng lệnh, hãy đảm bảo bạn đang viết tên đầy đủ bằng URL. ví dụ: "packageName.ClassName"
  • cuối cùng lệnh sẽ trông như thế này bin/spark-nộp --class "packageName.ClassName" --master spark: // myurl: 7077pathToYourJar/mục tiêu /yourJarFromMaven.jar

Lưu ý: jar này pathToYourJar/target/yourJarFromMaven.jar tại điểm cuối cùng cũng được thiết lập trong mã như trong điểm đầu tiên của câu trả lời này.

+0

Liên kết này là vô giá - http://www.datastax.com/dev/blog/common-spark-troubleshooting; Lưu ý rằng bạn cần bao gồm một lọ 'chất béo' nếu bạn không có kế hoạch sao chép các phụ thuộc vào tất cả các nút. Vui lòng kiểm tra ở đây để xem cách xây dựng một bằng cách sử dụng sbt: assembly http://stackoverflow.com/questions/28459333/how-to-build-an-uber-jar-fat-jar-using-sbt-within-intellij-idea –

3

Tôi cũng gặp vấn đề tương tự. Tôi nghĩ rằng - jars không vận chuyển các lọ đến các nhà điều hành. Sau khi tôi thêm vào SparkConf, nó hoạt động tốt.

val conf = new SparkConf().setMaster("...").setJars(Seq("https://stackoverflow.com/a/b/x.jar", "/c/d/y.jar")) 

This web page for trouble shooting cũng hữu ích.

3

Bạn nên thiết lập SPARK_CLASS_PATH trong spark-env.sh tập tin như thế này:

SPARK_LOCAL_IP=your local ip 
SPARK_CLASSPATH=your external jars 

và bạn nên gửi với vỏ tia lửa như thế này: spark-submit --class your.runclass --master spark://yourSparkMasterHostname:7077 /your.jar

và mã java của bạn như thế này:

SparkConf sparkconf = new SparkConf().setAppName("sparkOnHbase"); JavaSparkContext sc = new JavaSparkContext(sparkconf); 

thì nó sẽ hoạt động.

0

Nếu bạn đang sử dụng Maven và Maven Assembly plugin để tạo tệp jar của mình với mvn package, hãy đảm bảo rằng plugin lắp ráp được định cấu hình chính xác để trỏ tới lớp chính của ứng dụng Spark của bạn.

Something như thế này nên được thêm vào pom.xml của bạn để tránh bất kỳ java.lang.ClassNotFoundException 's:

  <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-assembly-plugin</artifactId> 
      <version>2.4.1</version> 
      <configuration> 
       <archive> 
        <manifest> 
         <mainClass>com.my.package.SparkDriverApp</mainClass> 
        </manifest> 
       </archive> 
       <descriptorRefs> 
        <descriptorRef>jar-with-dependencies</descriptorRef> 
       </descriptorRefs> 
       <skipAssembly>false</skipAssembly> 
      </configuration> 
      <executions> 
       <execution> 
        <id>package</id> 
        <phase>package</phase> 
        <goals> 
         <goal>single</goal> 
        </goals> 
       </execution> 
      </executions> 
     </plugin> 
Các vấn đề liên quan