2011-11-04 12 views
6

sto usando Scala 2.9.1Scala 2.9 Ponte-Metodo

ho definito un tratto di registrazione in quanto tale:

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

E io avere una classe JMSPublisher che mescola-nel tratto di registrazione :

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

Questo tutto va bene. Il mio problema è che ho un utente che vuole caricare il mio JMSPublisher in Primavera. Sta usando Spring 2.5.6.

Quando ApplicationContext viene caricato durante l'avvio, l'app si arresta in modo anomalo con un IllegalStateException, lamentandosi del fatto che non è possibile trovare un metodo con bridge correlato al mio tratto di registrazione.

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

Questo codice ha funzionato sotto Scala-2.8, e ho sentito che sta segnando Scala tratto che hanno alcuni metodi come ponte in 2.9. Penso che questo sia ciò che sta causando il fallimento di Spring. Non posso aggiornare a Scala-2.9 se la mia classe non può essere caricata da Spring.

Qualcuno si è imbattuto in questo problema? C'è qualche soluzione o soluzione?

+0

Penso che stiamo ottenendo qualcosa di simile - fortunatamente non sta interessando la nostra app, solo Spring IDE che contrassegna alcuni bean con errori in quanto lamenta che alcuni metodi definiti dai tratti non esistono. – Nick

+1

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

risposta

3

Abbiamo visto la stessa cosa. Non ho mai capito quale cambiamento in Scala 2.9.x ha attivato, ma penso che il vero problema sia con Spring stessa.

Quando si mescolano un tratto in una classe, la aggiunge metodi di sintesi per la classe, segnati in codice byte come metodi ponte, che in avanti per l'attuazione del metodo nel tratto.

Java aggiunge anche i metodi bridge alle classi, quando una sottoclasse sovrascrive un metodo in una superclasse o in un'interfaccia, ma perfeziona il tipo restituito. Poiché il tipo di ritorno è parte della firma del metodo a livello di bytetec, è necessario un metodo di inoltro in modo che i client che conoscono solo la firma del metodo genitore possano ancora chiamare il metodo nella sottoclasse. (Maggiori dettagli: what java.lang.reflect.Method.isBridge() used for?)

Spring controlla il bytecode per i metodi bridge per le ragioni descritte nell'articolo A Bridge Too Far. Il nome dell'articolo è ironico - Spring lo definisce "un perfetto esempio di Spring che risolve i problemi di infrastruttura hard che gli sviluppatori Java affrontano e li integra nello stack di applicazioni", ma fa troppe ipotesi sulla fonte del bytecode, e peggio, non può essere disabilitato.

Soluzione temporanea a breve termine, consiste nell'evitare di mescolare i tratti nelle classi utilizzate in primavera. Dovresti presentare un bug con Spring per consentire di disabilitare questo controllo per bytecode non Java.

Problemi correlati