我遇到了一个Java-17函数调用Scala 3.3.0内联/宏代码的问题,并得到了这个错误:
[error] /testDir/scala3-test/src/main/scala/csw/params/Test.java:7:1: cannot access io.bullet.borer.Encoder
[error] bad class file: /home/user/.cache/coursier/v1/https/repo1.maven.org/maven2/io/bullet/borer-core_3/1.11.0/borer-core_3-1.11.0.jar(/io/bullet/borer/Encoder.class)
[error] undeclared type variable: B
[error] Please remove or make sure it appears in the correct subdirectory of the classpath.
字符串
我创建了一个简单的测试代码库来演示这个问题:https://github.com/abrighton/scala3-test
Scala类:
import java.nio.charset.StandardCharsets
import io.bullet.borer.*
import io.bullet.borer.derivation.CompactMapBasedCodecs.deriveCodec
import play.api.libs.json.{Json => PJson, _}
object JsonSupport extends JsonSupport
trait JsonSupport {
def writes[T: Encoder](x: T): JsValue = PJson.parse(Json.encode(x).toUtf8String)
def reads[T: Decoder](x: JsValue): T = Json.decode(x.toString().getBytes(StandardCharsets.UTF_8)).to[T].value
}
case class ProperMotion(pmx: Double, pmy: Double)
object ProperMotion {
implicit val properMotionCodec: Codec[ProperMotion] = deriveCodec
}
型
Java类:
public class Test {
public void shouldConvertPmToFromJSON() {
var pm = new ProperMotion(0.5, 2.33);
var pmjs = JsonSupport.writes(pm, ProperMotion.properMotionCodec().encoder());
}
}
型
deriveCodec(来自borer)看起来像这样:
inline def deriveCodec[T]: Codec[T] = Codec(deriveEncoder[T], deriveDecoder[T])
型
类文件没有损坏(我已经测试了多个版本)。这似乎是Java调用内联Scala函数的问题。
Scala版本编译:
class TestX {
def shouldConvertPmToFromJSON(): Unit = {
val pm = ProperMotion(0.5, 2.33)
val pmjs = JsonSupport.writes(pm)
}
}
型
这类代码以前在Scala-2.13下编译过。
1条答案
按热度按时间iyfjxgzm1#
Scala宏不能从Java调用。
当你有:
字符串
或
型
基本上,编译器会在字节码中创建一个不能被调用的空体
method
。但是该方法会有一些额外的字节码属性,这些属性会告诉Scala编译器哪个方法可以将其参数转换为Expr
类型,其类型参数为Type
/WeakTypeTag
,并返回带有体AST的Expr。对于
javac
来说,它是一个格式错误的方法(或者是实现throw new NotYetImplemented
的方法),带有未知的属性。我不知道它在Scala 2.13中应该如何工作。上次我检查宏方法时,宏方法有一些宏属性,并被实现为
throw new NotYetImplemented
,可以调用(从Java或通过运行时反射),但不会返回任何有意义的东西。