mirror of
https://github.com/corda/corda.git
synced 2025-01-30 16:14:39 +00:00
CORDA-2653 - ensure that during initialisation of a Corda Service, the current thread has a context classloader. (#4907)
This commit is contained in:
parent
eb7928d761
commit
52ec48d63d
@ -575,6 +575,15 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
|
||||
|
||||
private fun installCordaServices() {
|
||||
val loadedServices = cordappLoader.cordapps.flatMap { it.services }
|
||||
|
||||
// This sets the Cordapp classloader on the contextClassLoader of the current thread, prior to initializing services
|
||||
// Needed because of bug CORDA-2653 - some Corda services can utilise third-party libraries that require access to
|
||||
// the Thread context class loader
|
||||
|
||||
val oldContextClassLoader : ClassLoader? = Thread.currentThread().contextClassLoader
|
||||
try {
|
||||
Thread.currentThread().contextClassLoader = cordappLoader.appClassLoader
|
||||
|
||||
loadedServices.forEach {
|
||||
try {
|
||||
installCordaService(it)
|
||||
@ -591,6 +600,9 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
|
||||
log.error("Unable to install Corda service ${it.name}", e)
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
Thread.currentThread().contextClassLoader = oldContextClassLoader
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -26,10 +26,7 @@ import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFailsWith
|
||||
import kotlin.test.assertNotEquals
|
||||
import kotlin.test.assertTrue
|
||||
import kotlin.test.*
|
||||
|
||||
class CordaServiceTest {
|
||||
private lateinit var mockNet: MockNetwork
|
||||
@ -77,6 +74,12 @@ class CordaServiceTest {
|
||||
service.startServiceFlowAndTrack()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Corda service can access a non-null thread context classloader`() {
|
||||
val service = nodeA.services.cordaService(CordaServiceThatRequiresThreadContextClassLoader::class.java)
|
||||
service.thatWeCanAccessClassLoader()
|
||||
}
|
||||
|
||||
/**
|
||||
* Reproduce CORDA-2296
|
||||
* Querying the vault from a services constructor failed because the criteriaBuilder
|
||||
@ -142,4 +145,19 @@ class CordaServiceTest {
|
||||
serviceHub.vaultService.trackBy(ContractState::class.java, criteria)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See: CORDA-2653
|
||||
* This is to check that a corda service is presented with a non-null thread context classloader
|
||||
*/
|
||||
@CordaService
|
||||
class CordaServiceThatRequiresThreadContextClassLoader(val serviceHub: AppServiceHub) : SingletonSerializeAsToken() {
|
||||
init {
|
||||
assertNotNull(Thread.currentThread().contextClassLoader, "thread context classloader should not be null during service initialisation")
|
||||
}
|
||||
|
||||
fun thatWeCanAccessClassLoader() {
|
||||
assertNotNull(Thread.currentThread().contextClassLoader, "thread context classloader should not be null during service initialisation")
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user