Scala中的DSE 5.0自定义编解码器-Intellij无法编译

时间:2018-08-13 14:20:40

标签: scala intellij-idea cassandra datastax-enterprise

我正在尝试编写一个自定义编解码器,以将timestamp类型的Cassandra列转换为org.joda.time.DateTime

我正在使用sbt版本0.13.13构建我的项目。

我编写了一个对DateTime对象进行序列化和反序列化的测试。当我使用sbt "test:testOnly *DateTimeCodecTest"通过命令行运行测试时,项目将构建并通过测试。

但是,如果我尝试在Intellij中构建项目,则会收到以下错误:

Error:(17, 22) overloaded method constructor TypeCodec with alternatives:
  (x$1: com.datastax.driver.core.DataType,x$2: shade.com.datastax.spark.connector.google.common.reflect.TypeToken[org.joda.time.DateTime])com.datastax.driver.core.TypeCodec[org.joda.time.DateTime] <and>
  (x$1: com.datastax.driver.core.DataType,x$2: Class[org.joda.time.DateTime])com.datastax.driver.core.TypeCodec[org.joda.time.DateTime]
 cannot be applied to (com.datastax.driver.core.DataType, com.google.common.reflect.TypeToken[org.joda.time.DateTime])
object DateTimeCodec extends TypeCodec[DateTime](DataType.timestamp(), TypeToken.of(classOf[DateTime]).wrap()) {

这是编解码器:

import java.nio.ByteBuffer

import com.datastax.driver.core.exceptions.InvalidTypeException
import com.datastax.driver.core.{ DataType, ProtocolVersion, TypeCodec }
import com.google.common.reflect.TypeToken
import org.joda.time.{ DateTime, DateTimeZone }

/**
 * Provides serialization between Cassandra types and org.joda.time.DateTime
 *
 * Reference for writing custom codecs in Scala:
 *   https://www.datastax.com/dev/blog/writing-scala-codecs-for-the-java-driver
 */
object DateTimeCodec extends TypeCodec[DateTime](DataType.timestamp(), TypeToken.of(classOf[DateTime]).wrap()) {

  override def serialize(value: DateTime, protocolVersion: ProtocolVersion): ByteBuffer = {
    if (value == null) return null

    val millis: Long = value.getMillis

    TypeCodec.bigint().serializeNoBoxing(millis, protocolVersion)
  }

  override def deserialize(bytes: ByteBuffer, protocolVersion: ProtocolVersion): DateTime = {
    val millis: Long = TypeCodec.bigint().deserializeNoBoxing(bytes, protocolVersion)
    new DateTime(millis).withZone(DateTimeZone.UTC)
  }

  // Do we need a formatter?
  override def format(value: DateTime): String = value.getMillis.toString

  // Do we need a formatter?
  override def parse(value: String): DateTime = {
    try {
      if (value == null ||
        value.isEmpty ||
        value.equalsIgnoreCase("NULL")) throw new Exception("Cannot produce a DateTime object from empty value")
      // Do we need a formatter?
      else new DateTime(value)
    } catch {
      // TODO: Determine the more specific exception that would be thrown in this case
      case e: Exception =>
        throw new InvalidTypeException(s"""Cannot parse DateTime from "$value"""", e)
    }
  }

}

这是测试:

import com.datastax.driver.core.ProtocolVersion
import org.joda.time.{ DateTime, DateTimeZone }
import org.scalatest.FunSpec

class DateTimeCodecTest extends FunSpec {

  describe("Serialization") {
    it("should serialize between Cassandra types and org.joda.time.DateTime") {
      val now = new DateTime().withZone(DateTimeZone.UTC)

      val result = DateTimeCodec.deserialize(
        // TODO: Verify correct ProtocolVersion for DSE 5.0
        DateTimeCodec.serialize(now, ProtocolVersion.V4), ProtocolVersion.V4
      )

      assertResult(now)(result)
    }
  }
}

我充分利用了Intellij中的调试器,以及使用一些热键快速运行单个测试的功能。 几乎在IDE中失去编译能力与完全失去编译能力一样糟糕。任何帮助将不胜感激,如果有人需要,我很乐意提供有关项目环境的其他信息。

编辑,更新: 如果我提供com.google.common.reflect.TypeToken而不是shade.com.datastax.spark.connector.google.common.reflect.TypeToken的实例,则该项目将在IntelliJ中编译。

但是,这会破坏sbt中的构建。

2 个答案:

答案 0 :(得分:0)

我解决了这个问题。

该问题源于类路径上spark-cassandra-connector的版本冲突。依赖项的阴影版本和非阴影版本都在类路径上,并且删除阴影的依赖项可以解决此问题。

答案 1 :(得分:0)

您必须为DateTimeCodec创建一个默认构造函数。