我编写了一个简单的代码来解析一个大的XML文件(从中提取行,清理文本,并从中删除任何html标记)。
我在字符串上调用.replaceAllIn
时看到NullPointerException,这是非空的。
有趣的是,我在本地运行代码时没有错误,使用来自磁盘的输入,但是当我在AWS EMR上运行相同的代码时,我得到NullPointerException
,从S3加载输入文件。
以下是相关代码:
val HTML_TAGS_PATTERN = """<[^>]+>""".r
// other code here...
spark
.sparkContext
.textFile(pathToInputFile, numPartitions)
.filter { str => str.startsWith(" <row ") }
.toDS()
.map { str =>
Locale.setDefault(new Locale("en", "US"))
val parts = str.split(""""""")
var title: String = ""
var body: String = ""
// some code ommitted here
title = StringEscapeUtils.unescapeXml(title).toLowerCase.trim
body = StringEscapeUtils.unescapeXml(body).toLowerCase // decode xml entities
println("before replacing, body is: "+body)
// NEXT LINE TRIGGERS NPE
body = HTML_TAGS_PATTERN.replaceAllIn(body, " ") // take out htmltags
}
我尝试的事情:
在致电replaceAllIn
之前打印字符串,以确保它不是null
。
确保区域设置不为空
打印出异常消息和stacktrace:它只是告诉我该行是NullPointerException发生的地方。没有更多
我的本地设置和AWS EMR之间的不同之处:
在我的本地设置中,我从磁盘加载输入文件,在EMR上我从s3加载它。
在我的本地设置中,我以独立模式运行Spark,在EMR上以集群模式运行。
我的机器和AWS EMR上的其他所有内容都相同:Scala版本,Spark版本,Java版本,群集配置......
我一直在努力解决这个问题几个小时,我无法想到其他任何事情。
我已将r()
的电话转移到map{}
机构内,如下所示:
val HTML_TAGS_PATTERN = """<[^>]+>"""
// code ommited
.map{
body = HTML_TAGS_PATTERN.r.replaceAllIn(body, " ")
}
这也产生 NPE ,具有以下stracktrace:
java.lang.NullPointerException
at java.util.regex.Pattern.<init>(Pattern.java:1350)
at java.util.regex.Pattern.compile(Pattern.java:1028)
at scala.util.matching.Regex.<init>(Regex.scala:191)
at scala.collection.immutable.StringLike$class.r(StringLike.scala:255)
at scala.collection.immutable.StringOps.r(StringOps.scala:29)
at scala.collection.immutable.StringLike$class.r(StringLike.scala:244)
at scala.collection.immutable.StringOps.r(StringOps.scala:29)
at ReadSOStanfordTokenize$$anonfun$2.apply(ReadSOStanfordTokenize.scala:102)
at ReadSOStanfordTokenize$$anonfun$2.apply(ReadSOStanfordTokenize.scala:72)
at org.apache.spark.sql.catalyst.expressions.GeneratedClass$GeneratedIterator.processNext(Unknown Source)
at org.apache.spark.sql.execution.BufferedRowIterator.hasNext(BufferedRowIterator.java:43)
at org.apache.spark.sql.execution.WholeStageCodegenExec$$anonfun$8$$anon$1.hasNext(WholeStageCodegenExec.scala:377)
at org.apache.spark.sql.execution.datasources.FileFormatWriter$SingleDirectoryWriteTask.execute(FileFormatWriter.scala:243)
at org.apache.spark.sql.execution.datasources.FileFormatWriter$$anonfun$org$apache$spark$sql$execution$datasources$FileFormatWriter$$executeTask$3.apply(FileFormatWriter.scala:190)
at org.apache.spark.sql.execution.datasources.FileFormatWriter$$anonfun$org$apache$spar
答案 0 :(得分:2)
我认为你应该尝试将正则表达式内联到下面。
这是一个蹩脚的解决方案,您应该能够定义一个常量,可能将它放在全局object
或其他东西中。我不知道你在哪里定义这将是一个问题。但请记住spark将代码序列化并在分布式工作程序上运行,因此可能会出现问题。
rdd.map { _ =>
...
body = """<[^>]+>""".r.replaceAllIn(body, " ")
}
当我在空字符串上运行.r
时,我收到一个非常类似的错误。
val x: String = null
x.r
java.lang.NullPointerException
java.util.regex.Pattern.<init>(Pattern.java:1350)
java.util.regex.Pattern.compile(Pattern.java:1028)
scala.util.matching.Regex.<init>(Regex.scala:223)
scala.collection.immutable.StringLike.r(StringLike.scala:281)
scala.collection.immutable.StringLike.r$(StringLike.scala:281)
scala.collection.immutable.StringOps.r(StringOps.scala:29)
scala.collection.immutable.StringLike.r(StringLike.scala:270)
scala.collection.immutable.StringLike.r$(StringLike.scala:270)
scala.collection.immutable.StringOps.r(StringOps.scala:29)
该错误的行号略有不同,我认为是因为scala版本。我在2.12.2。
答案 1 :(得分:0)
感谢Stephen的回答,我找到了为什么我在我的UDF上获得NPE ...我这样做了(在我的案例中找到匹配):
onpaste
答案 2 :(得分:0)
“ <[^>] +>”很棒,但是我的HTML中有一种类型的东西。它由样式名称和大括号之间的参数组成:
<form data-members-form>
<input data-members-label type="hidden" value="Free" />
<input data-members-email type="email" required="true" placeholder="jenny.doe@example.com"
class="w-full appearance-none rounded border shadow p-3 text-grey-dark mr-2 focus:outline-none">
<button
class="w-full p-2 mt-5 py-5 bg-primary-600 text-white font-medium rounded hover:bg-primary-800 hover:font-semibold">
<span class="button-content">Sign Up for Free</span>
<span class="button-loader text-white">{{> "icons/loader"}}</span>
</button>
<div class="form-response-messages">
<div class="form-success bg-green-300 text-green-800 border-green-900 border rounded-lg my-5 p-5">Awww yeah,
Success! Please check your email to login.</div>
<div class="form-error bg-red-300 text-red-800 border-red-900 border rounded-lg my-5 p-5">Oh no! Looks like
there was an error. Please try again.</div>
</div>
</form>
我尝试使用以下方法提取它们,但没有用:
form[data-members-form] .form-response-messages {
display: none;
}
/*-- Show success message on success --*/
form[data-members-form].success .form-response-messages .form-success {
display: block;
}
/*-- Show error message on error --*/
form[data-members-form].error .form-response-messages .form-error {
display: block;
}