2011-11-04 12 views
6

Używam Scala 2.9.1Scala 2,9 Most-Metoda

Mam zdefiniowane cechę rejestrowania takich jak:

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

I mam klasę JMSPublisher który miesza w tej cechy Logging :

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

To wszystko kompiluje dobrze. Mój problem polega na tym, że mam użytkownika, który chce załadować mój JMS Publisher na wiosnę. Używa Spring 2.5.6.

Po załadowaniu ApplicationContext podczas uruchamiania aplikacja ulega awarii z IllegalStateException, narzekając, że nie może znaleźć metody zmostkowanej związanej z moją cechą rejestrowania.

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....... 

Ten kod pracował pod Scala-2.8, a słyszałem, że Scala jest oznakowanie cechę, że mają pewne metody jak zmostkowane w 2,9. Myślę, że właśnie to powoduje awarię Wiosny. Nie mogę uaktualnić do Scala-2.9, jeśli moja klasa nie może być załadowana przez Spring.

Czy ktoś napotkał ten problem? Czy jest jakaś poprawka lub obejście?

+0

Myślę, że otrzymujemy coś podobnego - na szczęście nie ma to wpływu na naszą rzeczywistą aplikację, tylko Spring IDE, który oznacza kilka fasoli z błędami, ponieważ narzeka, że ​​niektóre metody zdefiniowane przez cechy nie istnieją. – Nick

+1

Zobacz: http://stackoverflow.com/questions/8748625/why-are-concrete-function-implementations-in-traits-compiled-to-bridge-methods-i – Janx

Odpowiedz

3

Widzieliśmy to samo. Nigdy nie doszedłem do wniosku, jakie zmiany wywołał Scala 2.9.x, ale moim zdaniem prawdziwy problem dotyczy samej Spring.

Po zmiksowaniu cechy na klasę, dodaje metody syntetyczne do klasy, oznaczone w kodzie bajtowym jako metody mostkowe, które przekazują do implementacji metody w cechie.

Java dodaje również metody mostu do klas, gdy podklasa przesłania metodę w nadklasie lub interfejsie, ale precyzuje typ zwracany. Ponieważ typ zwracany jest częścią sygnatury metody na poziomie kodu bajtowego, potrzebna jest metoda przekazywania, aby klienci, którzy znają jedynie sygnaturę metody nadrzędnej, mogli nadal wywoływać metodę w podklasie. (Więcej szczegółów: what java.lang.reflect.Method.isBridge() used for?)

Sprężyna sprawdza kod bajtowy metod mostu z przyczyn opisanych w artykule A Bridge Too Far. Nazwa tego artykułu jest ironiczna - Spring nazywa to "doskonałym przykładem Springa rozwiązującego trudne problemy z infrastrukturą, które napotykają programiści Javy i integrującymi je ze stosami aplikacji", ale ma zbyt wiele założeń co do źródła kodu bajtowego, oraz gorzej, nie można wyłączyć.

Krótkoterminowe obejście, to unikanie mieszania cech z klasami, których używasz na wiosnę. Powinieneś złożyć błąd w Spring, aby umożliwić wyłączenie tego sprawdzenia dla kodu bajtowego innego niż Java.