使用反射访问 Amazon Deequ 中的方法
Using reflections to access methods in Amazon Deequ
我计划创建一个用户配置文件,稍后我将解析该文件以便 运行 来自 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 上找到的示例。我还检查了 class 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 反射代码中的编译错误。
使用 Scala 2.13.3 + Deequ 1.0.5 和 Scala 2.11.12 + Deequ 1.0.5,您的代码可以编译。
编写您的依赖项和 Scala 版本。尝试 clean 重建您的项目(例如 sbt clean compile
如果您使用 sbt 构建项目)。
Deequ 1.0.5 依赖于 Scala 2 的 Scala 库版本(Shapeless、Twitter Chill、Spark、json4s、scala-parser-combinators、scala-xml、Breeze、Spire、Machinist)11.x 所以你应该使用 Scala 2.11.x.
使用 Scala 2.13 我有 java.lang.NoClassDefFoundError: scala/Serializable
.
还要注意在https://github.com/awslabs/deequ处写着
Deequ depends on Java 8 and is known to work with Apache Spark versions 2.2.x to 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 反射很奇怪。
我计划创建一个用户配置文件,稍后我将解析该文件以便 运行 来自 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 上找到的示例。我还检查了 class 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 反射代码中的编译错误。
使用 Scala 2.13.3 + Deequ 1.0.5 和 Scala 2.11.12 + Deequ 1.0.5,您的代码可以编译。
编写您的依赖项和 Scala 版本。尝试 clean 重建您的项目(例如 sbt clean compile
如果您使用 sbt 构建项目)。
Deequ 1.0.5 依赖于 Scala 2 的 Scala 库版本(Shapeless、Twitter Chill、Spark、json4s、scala-parser-combinators、scala-xml、Breeze、Spire、Machinist)11.x 所以你应该使用 Scala 2.11.x.
使用 Scala 2.13 我有 java.lang.NoClassDefFoundError: scala/Serializable
.
还要注意在https://github.com/awslabs/deequ处写着
Deequ depends on Java 8 and is known to work with Apache Spark versions 2.2.x to 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 反射很奇怪。