Spark升级到2.0后测试stream-kafka测试报java.lang.NoClassDefFoundError: org/apache/spark/Logging错误

在使用spark读取kafka数据时,当spark升级到2.0之后,出现如上问题:之前遇到了,当时在工程里面添加了org.apache.spark.Logging类,能够运行。

但是在后期使用过程中,又遇到了相同的问题,为了一劳永逸,今天彻底把问题解决。

开发环境:Idea intelligent14 + spark-2.1.0 + kafka

在Idea中安装scala



新建maven-scala工程


在工程中新建org.apche.spark包

新建Logging.scala类

将Logging源码拷贝到类中

[java]  view plain  copy
  1. package org.apache.spark  
  2.   
  3. import org.apache.log4j.{LogManager, PropertyConfigurator}  
  4. import org.slf4j.{Logger, LoggerFactory}  
  5. import org.slf4j.impl.StaticLoggerBinder  
  6.   
  7. import org.apache.spark.annotation.DeveloperApi  
  8. import org.apache.spark.util.Utils  
  9. /** 
  10.  * Created by Administrator on 2017/8/11. 
  11.  */  
  12.   
  13.   
  14. /** 
  15.  * :: DeveloperApi :: 
  16.  * Utility trait for classes that want to log data. Creates a SLF4J logger for the class and allows 
  17.  * logging messages at different levels using methods that only evaluate parameters lazily if the 
  18.  * log level is enabled. 
  19.  * 
  20.  * NOTE: DO NOT USE this class outside of Spark. It is intended as an internal utility. 
  21.  *       This will likely be changed or removed in future releases. 
  22.  */  
  23. @DeveloperApi  
  24. trait Logging {  
  25.   // Make the log field transient so that objects with Logging can  
  26.   // be serialized and used on another machine  
  27.   @transient private var log_ : Logger = null  
  28.   
  29.   // Method to get the logger name for this object  
  30.   protected def logName = {  
  31.     // Ignore trailing $'s in the class names for Scala objects  
  32.     this.getClass.getName.stripSuffix("$")  
  33.   }  
  34.   
  35.   // Method to get or create the logger for this object  
  36.   protected def log: Logger = {  
  37.     if (log_ == null) {  
  38.       initializeIfNecessary()  
  39.       log_ = LoggerFactory.getLogger(logName)  
  40.     }  
  41.     log_  
  42.   }  
  43.   
  44.   // Log methods that take only a String  
  45.   protected def logInfo(msg: => String) {  
  46.     if (log.isInfoEnabled) log.info(msg)  
  47.   }  
  48.   
  49.   protected def logDebug(msg: => String) {  
  50.     if (log.isDebugEnabled) log.debug(msg)  
  51.   }  
  52.   
  53.   protected def logTrace(msg: => String) {  
  54.     if (log.isTraceEnabled) log.trace(msg)  
  55.   }  
  56.   
  57.   protected def logWarning(msg: => String) {  
  58.     if (log.isWarnEnabled) log.warn(msg)  
  59.   }  
  60.   
  61.   protected def logError(msg: => String) {  
  62.     if (log.isErrorEnabled) log.error(msg)  
  63.   }  
  64.   
  65.   // Log methods that take Throwables (Exceptions/Errors) too  
  66.   protected def logInfo(msg: => String, throwable: Throwable) {  
  67.     if (log.isInfoEnabled) log.info(msg, throwable)  
  68.   }  
  69.   
  70.   protected def logDebug(msg: => String, throwable: Throwable) {  
  71.     if (log.isDebugEnabled) log.debug(msg, throwable)  
  72.   }  
  73.   
  74.   protected def logTrace(msg: => String, throwable: Throwable) {  
  75.     if (log.isTraceEnabled) log.trace(msg, throwable)  
  76.   }  
  77.   
  78.   protected def logWarning(msg: => String, throwable: Throwable) {  
  79.     if (log.isWarnEnabled) log.warn(msg, throwable)  
  80.   }  
  81.   
  82.   protected def logError(msg: => String, throwable: Throwable) {  
  83.     if (log.isErrorEnabled) log.error(msg, throwable)  
  84.   }  
  85.   
  86.   protected def isTraceEnabled(): Boolean = {  
  87.     log.isTraceEnabled  
  88.   }  
  89.   
  90.   private def initializeIfNecessary() {  
  91.     if (!Logging.initialized) {  
  92.       Logging.initLock.synchronized {  
  93.         if (!Logging.initialized) {  
  94.           initializeLogging()  
  95.         }  
  96.       }  
  97.     }  
  98.   }  
  99.   
  100.   private def initializeLogging() {  
  101.     // Don't use a logger in here, as this is itself occurring during initialization of a logger  
  102.     // If Log4j 1.2 is being used, but is not initialized, load a default properties file  
  103.     val binderClass = StaticLoggerBinder.getSingleton.getLoggerFactoryClassStr  
  104.     // This distinguishes the log4j 1.2 binding, currently  
  105.     // org.slf4j.impl.Log4jLoggerFactory, from the log4j 2.0 binding, currently  
  106.     // org.apache.logging.slf4j.Log4jLoggerFactory  
  107.     val usingLog4j12 = "org.slf4j.impl.Log4jLoggerFactory".equals(binderClass)  
  108.   
  109.     lazy val isInInterpreter: Boolean = {  
  110.       try {  
  111.         val interpClass = classForName("org.apache.spark.repl.Main")  
  112.         interpClass.getMethod("interp").invoke(null) != null  
  113.       } catch {  
  114.         case _: ClassNotFoundException => false  
  115.       }  
  116.     }  
  117.     def classForName(className: String): Class[_] = {  
  118.       Class.forName(className, true, getContextOrSparkClassLoader)  
  119.       // scalastyle:on classforname  
  120.     }  
  121.     def getContextOrSparkClassLoader: ClassLoader =  
  122.       Option(Thread.currentThread().getContextClassLoader).getOrElse(getSparkClassLoader)  
  123.     def getSparkClassLoader: ClassLoader = getClass.getClassLoader  
  124.   
  125.     if (usingLog4j12) {  
  126.       val log4j12Initialized = LogManager.getRootLogger.getAllAppenders.hasMoreElements  
  127.       if (!log4j12Initialized) {  
  128.         // scalastyle:off println  
  129.         if (isInInterpreter) {  
  130.           val replDefaultLogProps = "org/apache/spark/log4j-defaults-repl.properties"  
  131.           Option(Utils.getSparkClassLoader.getResource(replDefaultLogProps)) match {  
  132.             case Some(url) =>  
  133.               PropertyConfigurator.configure(url)  
  134.               System.err.println(s"Using Spark's repl log4j profile: $replDefaultLogProps")  
  135.               System.err.println("To adjust logging level use sc.setLogLevel(\"INFO\")")  
  136.             case None =>  
  137.               System.err.println(s"Spark was unable to load $replDefaultLogProps")  
  138.           }  
  139.         } else {  
  140.           val defaultLogProps = "org/apache/spark/log4j-defaults.properties"  
  141.           Option(Utils.getSparkClassLoader.getResource(defaultLogProps)) match {  
  142.             case Some(url) =>  
  143.               PropertyConfigurator.configure(url)  
  144.               System.err.println(s"Using Spark's default log4j profile: $defaultLogProps")  
  145.             case None =>  
  146.               System.err.println(s"Spark was unable to load $defaultLogProps")  
  147.           }  
  148.         }  
  149.         // scalastyle:on println  
  150.       }  
  151.     }  
  152.     Logging.initialized = true  
  153.   
  154.     // Force a call into slf4j to initialize it. Avoids this happening from multiple threads  
  155.     // and triggering this: http://mailman.qos.ch/pipermail/slf4j-dev/2010-April/002956.html  
  156.     log  
  157.   }  
  158. }  
  159.   
  160. private object Logging {  
  161.   @volatile private var initialized = false  
  162.   val initLock = new Object()  
  163.   try {  
  164.     // We use reflection here to handle the case where users remove the  
  165.     // slf4j-to-jul bridge order to route their logs to JUL.  
  166.     val bridgeClass = Utils.classForName("org.slf4j.bridge.SLF4JBridgeHandler")  
  167.     bridgeClass.getMethod("removeHandlersForRootLogger").invoke(null)  
  168.     val installed = bridgeClass.getMethod("isInstalled").invoke(null).asInstanceOf[Boolean]  
  169.     if (!installed) {  
  170.       bridgeClass.getMethod("install").invoke(null)  
  171.     }  
  172.   } catch {  
  173.     case e: ClassNotFoundException => // can't log anything yet so just fail silently  
  174.   }  
  175. }  

打包运行


将生成的jar包放到spark的jar包文件夹下,然后在使用spark-submit-2.1.0就不会出现问题了。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值