Scala 2.9 Bridge Method

I am using Scala 2.9.1

I defined the Logging trait as such:

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

And I have a JMSPublisher class that mixes in the Logging dash:

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

All of this compiles perfectly. My problem is that I have a user who wants to load JMSPublisher in Spring. It uses Spring 2.5.6.

When the ApplicationContext loads during startup, the application crashes with an IllegalStateException, complaining that it cannot find the bridge method associated with my logging characteristic.

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

This code worked under Scala -2.8, and I heard that Scala is a sign of marking, which has some methods as a bridge in 2.9. I think this is what leads to Spring error. I cannot upgrade to Scala -2.9 if my class cannot be loaded by Spring.

Has anyone encountered this problem? Is there a fix or workaround?

+6
source share
1 answer

We saw the same thing. I have never figured out what change in Scala 2.9.x caused this, but I think the real problem is in Spring itself.

When you mix a dash with a class, synthetic methods are added to the class, marked in byte code as bridge methods, which proceed to the implementation of the method in the attribute.

Java also adds bridge methods to classes when a subclass overrides a method in a superclass or interface, but refines the type of return value. Since the return type is part of the method signature at the bytecode level, a forwarding method is needed, so clients who know only the signature of the parent method can still call the method in a subclass. (More: what is java.lang.reflect.Method.isBridge () used for? )

Spring validates bytecode for bridge methods for the reasons described in A Bridge Too Far . The title of this article is ironic - Spring calls it β€œa great example of Spring addressing the tight infrastructure problems faced by Java developers and integrating them into the application stack,” but he makes too many assumptions about the source of the bytecode and, even worse, can't to be disconnected.

A short-term workaround is to avoid mixing traits in the classes that you use in Spring. You must make a mistake using Spring so that you can disable this check for non-Java bytecode.

+3
source

Source: https://habr.com/ru/post/900813/


All Articles