【问题标题】:Scala 2.9 Bridge-MethodScala 2.9 桥接法
【发布时间】:2011-12-22 07:55:00
【问题描述】:

我使用的是 Scala 2.9.1

我已经这样定义了一个 Logging 特征:

 trait Logging {
    def debug(msg: String, throwables: Throwable*) = ....
    ....
 }

我有一个 JMSPublisher 类,它混合了 Logging 特征:

 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 中桥接的方法的 trait。我认为这就是导致 Spring 失败的原因。如果 Spring 无法加载我的类,我将无法升级到 Scala-2.9。

有人遇到过这个问题吗?是否有任何修复或解决方法?

【问题讨论】:

  • 我认为我们得到了类似的东西 - 幸运的是它不会影响我们的实际应用程序,只是 Spring IDE 会标记一些带有错误的 bean,因为它抱怨某些 trait 定义的方法不存在。跨度>

标签: java spring scala reflection scala-2.9


【解决方案1】:

我们看到了同样的事情。我从来不知道 Scala 2.9.x 中的什么变化触发了这个,但我认为真正的问题在于 Spring 本身。

当您将 trait 混合到一个类中时,会在类中添加合成方法,在字节码中标记为 bridge methods,这会转发到 trait 中方法的实现。

当子类覆盖超类或接口中的方法时,Java 还会向类添加桥接方法,但会改进返回类型。因为返回类型是字节码级别的方法签名的一部分,所以需要一个转发方法,以便只知道父方法签名的客户端仍然可以调用子类中的方法。 (更多详情:What Method.isBridge used for?

Spring 检查桥接方法的字节码,原因在文章A Bridge Too Far 中描述。那篇文章的名字很讽刺——Spring 称这是“Spring 解决 Java 开发人员面临的硬基础设施问题并将其集成到应用程序堆栈中的完美示例”,但它对字节码的来源做出了太多假设,并且更糟糕的是,无法禁用。

短期解决方法是避免将特征混入您在 Spring 中使用的类中。您应该向 Spring 提交一个错误,以允许您禁用对非 Java 字节码的检查。

【讨论】:

    猜你喜欢
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 2012-02-03
    • 1970-01-01
    • 2011-08-02
    • 2011-11-26
    • 2011-10-24
    • 1970-01-01
    相关资源
    最近更新 更多