gpt4 book ai didi

java - Avro 工具运行用 Java 编写的方法的 Scala 类加载器

转载 作者:行者123 更新时间:2023-12-02 00:04:40 24 4
gpt4 key购买 nike

我在确定加载“Avro Tools”类及其 run 方法的方法时遇到一些困难。问题出在 java 和 scala 接口(interface)以及类加载方法之间。由于 avro 在具有不同版本的 Spark 应用程序中的其他位置用于加载数据文件,因此我需要能够将此特定方法视为对另一个版本的 avro-tools 的孤立调用。

以下是我的代码:

package samples

import java.io.{ByteArrayOutputStream, InputStream}
import org.junit.runner.RunWith
import org.specs2.mutable._
import org.specs2.runner._

import scala.collection.JavaConverters._

@RunWith(classOf[JUnitRunner])
class MySpecTest extends Specification {
"Class Loader" should {
"load an implement a class" in {

var classLoader = new java.net.URLClassLoader(
Array(new java.io.File("./avro-tools-1.9.1.jar").toURI.toURL),
this.getClass.getClassLoader)

var clazzDFRT = classLoader.loadClass("org.apache.avro.tool.DataFileRepairTool")

val objDFRT = clazzDFRT.getConstructor().newInstance()
val toolCmdArgsAsJava = List("-o", "all", "questionable.avro", "fixed.avro").asJava
val stdin : InputStream = null
val out: ByteArrayOutputStream = new ByteArrayOutputStream
val stdout = new PrintStream(out) // added stdout in edit#1

val err = System.err
val toolClassArgsAsJava = List(stdin, stdout, // changed out to stdout in edit#1
err, toolCmdArgsAsJava).asJava

// parameterTypes: Class[_] *
// public int run( InputStream stdin, PrintStream out, PrintStream err, List<String> args)

val paramClasses: Array[Class[_]] = Array(classOf[InputStream], classOf[PrintStream], classOf[PrintStream], classOf[java.util.List[_]])

val method = clazzDFRT.getMethod("run", paramClasses : _*)

// the following produces wrong number of arguments exception
method.invoke(objDFRT.asInstanceOf[Object], toolClassArgsAsJava)

// sidebar: is this the end result for the Unit test - want out str with summary
out.toString("UTF-8").contains("File Summary")
}
}
}

我似乎在调用方法部分遇到了一些问题,但也许整个解决方案有点不对劲 - 我需要能够调用该方法以及加载、实例化或...

如何修复此问题以运行整个代码段(并修复损坏的 avro)?

最佳答案

由于您没有包含异常或堆栈跟踪,因此很难判断问题的确切性质。我不确定为什么您要动态加载 avro 工具,而不是将 jar 静态地包含在构建中。

//  public int run( InputStream stdin, PrintStream out, PrintStream err, List<String> args)
val method = clazzDFRT.getMethod("run", Class[_] : _*)

您没有正确指定参数。

method.invoke(objDFRT.asInstanceOf[Object], toolClassArgsAsJava)

val params: Array[Class[_]] = Array(classOf[InputStream], classOf[PrintStream], classOf[PrintStream], classOf[java.util.List[_]])
val method = clazzDFRT.getMethod("run", params : _*)

val method = clazzDFRT.getMethod("run", classOf[InputStream], classOf[PrintStream], classOf[PrintStream], classOf[java.util.List[_]])

要修复调用,您不能传递列表中的参数。 invoke 方法接受可变参数,您需要直接传递这些参数。

method.invoke(objDFRT.asInstanceOf[Object], stdin, stdout, stderr, toolCmdArgsAsJava)

method.invoke(objDFRT.asInstanceOf[Object], Array(stdin, stdout, stderr, toolCmdArgsAsJava): _*)

请注意,第二个选项使用 Array 而不是 List

我建议您阅读有关在 Java 和 Scala 中使用 var args 的文档* https://docs.oracle.com/javase/8/docs/technotes/guides/language/varargs.html* http://daily-scala.blogspot.com/2009/11/varargs.html

关于java - Avro 工具运行用 Java 编写的方法的 Scala 类加载器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58162643/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com