我使用的是Scala 2.9.1
我已经这样定义了一个日志记录特征:
trait Logging {
def debug(msg: String, throwables: Throwable*) = ....
....
}我有一个JMSPublisher类,它混合了日志特性:
class JMSPublisher extends Publisher with Logging {
def publishProducts(list: List[_ <: Product]) = ....
def publish(list: Seq[Product]) = ....
}这一切都编译得很好。我的问题是,我有一个用户想要将我的JMSPublisher加载到Spring中。他使用的是Spring 2.5.6。
在启动期间加载ApplicationContext时,应用程序崩溃并显示IllegalStateException,并抱怨它找不到与我的日志记录特性相关的桥接方法。
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。
有没有人遇到过这个问题?是否有任何修复或变通方法?
发布于 2011-11-07 04:07:05
我们看到了同样的事情。我从来没有弄清楚是什么变化在Scala2.9.x中触发了这个问题,但我认为真正的问题在于Spring本身。
当您将一个特征混合到一个类中时,会将合成方法添加到该类中,这些方法在字节码中标记为桥方法,并转发到特征中方法的实现。
当子类覆盖超类或接口中的方法时,Java还会将桥方法添加到类中,但会优化返回类型。因为返回类型是字节码级别的方法签名的一部分,所以需要一个转发方法,以便只知道父方法签名的客户端仍然可以调用子类中的方法。(更多细节:what java.lang.reflect.Method.isBridge () used for?)
Spring检查桥方法的字节码,原因在文章A Bridge Too Far中描述。这篇文章的名字颇具讽刺意味-- Spring将其称为“Spring解决Java开发人员面临的硬基础设施问题并将其集成到应用程序堆栈中的完美示例”,但它对字节码的来源做了太多假设,更糟糕的是,它无法禁用。
短期的解决办法是避免将特征混合到Spring中使用的类中。您应该向Spring提交一个错误,以允许您对非Java字节码禁用此检查。
https://stackoverflow.com/questions/8014920
复制相似问题