在spark集群

时间:2016-05-07 18:37:19

标签: java apache-spark classnotfoundexception

我有一个spark scala程序,它加载我在java中编写的jar。从该jar调用静态函数,该函数尝试从文件(Pattern.class)读取序列化对象,但抛出java.lang.ClassNotFoundException。 在本地运行spark程序可以正常工作,但在群集工作者上却没有。这特别奇怪,因为在我尝试从文件中读取之前,我实例化了一个Pattern对象并且没有问题。

我确信我在文件中写的Pattern个对象与我想要阅读的Pattern个对象相同。

我检查了从机中的jar,Pattern类就在那里。

有谁知道问题可能是什么?如果需要,我可以添加更多细节。

这是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());
}

}

我正在通过以下方式从S3读取文件:

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:我在运行时检查了类路径,并且jar的路径不存在。我为执行者添加了它,但我仍然遇到同样的问题。我不认为是这样,因为我在jar中调用了readObject函数的Pattern类。

1 个答案:

答案 0 :(得分:1)

建议在添加这种方法之前在调用之前找出类路径资源,以确保从调用者的角度来看一切都很好

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());
        }

    }
  • 这是示例配置spark 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 ' ' ',')

  • 正如此描述 Trouble shooting guide未找到类:类路径问题 另一个常见问题是在编译Spark程序时看到类未定义这是一个有点令人困惑的话题,因为spark在执行您的进程时实际上正在运行多个JVM,并且每个JVM的路径必须正确。通常,这归结为正确地将依赖项传递给执行程序。确保在运行时包含一个包含所有依赖项的胖Jar,(我建议使用sbt程序集)在用于创建Spark Context的SparkConf对象中。您最终应该在spark应用程序中编写这样的行:

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

这应该可以解决绝大多数未发现的课程问题。另一种选择是将依赖项放在集群中所有工作节点上的默认类路径中。这样你就不必绕过一个大罐子。

类未找到问题的唯一其他主要问题源于使用的库的不同版本。例如,如果您在应用程序和spark服务器中不使用相同版本的公共库,则最终会出现类路径问题。当您针对一个版本的库(如Spark 1.1.0)进行编译,然后尝试针对具有不同或过时版本的集群(如Spark 0.9.2)运行时,可能会发生这种情况。确保您将库版本与正在加载到执行程序类路径上的任何内容匹配。一个常见的例子是编译Spark Cassandra Connector的alpha版本,然后尝试使用旧版本的类路径引用运行。