2011-11-04 7 views
6

私は私のようなロギング特性を定義したのScala 2.9.1Scalaの2.9ブリッジ法

を使用しています:

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が発生してアプリケーションがクラッシュし、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でクラスをロードできない場合は、Scala-2.9にアップグレードできません。

誰もこの問題に遭遇しましたか?修正や回避策はありますか?

+0

幸いなことに私たちの実際のアプリケーションには影響しません。いくつかの特性定義メソッドが存在しないため、いくつかのBeanにエラーがあることを示すSpring IDEだけです。 – Nick

+1

これを参照してください:http://stackoverflow.com/questions/8748625/why-are-concrete-function-implementations-in-traits-compiled-to-bridge-methodsi-i – Janx

答えて

3

同じことがわかりました。私はScala 2.9.xのどのような変更がこれを引き起こしたのか分かりませんでしたが、本当の問題はSpring自体にあると思います。

特性をクラスに混合すると、クラス内の合成メソッドが追加され、ブリッジメソッドとしてマークされ、その特性のメソッドの実装に転送されます。

Javaでは、サブクラスがスーパークラスまたはインタフェース内のメソッドをオーバーライドするが、戻り型を洗練する際に、クラスにもブリッジメソッドが追加されています。戻り値の型はバイトコードレベルのメソッドシグネチャの一部であるため、親メソッドのシグニチャだけを知っているクライアントが引き続きサブクラス内のメソッドを呼び出せるように、転送メソッドが必要です。 (詳細はwhat java.lang.reflect.Method.isBridge() used for?

スプリングは、記事A Bridge Too Farに記載されている理由でブリッジメソッドのバイトコードを検査します。その記事の名前は皮肉なことです - SpringはこれをJava開発者が直面してアプリケーションスタックに統合するハードインフラストラクチャの問題を解決するSpringの完璧な例ですが、バイトコードのソースについてあまりにも多くの仮定をしています。悪い、無効にすることはできません。

短期的な回避策は、Springで使用するクラスに特性を混在させないようにすることです。 Java以外のバイトコードに対してこのチェックを無効にするには、Springにバグを付ける必要があります。

関連する問題