Spark 无法将 JSON 整数映射到 Java 整数



我有一个定义我的JSON的Java类,这个类包含一些整数属性。 Spark能够读取这个JSON并使用上面的Java类编码器解析它。我也能够执行正常的Spark SQL操作。

但是,当我尝试将此 Spark 数据集转换为 JavaRDD 或尝试使用 collectAsList 或 collect 在驱动程序中收集数据时,它失败并出现编译时错误。

如果我将这些 Integer 属性转换为 Long,事情就会开始工作。
那么,关于"Spark-Java-Integers",我在这里缺少什么?

像这样的链接只是告诉解决方案,但并没有给出实际问题的理由。
1( https://issues.apache.org/jira/browse/SPARK-12036
2( Spark CSV - 找不到实际参数的适用构造函数/方法

下面是我尝试过的代码。它包含3个文件。第一个是主要的 Spark 驱动程序代码。第二个是 Person Java 类,它定义了我想要解析和使用的 JSON。第三个文件是 JSON 本身。最后,我还从我的pom中包含了Spark依赖.xml

文件 1:主要的 Spark Java 驱动程序代码

package com.suraj.spark;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Encoder;
import org.apache.spark.sql.Encoders;
import org.apache.spark.sql.SparkSession;
import com.suraj.spark.pojos.Person;
public class PersonTest {
public static void main(String... args) {
SparkSession spark = SparkSession.builder().master("local").appName("Simple Application")
.getOrCreate();
Encoder<Person> pe = Encoders.bean(Person.class);
Dataset<Person> pdf = spark.read().json("person.json").as(pe);
pdf.show(); // This works
JavaRDD<Person> prdd = pdf.toJavaRDD();
System.out.println(prdd.take(1)); // This fails.
}
}

文件 2:定义我的 JSON 的人员类

package com.suraj.spark.pojos;
import java.io.Serializable;
public class Person implements Serializable {
private Integer age;
private String name;
private Double height;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getHeight() {
return height;
}
public void setHeight(Double height) {
this.height = height;
}
}

文件 3:包含我的 JSON 字符串的文件。将其保留在项目根目录。

{"name":"ravi","age":14,"height":6.4}
{"name":null,"age":12,"height":null}

文件4:我的诗歌摘录.xml

<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-sql_2.11</artifactId>
<version>2.4.4</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>2.4.4</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.apache.curator</groupId>
<artifactId>apache-curator</artifactId>
</exclusion>
</exclusions>
</dependency>

预期 = 这应该能够打印 take(1( 方法的输出。
实际结果 = 此操作失败,并出现以下堆栈的编译时错误

Caused by: java.util.concurrent.ExecutionException: org.codehaus.commons.compiler.CompileException: File 'generated.java', Line 57, Column 37: failed to compile: org.codehaus.commons.compiler.CompileException: File 'generated.java', Line 57, Column 37: No applicable constructor/method found for actual parameters "long"; candidates are: "public static java.lang.Integer java.lang.Integer.valueOf(int)", "public static java.lang.Integer java.lang.Integer.valueOf(java.lang.String) throws java.lang.NumberFormatException", "public static java.lang.Integer java.lang.Integer.valueOf(java.lang.String, int) throws java.lang.NumberFormatException"

这不是你得到的Integer,而是Long

No applicable constructor/method found for actual parameters "long";

它试图找到像new Integer(long)这样的方法来转换它,但没有,因为它是有损转换。将Person.age更改为Long,它将起作用(最简单的选项(。

最新更新