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

DSE 5.0 Custom Codecs in Scala - Intellij does not compile

我正在尝试编写自定义编解码器以将 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: com.datastax.driver.core.DataType,x: shade.com.datastax.spark.connector.google.common.reflect.TypeToken[org.joda.time.DateTime])com.datastax.driver.core.TypeCodec[org.joda.time.DateTime] <and>
  (x: com.datastax.driver.core.DataType,x: 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 中的构建。

我解决了这个问题。

问题源于类路径中 spark-cassandra-connector 的版本冲突。阴影和非阴影版本的依赖项都在类路径中,删除阴影依赖项解决了这个问题。

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