Java.lang.NoClassDefFoundError: org/apache/spark/streaming/twitter/TwitterUtils$ 在运行 TwitterPopularTags 时发生。

17

我是一个Spark Streaming和Scala的初学者。由于项目需求,我试图在Github上运行TwitterPopularTags示例。由于SBT汇编对我不起作用,而且我不熟悉SBT,因此我正在尝试使用Maven进行构建。经过许多初始问题,我能够创建jar文件。但是,在尝试执行它时,我遇到了以下错误。有人可以帮助我解决吗?

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/spark/streaming/twitter/TwitterUtils$
    at TwitterPopularTags$.main(TwitterPopularTags.scala:43)
    at TwitterPopularTags.main(TwitterPopularTags.scala)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.apache.spark.deploy.SparkSubmit$.launch(SparkSubmit.scala:331)
    at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:75)
    at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
Caused by: java.lang.ClassNotFoundException: org.apache.spark.streaming.twitter.TwitterUtils$
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    ... 9 more

我已经添加了以下依赖项: Spark-streaming_2.10:1.1.0 Spark-core_2.10:1.1.0 Spark-streaming-twitter_2.10:1.1.0

我甚至尝试了Spark-streaming-twitter 1.2.0,但仍然出现了相同的错误。

提前感谢您的帮助。

敬礼, vpv

7个回答

15
感谢您提供的建议。我通过仅使用SBT汇编来解决了此问题。以下是关于我如何做到这一点的详细信息。
Spark - 已经存在于Cloudera VM中 Scala - 不确定Cloudera是否有此项安装,如果没有,我们可以安装它 SBT - 这也需要安装。我在本地机器上进行了两次安装,并将Jar传输到VM中。为了安装此程序,我使用了以下链接

https://gist.github.com/visenger/5496675

1) 一旦所有这些都创建好了,我们就需要为我们的项目创建父文件夹。我创建了一个名为Twitter的文件夹。

2) 创建另一个文件夹,结构如下:Twitter/src/main/scala,并在此文件夹中创建名为TwitterPopularTags.scala的.scala文件。这个文件与我们从github上得到的代码有些不同,我不得不更改导入语句。

import org.apache.spark.streaming.Seconds
import org.apache.spark.streaming.StreamingContext
import org.apache.spark.streaming.StreamingContext._
import org.apache.spark.SparkContext._
import org.apache.spark.streaming.twitter._
import org.apache.spark.SparkConf

3) 在此之后,在父文件夹下创建另一个名为 Twitter/project 的文件夹,并创建一个名为 assembly.sbt 的文件。该文件包含汇编插件的路径。以下是文件中的完整代码。

resolvers += Resolver.url("sbt-plugin-releases-scalasbt", url("http://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/"))

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")

4) 一旦完成以上两个步骤,就在项目(Twitter)的父目录中创建一个名为build.sbt的文件。这是我们需要提供要创建的.Jar文件的名称以及依赖项的地方。请注意,即使是此文件中代码之间的空行也很重要。

name := "TwitterPopularTags"

version := "1.0"

mergeStrategy in assembly <<= (mergeStrategy in assembly) { (old) =>
   {
    case PathList("META-INF", xs @ _*) => MergeStrategy.discard
    case x => MergeStrategy.first
   }
}

libraryDependencies += "org.apache.spark" %% "spark-core" % "1.1.0" % "provided"

libraryDependencies += "org.apache.spark" %% "spark-streaming" % "1.1.0" % "provided"

libraryDependencies += "org.apache.spark" %% "spark-streaming-twitter" % "1.2.0" 

libraryDependencies += "org.twitter4j" % "twitter4j-stream" % "3.0.3" 

resolvers += "Akka Repository" at "http://repo.akka.io/releases/"

5) 最后,我们需要打开终端并进入项目(Twitter)的父文件夹。从这里输入以下命令:

sbt assembly

这将下载依赖项并创建所需的jar文件。
6)为了运行程序,我们需要在我们的ID下创建一个Twitter应用程序,并提供身份验证令牌和其他详细信息。有关如何创建此应用程序的详细步骤,请参见以下链接。

http://ampcamp.berkeley.edu/3/exercises/realtime-processing-with-spark-streaming.html

7)完成以上步骤后,我们可以使用VM中的spark-submit命令运行作业。示例命令如下:

./bin/spark-submit \
  --class TwitterPopularTags \
  --master local[4] \
  /path/to/TwitterPopilarTags.jar \
  comsumerkey consumersecret accesstoken accesssecret 

