Affects: 6.1.1+
(Spring Boot 3.2.x)
Reproducer: reproducer.zip
Problem
Calling any suspend function in a service that is proxied by SpringCGLIB might throw an exception due to missing classes in the classpath (java.lang.ClassNotFoundException: org.reactivestreams.Publisher
). For some reason this only occurs when another function in the specified class is getting changed too. E.g. if there is an @Transactional
method, only then this bug occurs.
Expected Behavior
When calling a suspend function, the call should not be re-written on a non-reactive stack regardeless of other functions in the , similar to how it worked in 6.0.x
.
Actual Behavior
When another function in the service forces some new behavior to be introduced by the SpringCGLIB proxy, then the suspend function should be left untouched in a non-reactive application.
Reproducer
Crashes with SB 3.2.X, works with SB 3.1.X:
import jakarta.transaction.Transactional
import kotlinx.coroutines.runBlocking
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.stereotype.Service
@SpringBootApplication
class DemoCoroutinesCrashApplication
@Service
class DemoService {
@Transactional
fun somethingTransaction() {
}
suspend fun mySuspendFunction(): Int {
return 123
}
}
@SpringBootTest
class DemoCoroutinesCrashApplicationTests {
@Autowired
private lateinit var demoService: DemoService
@Test
fun `should not crash`(): Unit = runBlocking {
demoService.mySuspendFunction()
}
}