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() {
|
private fun installCordaServices() {
|
||||||
val loadedServices = cordappLoader.cordapps.flatMap { it.services }
|
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 {
|
loadedServices.forEach {
|
||||||
try {
|
try {
|
||||||
installCordaService(it)
|
installCordaService(it)
|
||||||
@ -591,6 +600,9 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
|
|||||||
log.error("Unable to install Corda service ${it.name}", e)
|
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.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.*
|
||||||
import kotlin.test.assertFailsWith
|
|
||||||
import kotlin.test.assertNotEquals
|
|
||||||
import kotlin.test.assertTrue
|
|
||||||
|
|
||||||
class CordaServiceTest {
|
class CordaServiceTest {
|
||||||
private lateinit var mockNet: MockNetwork
|
private lateinit var mockNet: MockNetwork
|
||||||
@ -77,6 +74,12 @@ class CordaServiceTest {
|
|||||||
service.startServiceFlowAndTrack()
|
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
|
* Reproduce CORDA-2296
|
||||||
* Querying the vault from a services constructor failed because the criteriaBuilder
|
* Querying the vault from a services constructor failed because the criteriaBuilder
|
||||||
@ -142,4 +145,19 @@ class CordaServiceTest {
|
|||||||
serviceHub.vaultService.trackBy(ContractState::class.java, criteria)
|
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