8) 这将输出结果到控制台,为了监视输出,最好通过调整代码来降低频率。

如果需要更多细节,请告诉我。

谢谢 & 致意,

VPV


1
谢谢,我也遇到了同样的问题。我在另一个主题中提供了答案:https://dev59.com/Tl4b5IYBdhLWcg3w-1-c#28498443,为那些需要更多信息的人提供帮助.. :) - Yves M.
1
谢谢@YvesM。你的回答真的帮了我很多 - 再次感谢!我看到了你很多的答案,都救了我的命! - Paladini

8

我找到了一个简单的解决方案(在1.5.1版本中肯定有效,可能早期版本也可以):

使用 --packages 参数和 Maven 坐标进行提交,例如:

spark-submit --master local[*] \
    --class TwitterStreaming \
    --packages "org.apache.spark:spark-streaming-twitter_2.10:1.5.1" \
    ${PATH_TO_JAR_IN_TARGET}

请参考http://spark.apache.org/docs/latest/programming-guide.html#using-the-shell,该文档描述了如何使用Spark的Shell。


这似乎是最简单的方法。 - David George
1
@Marek Dudek,当我添加--packages "org.apache.spark:spark-streaming-twitter_2.10:1.5.1"时,出现了异常信息“Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/spark/streaming/twitter/TwitterUtils”,虽然已经解决了这个异常,但是又出现了新的异常信息“Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/spark/Logging”。 - ROOT

2

这个错误意味着在运行时TwitterUtils类(或在scala语言中TwitterUtils对象)不存在,但在编译时存在(否则您将无法使用maven构建)。您应该确保您创建的jar文件确实包含该类/对象。您可以简单地解压缩该jar文件以查看实际包含的内容。最有可能的是,您的maven构建文件使用依赖项来构建项目,但最终未将其包含在最终的jar文件中。


0
    **I have the same problem and I am not able to fix**


    name := "SentimentAnalyser"

    version := "0.1"

    scalaVersion := "2.11.11"



    libraryDependencies += "org.apache.spark" % "spark-core_2.11" % "2.2.0"

    // https://mvnrepository.com/artifact/org.apache.spark/park-streaming-twitter_2.11

    // https://mvnrepository.com/artifact/org.apache.spark/spark-streaming_2.11
    libraryDependencies += "org.apache.spark" % "spark-streaming-twitter_2.11" % "2.0.0"
    libraryDependencies += "org.apache.spark" % "spark-streaming_2.11" % "2.2.0"

    package com

    import org.apache.spark.SparkConf
    import org.apache.spark.streaming.{Seconds, StreamingContext}
    import org.apache.spark.streaming.twitter.TwitterUtils

    object Sentiment {

      def main(args: Array[String]): Unit = {

        if(args.length<4){
          System.out.print("Enter Consumer Key (API Key) Consumer Secret (API Secret)Access Token Access Token Secret")
          System.exit(1);
        }

        val Array(customer_key,customer_secrect,access_token,access_token_secret)=args.take(4)

        System.setProperty("twiteer4j.oauth.consumerKey",customer_key)
        System.setProperty("twiteer4j.oauth.customerSecret",customer_secrect)
        System.setProperty("twiteer4j.oauth.accessToken",access_token)
        System.setProperty("twiteer4j.oauth.accessTokenSecret",access_token_secret)

        val conf=new SparkConf().setAppName("Sentiment").setMaster("local")
        val scc=new StreamingContext(conf,Seconds(30))
        //Dstream
        val stream=TwitterUtils.createStream(scc,None)

        val hashTag=stream.flatMap(status=>{status.getText.split(" ").filter(_.startsWith("#"))})

        val topHashTag60=hashTag.map((_,1)).reduceByKeyAndWindow(_+_,Seconds(60))
          .map{case (topic,count)=>(topic,count)}.transform(_.sortByKey(false))

        val topHashTag10=hashTag.map((_,1)).reduceByKeyAndWindow(_+_,Seconds(10))
          .map{case (topic,count)=>(topic,count)}.transform(_.sortByKey(false))


        topHashTag60.foreachRDD(rdd=>{
          val topList=rdd.take(10)
          println("Popular topic in last 60 sec (%s total)".format(rdd.count()))
          topList.foreach{case (count,tag)=>println("%s (%s tweets)".format(tag,count))}
        })

        topHashTag10.foreachRDD(rdd=>{
          val topList=rdd.take(10)
          println("Popular topic in last 10 sec (%s total)".format(rdd.count()))
          topList.foreach{case (count,tag)=>println("%s (%s tweets)".format(tag,count))}
        })


        scc.start()
        scc.awaitTermination()








      }

    }






