Scala 2.9桥接方法

6
我将使用Scala 2.9.1版本进行翻译。
我定义了一个Logging trait,如下所示:
 trait Logging {
    def debug(msg: String, throwables: Throwable*) = ....
    ....
 }

我有一个JMSPublisher类,其中混合了Logging trait:

 class JMSPublisher extends Publisher with Logging {
    def publishProducts(list: List[_ <: Product]) = ....
    def publish(list: Seq[Product]) = ....
 }

这一切都编译得很好。我的问题是,我有一个用户想将我的JMSPublisher加载到Spring中。他正在使用Spring 2.5.6。
当ApplicationContext在启动期间被加载时,应用程序会崩溃,并出现IllegalStateException,抱怨找不到与我的Logging特性相关的桥接方法。
Initialization of bean failed; nested exception is java.lang.IllegalStateException: Unable to locate bridged method for bridge method 'public void com.app.messaging.JmsPublisher.debug(java.lang.String, scala.collection.Seq)' 
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:480)
    .....stack trace follows.......

这段代码在Scala-2.8下运行正常,我听说Scala在2.9中将一些方法标记为桥接方法。我认为这是导致Spring失败的原因。如果我的类无法被Spring加载,我就无法升级到Scala-2.9。

有人遇到过这个问题吗?有没有解决方案或解决方法?


我认为我们遇到了类似的问题 - 幸运的是,它并没有影响我们的实际应用程序,只是Spring IDE会标记一些bean出现错误,因为它抱怨某些特征定义的方法不存在。 - Nick
1
请参考此链接:https://dev59.com/4Goy5IYBdhLWcg3wJKoq - Janx
1个回答

3
我们也遇到了相同的问题。我从未弄清楚Scala 2.9.x中的哪个更改触发了这个问题,但我认为真正的问题在于Spring本身。
当您将一个trait混入到类中时,在类中添加合成方法,标记为字节码中的“桥接方法”,并转发到trait中方法的实现。
Java也会在类中添加桥接方法,当子类覆盖父类或接口中的某个方法时,并细化返回类型。因为返回类型在字节码级别上是方法签名的一部分,所以需要转发方法,以便只知道父方法签名的客户端仍然可以调用子类中的方法。(更多细节: What Method.isBridge used for?)
Spring检查桥接方法的字节码,原因在文章A Bridge Too Far中有所描述。文章名称具有讽刺意味 - Spring称这是“Spring解决Java开发人员面临的难题并将其集成到应用程序栈中的完美例子”,但它对字节码来源做了太多的假设,更糟糕的是无法禁用。
短期解决方案是避免将trait混入到您在Spring中使用的类中。您应该向Spring提交错误报告,以允许您禁用此检查以针对非Java字节码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接