0

我计划创建一个用户配置文件,稍后我将对其进行解析,以便从 Amazon Deequ 运行一些检查。我希望能够从配置文件中传递字符串名称来获取方法;然而,在我尝试这样做的过程中,我不断遇到障碍。

import com.amazon.deequ.checks._

val ru = scala.reflect.runtime.universe
val rm = ru.runtimeMirror(getClass.getClassLoader)

val myClass = new Check(CheckLevel.Error, "unit testing my data")
val im = rm.reflect(myClass)

val methodSymbolNonNeg = ru.typeOf[Check].decl(ru.TermName("isNonNegative")).asMethod
val methodNonNeg = im.reflectMethod(methodSymbolNonNeg)

Name: Compile Error
Message: <console>:48: error: type mismatch;
 found   : ru.MethodSymbol
 required: ru.MethodSymbol
       val methodNonNeg = im.reflectMethod(methodSymbolNonNeg)

我已经尝试了文档中的几个示例以及我在 SO 上找到的内容。我还检查了类myClass.getClass.getMethods.map(_.getName).foreach{println}中以及 Github 上的方法名称。

此外,我也尝试过使用.getClass.getMethod和调用该方法

val m = myClass.getClass.getMethod("isNonNegative", "".getClass, 2.13.getClass, Option("").getClass)

Name: java.lang.NoSuchMethodException
Message: com.amazon.deequ.checks.Check.isNonNegative(java.lang.String, double, scala.Some)
StackTrace:   at java.lang.Class.getMethod(Class.java:1786)
4

1 回答 1

2

无法在 Scala 反射代码中重现编译错误。使用 Scala 2.13.3 + Deequ 1.0.5 和 Scala 2.11.12 + Deequ 1.0.5,您的代码可以编译。编写依赖项和 Scala 的版本。尝试干净地重建您的项目(例如sbt clean compile,如果您使用 sbt 构建项目)。

Deequ 1.0.5 依赖于 Scala 2.11 .x 的 Scala 库版本(Shapeless、Twitter Chill、Spark、json4s、scala-parser-combinators、scala-xml、Breeze、Spire、Machinist),因此您应该使用 Scala 2 11.x。 _

使用 Scala 2.13 我有java.lang.NoClassDefFoundError: scala/Serializable.

另请注意,在https://github.com/awslabs/deequ它是这样写的

Deequ 依赖于 Java 8,并且已知可与 Apache Spark 版本 2.2.x 到 2.4.x 一起使用。

您的编译错误 found: ru.MethodSymbol, required: ru.MethodSymbol看起来像是依赖版本的一些问题。

关于您的 Java 反射代码,您刚刚错误地指定了方法参数的类。的签名Check#isNonNegative

def isNonNegative(
  column: String,
  assertion: Double => Boolean,
  hint: Option[String])
: CheckWithLastConstraintFilterable

所以你应该做

myClass.getClass.getMethod("isNonNegative", classOf[String], classOf[Double => Boolean], classOf[Option[_]])

顺便说一句,混合 Scala 反射和 Java 反射很奇怪。

于 2020-10-01T09:59:48.640 回答