如何通过使用scala类扩展我的java类可写?

时间:2018-05-11 14:22:09

标签: java scala apache-spark inheritance sequencefile

我需要 saveAsSequenceFile 我的Java类对象(由于某些原因我无法更正类本身),因为我必须使它成为可写的。我试图通过实现 readFields 方法来扩展我的Java类与Scala类(只能使用Scala)。我可以保存到文件,但我看不懂:

java.lang.RuntimeException: java.lang.NoSuchMethodException: $iwC$$iwC$ClassBWritable.<init>()

似乎我必须为我的ClassBWritable创建初始​​构造函数,但是以下没有工作:

def this() = this(0, 0.0F)

如何制作初始构造函数或解决我的问题? 我的班级(需要修改其定义或添加其他构造函数):

import ClassA
import java.io.{DataOutput, DataInput}
import org.apache.hadoop.io.Writable
import org.apache.hadoop.io.LongWritable
class ClassBWritable(field1: Byte, field2: Float) extends ClassA(field1, field2)  with Writable{
    def this() = this(0.toByte, 0.0F)       
    override def write(out: DataOutput): Unit = {
        out.writeByte(getField1)
        out.writeFloat(getfield2)            
    }
    override def readFields(in: DataInput) : Unit = {
        setField1(in.readByte())
        setField2(in.readFloat())
    }
}

这里我如何保存到文件:

myrdd.map(pair => (new LongWritable(pair.longNumber) -> new ClassBWritable(pair.my_byte_value, pair.my_float_value)))
     .saveAsSequenceFile(mypath)

我如何阅读文件:

val df = sc.sequenceFile(mypath, classOf[LongWritable], classOf[ClassBWritable])
      .map(row => (p._1.get(), row._2.getField1(), row._2.getField2()) )
      .take(1)

我的例外:

Caused by: java.lang.NoSuchMethodException: $iwC$$iwC$ClassBWritable.<init>()
    at java.lang.Class.getConstructor0(Class.java:3082)
    at java.lang.Class.getDeclaredConstructor(Class.java:2178)
    at org.apache.hadoop.util.ReflectionUtils.newInstance(ReflectionUtils.java:128)
    ... 15 more

1 个答案:

答案 0 :(得分:0)

class ClassBWritable(field1: Byte, field2: Long) ... {
    def this() = this(0, 0.0F, 0, 0.0F, 0.0F) ...

无法编译:它必须是

    def this() = this(0.toByte, 0L)

代替。所以你显然在类路径中有ClassBWritable的不同版本(由$iwC$$iwC$ClassBWritable判断,它可能是在控制台而不是文件中定义的)。一旦你真正编译了类并确保它是其他文件中使用的类,那么问题应该得到解决。