使用反射访问AmazonDeequ中的方法



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

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)

无法在Scala反射代码中重现编译错误。使用Scala2.13.3+Deequ1.0.5和Scala2.11.12+Deequ 1.0.5编译代码。编写依赖项和Scala的版本。尝试clean重建项目(例如,如果使用sbt构建项目,则为sbt clean compile(。

Deequ 1.0.5依赖于Scala 2.11.x的Scala库版本(Shapeless、Twitter Chill、Spark、json4s、Scala解析器组合子、Scala-xml、Breeze、Spire、Machinist(,因此您应该使用Scala2.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反射是很奇怪的。

相关内容

  • 没有找到相关文章

最新更新