mirror of
https://github.com/corda/corda.git
synced 2025-01-20 03:36:29 +00:00
Remove CordApps JARs from node classpath [CORDA-1135] (#2691)
This commit is contained in:
parent
a24a2105b1
commit
2cff495553
@ -52,13 +52,19 @@ data class LedgerTransaction @JvmOverloads constructor(
|
||||
|
||||
private companion object {
|
||||
@JvmStatic
|
||||
private fun createContractFor(className: ContractClassName): Try<Contract> {
|
||||
return Try.on { this::class.java.classLoader.loadClass(className).asSubclass(Contract::class.java).getConstructor().newInstance() }
|
||||
private fun createContractFor(className: ContractClassName, classLoader: ClassLoader?): Try<Contract> {
|
||||
return Try.on {
|
||||
(classLoader ?: this::class.java.classLoader)
|
||||
.loadClass(className)
|
||||
.asSubclass(Contract::class.java)
|
||||
.getConstructor()
|
||||
.newInstance()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val contracts: Map<ContractClassName, Try<Contract>> = (inputs.map { it.state.contract } + outputs.map { it.contract })
|
||||
.toSet().map { it to createContractFor(it) }.toMap()
|
||||
private val contracts: Map<ContractClassName, Try<Contract>> = (inputs.map { it.state } + outputs)
|
||||
.map { it.contract to createContractFor(it.contract, it.data::class.java.classLoader) }.toMap()
|
||||
|
||||
val inputStates: List<ContractState> get() = inputs.map { it.state.data }
|
||||
|
||||
|
@ -34,7 +34,7 @@ abstract class AbstractCashSelection {
|
||||
fun getInstance(metadata: () -> java.sql.DatabaseMetaData): AbstractCashSelection {
|
||||
return instance.get() ?: {
|
||||
val _metadata = metadata()
|
||||
val cashSelectionAlgos = ServiceLoader.load(AbstractCashSelection::class.java).toList()
|
||||
val cashSelectionAlgos = ServiceLoader.load(AbstractCashSelection::class.java, this::class.java.classLoader).toList()
|
||||
val cashSelectionAlgo = cashSelectionAlgos.firstOrNull { it.isCompatible(_metadata) }
|
||||
cashSelectionAlgo?.let {
|
||||
instance.set(cashSelectionAlgo)
|
||||
|
@ -52,7 +52,8 @@ class CordaPersistence(
|
||||
val dataSource: DataSource,
|
||||
databaseConfig: DatabaseConfig,
|
||||
schemas: Set<MappedSchema>,
|
||||
attributeConverters: Collection<AttributeConverter<*, *>> = emptySet()
|
||||
attributeConverters: Collection<AttributeConverter<*, *>> = emptySet(),
|
||||
val cordappClassLoader: ClassLoader? = null
|
||||
) : Closeable {
|
||||
companion object {
|
||||
private val log = contextLogger()
|
||||
@ -61,7 +62,7 @@ class CordaPersistence(
|
||||
private val defaultIsolationLevel = databaseConfig.transactionIsolationLevel
|
||||
val hibernateConfig: HibernateConfiguration by lazy {
|
||||
transaction {
|
||||
HibernateConfiguration(schemas, databaseConfig, attributeConverters)
|
||||
HibernateConfiguration(schemas, databaseConfig, attributeConverters, cordappClassLoader)
|
||||
}
|
||||
}
|
||||
val entityManagerFactory get() = hibernateConfig.sessionFactoryForRegisteredSchemas
|
||||
|
@ -9,6 +9,8 @@ import org.hibernate.boot.MetadataSources
|
||||
import org.hibernate.boot.model.naming.Identifier
|
||||
import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
|
||||
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder
|
||||
import org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService
|
||||
import org.hibernate.cfg.Configuration
|
||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment
|
||||
@ -26,7 +28,8 @@ import javax.persistence.AttributeConverter
|
||||
class HibernateConfiguration(
|
||||
schemas: Set<MappedSchema>,
|
||||
private val databaseConfig: DatabaseConfig,
|
||||
private val attributeConverters: Collection<AttributeConverter<*, *>>
|
||||
private val attributeConverters: Collection<AttributeConverter<*, *>>,
|
||||
val cordappClassLoader: ClassLoader? = null
|
||||
) {
|
||||
companion object {
|
||||
private val logger = contextLogger()
|
||||
@ -60,7 +63,7 @@ class HibernateConfiguration(
|
||||
schema.mappedTypes.forEach { config.addAnnotatedClass(it) }
|
||||
}
|
||||
|
||||
val sessionFactory = buildSessionFactory(config, metadataSources, databaseConfig.serverNameTablePrefix)
|
||||
val sessionFactory = buildSessionFactory(config, metadataSources, databaseConfig.serverNameTablePrefix, cordappClassLoader)
|
||||
logger.info("Created session factory for schemas: $schemas")
|
||||
|
||||
// export Hibernate JMX statistics
|
||||
@ -87,8 +90,15 @@ class HibernateConfiguration(
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildSessionFactory(config: Configuration, metadataSources: MetadataSources, tablePrefix: String): SessionFactory {
|
||||
private fun buildSessionFactory(config: Configuration, metadataSources: MetadataSources, tablePrefix: String, cordappClassLoader: ClassLoader?): SessionFactory {
|
||||
config.standardServiceRegistryBuilder.applySettings(config.properties)
|
||||
|
||||
if (cordappClassLoader != null) {
|
||||
config.standardServiceRegistryBuilder.addService(
|
||||
ClassLoaderService::class.java,
|
||||
ClassLoaderServiceImpl(cordappClassLoader))
|
||||
}
|
||||
|
||||
val metadata = metadataSources.getMetadataBuilder(config.standardServiceRegistryBuilder.build()).run {
|
||||
applyPhysicalNamingStrategy(object : PhysicalNamingStrategyStandardImpl() {
|
||||
override fun toPhysicalTableName(name: Identifier?, context: JdbcEnvironment?): Identifier {
|
||||
|
@ -18,7 +18,8 @@ private typealias MapCreationFunction = (Map<*, *>) -> Map<*, *>
|
||||
* Serialization / deserialization of certain supported [Map] types.
|
||||
*/
|
||||
class MapSerializer(private val declaredType: ParameterizedType, factory: SerializerFactory) : AMQPSerializer<Any> {
|
||||
override val type: Type = declaredType as? DeserializedParameterizedType ?: DeserializedParameterizedType.make(SerializerFactory.nameForType(declaredType))
|
||||
override val type: Type = (declaredType as? DeserializedParameterizedType) ?:
|
||||
DeserializedParameterizedType.make(SerializerFactory.nameForType(declaredType), factory.classloader)
|
||||
override val typeDescriptor: Symbol = Symbol.valueOf(
|
||||
"$DESCRIPTOR_DOMAIN:${factory.fingerPrinter.fingerprint(type)}")
|
||||
|
||||
|
@ -81,8 +81,6 @@ public class CordaCaplet extends Capsule {
|
||||
T cp = super.attribute(attr);
|
||||
|
||||
(new File(baseDir, "cordapps")).mkdir();
|
||||
augmentClasspath((List<Path>) cp, new File(baseDir, "cordapps"));
|
||||
augmentClasspath((List<Path>) cp, new File(baseDir, "plugins"));
|
||||
// Add additional directories of JARs to the classpath (at the end). e.g. for JDBC drivers
|
||||
try {
|
||||
List<String> jarDirs = nodeConfig.getStringList("jarDirs");
|
||||
|
@ -639,7 +639,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
|
||||
protected open fun initialiseDatabasePersistence(schemaService: SchemaService, identityService: IdentityService): CordaPersistence {
|
||||
val props = configuration.dataSourceProperties
|
||||
if (props.isEmpty()) throw DatabaseConfigurationException("There must be a database configured.")
|
||||
val database = configureDatabase(props, configuration.database, identityService, schemaService)
|
||||
val database = configureDatabase(props, configuration.database, identityService, schemaService, cordappLoader.appClassLoader)
|
||||
// Now log the vendor string as this will also cause a connection to be tested eagerly.
|
||||
logVendorString(database, log)
|
||||
runOnStop += database::close
|
||||
@ -874,7 +874,8 @@ internal class NetworkMapCacheEmptyException : Exception()
|
||||
fun configureDatabase(hikariProperties: Properties,
|
||||
databaseConfig: DatabaseConfig,
|
||||
identityService: IdentityService,
|
||||
schemaService: SchemaService = NodeSchemaService()): CordaPersistence {
|
||||
schemaService: SchemaService = NodeSchemaService(),
|
||||
cordappClassLoader: ClassLoader? = null): CordaPersistence {
|
||||
// Register the AbstractPartyDescriptor so Hibernate doesn't warn when encountering AbstractParty. Unfortunately
|
||||
// Hibernate warns about not being able to find a descriptor if we don't provide one, but won't use it by default
|
||||
// so we end up providing both descriptor and converter. We should re-examine this in later versions to see if
|
||||
@ -882,5 +883,5 @@ fun configureDatabase(hikariProperties: Properties,
|
||||
JavaTypeDescriptorRegistry.INSTANCE.addDescriptor(AbstractPartyDescriptor(identityService))
|
||||
val dataSource = DataSourceFactory.createDataSource(hikariProperties)
|
||||
val attributeConverters = listOf(AbstractPartyToX500NameAsStringConverter(identityService))
|
||||
return CordaPersistence(dataSource, databaseConfig, schemaService.schemaOptions.keys, attributeConverters)
|
||||
return CordaPersistence(dataSource, databaseConfig, schemaService.schemaOptions.keys, attributeConverters, cordappClassLoader)
|
||||
}
|
||||
|
@ -43,8 +43,7 @@ import kotlin.streams.toList
|
||||
*/
|
||||
class CordappLoader private constructor(private val cordappJarPaths: List<RestrictedURL>) {
|
||||
val cordapps: List<Cordapp> by lazy { loadCordapps() + coreCordapp }
|
||||
|
||||
internal val appClassLoader: ClassLoader = URLClassLoader(cordappJarPaths.stream().map { it.url }.toTypedArray(), javaClass.classLoader)
|
||||
val appClassLoader: ClassLoader = URLClassLoader(cordappJarPaths.stream().map { it.url }.toTypedArray(), javaClass.classLoader)
|
||||
|
||||
init {
|
||||
if (cordappJarPaths.isEmpty()) {
|
||||
|
@ -160,7 +160,7 @@ object NodeInterestRates {
|
||||
}
|
||||
|
||||
private fun addDefaultFixes() {
|
||||
knownFixes = parseFile(IOUtils.toString(Thread.currentThread().contextClassLoader.getResourceAsStream("net/corda/irs/simulation/example.rates.txt"), Charsets.UTF_8.name()))
|
||||
knownFixes = parseFile(IOUtils.toString(this::class.java.classLoader.getResourceAsStream("net/corda/irs/simulation/example.rates.txt"), Charsets.UTF_8.name()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ open class MockServices private constructor(
|
||||
val cordappLoader = CordappLoader.createWithTestPackages(cordappPackages)
|
||||
val dataSourceProps = makeTestDataSourceProperties()
|
||||
val schemaService = NodeSchemaService(cordappLoader.cordappSchemas)
|
||||
val database = configureDatabase(dataSourceProps, DatabaseConfig(), identityService, schemaService)
|
||||
val database = configureDatabase(dataSourceProps, DatabaseConfig(), identityService, schemaService, cordappLoader.appClassLoader)
|
||||
val mockService = database.transaction {
|
||||
object : MockServices(cordappLoader, identityService, networkParameters, initialIdentity, moreKeys) {
|
||||
override val vaultService: VaultService = makeVaultService(database.hibernateConfig, schemaService)
|
||||
|
Loading…
Reference in New Issue
Block a user