作者:永远路鸣 | 来源:互联网 | 2023-09-15 20:26
本文由编程笔记#小编为大家整理,主要介绍了Spark-submit ClassNotFoundexception相关的知识,希望对你有一定的参考价值。
使用这个简单的例子,我遇到了“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))
}
}
在本地模式下,根据文档提交会在第31行生成“ClassNotFound”异常,其中ClassToRoundTrip对象被反序列化。奇怪的是,第28行的早期使用是可以的:
spark-submit --class "SimpleApp"
--master local[4]
target/scala-2.10/simpleapp_2.10-1.0.jar
但是,如果我为“driver-class-path”和“-jars”添加额外的参数,它在本地工作正常。
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
但是,提交给本地开发人员仍然会生成相同的问题:
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
我可以从输出中看到执行程序正在获取JAR文件。
其中一个执行者的日志在这里:
stdout:http://pastebin.com/raw.php?i=DQvvGhKm
stderr:http://pastebin.com/raw.php?i=MPZZVa0Q
我正在使用Spark 1.0.2。 ClassToRoundTrip包含在JAR中。我宁愿不必在SPARK_CLASSPATH或SparkContext.addJar中硬编码值。有人可以帮忙吗?
答案
我有同样的问题。如果master是本地的,那么程序对大多数人来说运行良好。如果他们把它设置为(也发生在我身上)“spark:// myurl:7077”如果不起作用。大多数人都会收到错误,因为在执行过程中找不到匿名类。它通过使用SparkContext.addJars(“路径到jar”)来解决。
确保您正在做以下事情: -
- SparkContext.addJars(“从maven创建jar的路径[hint:mvn package]”)。
- 我在代码中使用了SparkConf.setMaster(“spark:// myurl:7077”)并在通过命令行提交作业时提供了相同的参数。
- 在命令行中指定类时,请确保使用URL编写其完整名称。例如:“packageName.ClassName”
- 最终命令应该看起来像这个bin / spark-submit --class“packageName.ClassName”--master spark:// myurl:7077 pathToYourJar / target / yourJarFromMaven.jar
注意:最后一点的jar jar pathToYourJar / target / yourJarFromMaven.jar也在代码中设置,如此答案的第一点。
另一答案
我也有同样的问题。我认为--jars不会将罐装运送给执行者。我将它添加到SparkConf后,它工作正常。
val cOnf= new SparkConf().setMaster("...").setJars(Seq("/a/b/x.jar", "/c/d/y.jar"))
This web page for trouble shooting也很有用。
另一答案
你应该在spark-env.sh文件中设置SPARK_CLASS_PATH,如下所示:
SPARK_LOCAL_IP=your local ip
SPARK_CLASSPATH=your external jars
你应该像这样提交火花壳:spark-submit --class your.runclass --master spark://yourSparkMasterHostname:7077 /your.jar
和你的java代码如下:
SparkConf sparkcOnf= new SparkConf().setAppName("sparkOnHbase"); JavaSparkContext sc = new JavaSparkContext(sparkconf);
然后它会工作。
另一答案
如果您使用Maven和Maven Assembly插件使用mvn package
构建jar文件,请确保正确配置程序集插件以指向Spark应用程序的主类。
这样的东西应该添加到你的pom.xml
,以避免任何java.lang.ClassNotFoundException
:
org.apache.maven.plugins
maven-assembly-plugin
2.4.1
com.my.package.SparkDriverApp
jar-with-dependencies
false
package
package
single
另一答案
我想到的是,如果你在没有任何警告的情况下构建你的项目,那么你就不必为master和其他东西编写额外的代码。虽然这是一个很好的做法,但你可以避免它。就像我的情况一样,项目中没有警告,所以我能够在没有任何额外代码的情况下运行它。 Project Structure Link
在我有一些与构建相关的警告的情况下,我必须在代码中以及执行时处理JAR路径,我的URL和master。
我希望它可以帮助某人。干杯!