mirror of
https://github.com/corda/corda.git
synced 2025-06-23 09:25:36 +00:00
CORDA-3644: Scan the CorDapp classloader directly for SerializationWhitelist. (#6014)
* CORDA-3644: Scan the CorDapp classloader directly for SerializationWhitelist. * CORDA-3644: Filter CorDapps from out-of-process node classpaths by their manifest attributes. Also exclude directories and blatant test artifacts. * Fix IRS Demo - its "tests" artifact had a non-standard classifier of "test".
This commit is contained in:
@ -1,6 +1,5 @@
|
||||
package net.corda.node.logging
|
||||
|
||||
import net.corda.core.flows.FlowException
|
||||
import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.flows.InitiatingFlow
|
||||
import net.corda.core.flows.StartableByRPC
|
||||
@ -23,7 +22,13 @@ class ErrorCodeLoggingTests {
|
||||
node.rpc.startFlow(::MyFlow).waitForCompletion()
|
||||
val logFile = node.logFile()
|
||||
|
||||
val linesWithErrorCode = logFile.useLines { lines -> lines.filter { line -> line.contains("[errorCode=") }.filter { line -> line.contains("moreInformationAt=https://errors.corda.net/") }.toList() }
|
||||
val linesWithErrorCode = logFile.useLines { lines ->
|
||||
lines.filter { line ->
|
||||
line.contains("[errorCode=")
|
||||
}.filter { line ->
|
||||
line.contains("moreInformationAt=https://errors.corda.net/")
|
||||
}.toList()
|
||||
}
|
||||
|
||||
assertThat(linesWithErrorCode).isNotEmpty
|
||||
}
|
||||
@ -35,10 +40,11 @@ class ErrorCodeLoggingTests {
|
||||
fun `When logging is set to error level, there are no other levels logged after node startup`() {
|
||||
driver(DriverParameters(notarySpecs = emptyList())) {
|
||||
val node = startNode(startInSameProcess = false, logLevelOverride = "ERROR").getOrThrow()
|
||||
node.rpc.startFlow(::MyFlow).waitForCompletion()
|
||||
val logFile = node.logFile()
|
||||
val lengthAfterStart = logFile.length()
|
||||
node.rpc.startFlow(::MyFlow).waitForCompletion()
|
||||
// An exception thrown in a flow will log at the "INFO" level.
|
||||
assertThat(logFile.length()).isEqualTo(0)
|
||||
assertThat(logFile.length()).isEqualTo(lengthAfterStart)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,6 @@ import net.corda.node.VersionInfo
|
||||
import net.corda.nodeapi.internal.cordapp.CordappLoader
|
||||
import net.corda.nodeapi.internal.coreContractClasses
|
||||
import net.corda.serialization.internal.DefaultWhitelist
|
||||
import org.apache.commons.collections4.map.LRUMap
|
||||
import java.lang.reflect.Modifier
|
||||
import java.math.BigInteger
|
||||
import java.net.URL
|
||||
@ -293,9 +292,7 @@ class JarScanningCordappLoader private constructor(private val cordappJarPaths:
|
||||
}
|
||||
|
||||
private fun findWhitelists(cordappJarPath: RestrictedURL): List<SerializationWhitelist> {
|
||||
val whitelists = URLClassLoader(arrayOf(cordappJarPath.url)).use {
|
||||
ServiceLoader.load(SerializationWhitelist::class.java, it).toList()
|
||||
}
|
||||
val whitelists = ServiceLoader.load(SerializationWhitelist::class.java, appClassLoader).toList()
|
||||
return whitelists.filter {
|
||||
it.javaClass.location == cordappJarPath.url && it.javaClass.name.startsWith(cordappJarPath.qualifiedNamePrefix)
|
||||
} + DefaultWhitelist // Always add the DefaultWhitelist to the whitelist for an app.
|
||||
@ -309,19 +306,21 @@ class JarScanningCordappLoader private constructor(private val cordappJarPaths:
|
||||
return scanResult.getClassesWithSuperclass(MappedSchema::class).instances().toSet()
|
||||
}
|
||||
|
||||
private val cachedScanResult = LRUMap<RestrictedURL, RestrictedScanResult>(1000)
|
||||
|
||||
private fun scanCordapp(cordappJarPath: RestrictedURL): RestrictedScanResult {
|
||||
logger.info("Scanning CorDapp in ${cordappJarPath.url}")
|
||||
return cachedScanResult.computeIfAbsent(cordappJarPath) {
|
||||
val scanResult = ClassGraph().addClassLoader(appClassLoader).overrideClasspath(cordappJarPath.url).enableAllInfo().pooledScan()
|
||||
RestrictedScanResult(scanResult, cordappJarPath.qualifiedNamePrefix)
|
||||
}
|
||||
val cordappElement = cordappJarPath.url.toString()
|
||||
logger.info("Scanning CorDapp in $cordappElement")
|
||||
val scanResult = ClassGraph()
|
||||
.filterClasspathElements { elt -> elt == cordappElement }
|
||||
.overrideClassLoaders(appClassLoader)
|
||||
.ignoreParentClassLoaders()
|
||||
.enableAllInfo()
|
||||
.pooledScan()
|
||||
return RestrictedScanResult(scanResult, cordappJarPath.qualifiedNamePrefix)
|
||||
}
|
||||
|
||||
private fun <T : Any> loadClass(className: String, type: KClass<T>): Class<out T>? {
|
||||
return try {
|
||||
appClassLoader.loadClass(className).asSubclass(type.java)
|
||||
Class.forName(className, false, appClassLoader).asSubclass(type.java)
|
||||
} catch (e: ClassCastException) {
|
||||
logger.warn("As $className must be a sub-type of ${type.java.name}")
|
||||
null
|
||||
|
Reference in New Issue
Block a user