I build jar using artifact in IJ ..


spark-submit --class com.Sentiment  /root/Desktop/SentimentAnalyser.jar XX XX XX XX


ERROR:
17/10/29 01:22:24 INFO BlockManager: Initialized BlockManager: BlockManagerId(driver, 192.168.46.132, 34179, None)
17/10/29 01:22:27 WARN StreamingContext: spark.master should be set as local[n], n > 1 in local mode if you have receivers to get data, otherwise Spark jobs will not get resources to process the received data.
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/spark/streaming/twitter/TwitterUtils$
        at com.Sentiment$.main(Sentiment.scala:26)
        at com.Sentiment.main(Sentiment.scala)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:755)
        at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:180)
        at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:205)
        at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:119)
        at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
Caused by: java.lang.ClassNotFoundException: org.apache.spark.streaming.twitter.TwitterUtils$
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at java.lang.ClassLoader.loadClass(ClassLoader.java

0

要在您的jar中包含依赖项,您需要指示Maven构建一个“fat jar”。 “Fat jar”是一个jar文件,不仅包括您项目的.class文件,还包括所有必需的依赖项的.class文件(这就是sbt assembly所做的)。默认的Maven行为是将您的项目视为库,因此仅构建一个带有您的.class文件的jar。

这是一个简单的maven pom,它将实现您想要的功能,请注意我已经包括了一些其他常见的Spark + Maven行为,例如使用Scala,但最相关的部分在底部附近:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.jmess.sparkexamples</groupId>
    <artifactId>example</artifactId>
    <version>1.0.0</version>

    <properties>
        <!-- Use java 1.8 -->
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <!-- Keep compiled against scala version uniform -->
        <scala.base.version>2.11</scala.base.version>
        <!-- Use most recent version of Scala compatible with stable Spark release -->
        <scala.version>${scala.base.version}.12</scala.version>
        <!-- Facilitates keeping multiple Spark dependencies aligned  -->
        <spark.version>2.4.0</spark.version>
    </properties>

    <dependencies>
        <!-- Begin Spark Dependencies -->
        <!-- Provides the base Spark APIs. Required for base functionality -->
        <!-- https://mvnrepository.com/artifact/org.apache.spark/spark-sql -->
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-sql_${scala.base.version}</artifactId>
            <version>${spark.version}</version>
            <!-- In most cases this dependency is supplied by Spark -->
            <scope>provided</scope>
        </dependency>
        <!-- Provides the expanded APIs for Streaming with Kafka. Required in addition to spark-sql library -->
        <!-- https://mvnrepository.com/artifact/org.apache.spark/spark-sql-kafka-0-10 -->
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-sql-kafka-0-10_${scala.base.version}</artifactId>
            <version>${spark.version}</version>
        </dependency>
        <!-- End Spark Dependencies -->

        <!-- Popular scala configuration library -->
        <dependency>
            <groupId>com.typesafe</groupId>
            <artifactId>config</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!-- To write to Splunk HTTP endpoint -->
    </dependencies>

    <build>
        <!-- Tells scala-maven-plugin where to look -->
        <sourceDirectory>src/main/scala</sourceDirectory>
        <testSourceDirectory>src/test/scala</testSourceDirectory>

        <plugins>
            <!-- For building scala projects using maven -->
            <plugin>
                <groupId>net.alchim31.maven</groupId>
                <artifactId>scala-maven-plugin</artifactId>
                <version>4.0.1</version>
                <!-- Includes the compiled Scala .class files in some maven goals -->
                <executions>
                    <execution>
                        <goals>
                            <goal>add-source</goal>
                            <goal>compile</goal>
                            <goal>testCompile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <!-- !!!!!!! BUILD FAT JAR !!!!!!! -->
            <!-- Build a fat jar named example-1.0.0-jar-with-dependencies.jar -->
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.1.1</version>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id> <!-- this is used for inheritance merges -->
                        <phase>package</phase> <!-- bind to the packaging phase -->
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

注意** 如果您是通过Spark而不是Yarn提交作业,则取消注释<scope>provided</scope>


0

我遇到了同样的问题,通过从sbt中删除“provided”来解决它。


0

试着这样做...

./bin/spark-submit \
  --class TwitterPopularTags \
  --jars (external_jars like twitter4j,streaming-twitter) \
  --master local[4] \
  /path/to/TwitterPopilarTags.jar \

消费者密钥 消费者秘钥 访问令牌 访问秘钥


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接