问题描述
我想传递一个包含案例类的scala文件,以便我的应用程序在运行时编译该案例类并开始使用它.
I want to pass a scala file containing a case class so my application compiles this case class during run time and start using it.
我这样做的主要原因是因为我希望避免每次case类更改时都重新构建代码.因此最好将其作为参数传递(以防万一,使用这种case类的操作是通用的,因此在转换中不需要任何重做)
The main reason why I am doing this is because I want to avoid rebuilding my code every time the case class changes. So would be better to pass it as a parameter (in case you are wondered, the operations with this case class are generic so it is not required any rework in the transformations)
我正在使用这些 post1 ,和 post3 作为参考.到目前为止,我的应用程序如下所示:
I was using these post1, post2 and post3 as references. So far my application looks like this:
import scala.io.Source
import scala.reflect.runtime.universe
import scala.tools.reflect._
object TestCompile {
def main(args: Array[String]): Unit = {
val path = "C:\\myWorkspace\\entity\\TestClass.scala"
val tb = universe.runtimeMirror(getClass.getClassLoader).mkToolBox()
val src = Source.fromFile(path).mkString.stripMargin
val clazz = tb.compile(tb.parse(src))().asInstanceOf[Class[_]]
}
}
文件 TestClass.scala 如下:
case class TestClass(
val value : String,
val timeStamp : Long,
val rowKey : String,
val columnFamily : String
)
但是我要例外了
val clazz = tb.compile(tb.parse(src))().asInstanceOf[Class[_]]
例外:
以下是我正在使用的依赖项,但是我尝试将其他版本始终得到相同的错误:
Below is the dependency I am using, however I tried with other versions always getting the same error:
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-reflect</artifactId>
<version>2.11.6</version>
</dependency>
我在做什么错了?
推荐答案
我今天有一些时间对此进行测试.我认为主要问题是 TestClass.scala 中缺少最后一个预期行scala.reflect.classTag[TestClass].runtimeClass
.
I got some time to test this today. The main problem I think is that the last expected line scala.reflect.classTag[TestClass].runtimeClass
is missing in TestClass.scala.
要记住的另一件重要事情是,scala-compiler.jar
也应该在您的类路径中.
One other important thing to remember is that scala-compiler.jar
should also be in your class path.
一旦我解决了这个问题,我就遇到了Java/Scala对象转换的另一个问题.您有两个选择,将timeStamp
字段设置为String
或Java.lang.Long
.由于String转换是微不足道的,因此下面给出了Java.lang.Long
的示例.
Once I resolved that, I ran into another problem with Java/Scala object conversion. You have two options, make the timeStamp
field, either a String
or Java.lang.Long
. Since the String conversion is trivial, I've given below example for Java.lang.Long
.
进行上述更改后,我的 TestClass.scala 如下所示:
With the above changes, my TestClass.scala looks like below:
case class TestClass(
value : String,
timeStamp : java.lang.Long,
rowKey : String,
columnFamily : String
) {}
scala.reflect.classTag[TestClass].runtimeClass
我将其复制到/tmp/
目录进行测试.
I copied it to /tmp/
directory for testing.
我的 TestCompile.scala 如下所示:
import scala.io.Source
import scala.reflect.runtime.universe
import scala.tools.reflect._
object TestCompile {
def main(args: Array[String]): Unit = {
val path = "/tmp/TestClass.scala"
val tb = universe.runtimeMirror(getClass.getClassLoader).mkToolBox()
val src = Source.fromFile(path).mkString.stripMargin
println(src)
val clazz = tb.compile(tb.parse(src))().asInstanceOf[Class[_]]
val ctor = clazz.getDeclaredConstructors()(0)
val instance = ctor.newInstance("My value", new java.lang.Long(1234567890L), "Row1", "Column1")
println(instance.toString)
}
}
输出
TestClass(My value,1234567890,Row1,Column1)
这篇关于scala.tools.reflect.ToolBoxError:反射编译失败:由于java.lang.VerifyError而无法初始化编译器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!