diff --git a/build.gradle b/build.gradle index 1b752b5088..6524707b9f 100644 --- a/build.gradle +++ b/build.gradle @@ -115,6 +115,7 @@ buildscript { classpath "net.corda.plugins:cordformation:$gradle_plugins_version" classpath "net.corda.plugins:cordapp:$gradle_plugins_version" classpath "net.corda.plugins:api-scanner:$gradle_plugins_version" + classpath "net.corda.plugins:jar-filter:$gradle_plugins_version" classpath "net.sf.proguard:proguard-gradle:$proguard_version" classpath 'com.github.ben-manes:gradle-versions-plugin:0.15.0' classpath "org.jetbrains.kotlin:kotlin-noarg:$kotlin_version" diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index b47259bd1c..6ed0edaf54 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -14,21 +14,8 @@ buildscript { ext { guava_version = constants.getProperty("guavaVersion") - kotlin_version = constants.getProperty("kotlinVersion") - proguard_version = constants.getProperty("proguardVersion") assertj_version = '3.9.1' junit_version = '4.12' - asm_version = '6.2' - } - - repositories { - mavenLocal() - mavenCentral() - jcenter() - } - dependencies { - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath "net.sf.proguard:proguard-gradle:$proguard_version" } } @@ -38,23 +25,9 @@ repositories { } allprojects { - tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { - kotlinOptions { - languageVersion = "1.2" - apiVersion = "1.2" - jvmTarget = "1.8" - javaParameters = true // Useful for reflection. - } - } - tasks.withType(Test) { // Prevent the project from creating temporary files outside of the build directory. systemProperty 'java.io.tmpdir', buildDir.absolutePath - - // Tell the tests where Gradle's current module cache is. - // We need the tests to share this module cache to prevent the - // Gradle Test-Kit from downloading its own copy of Kotlin etc. - systemProperty 'test.gradle.user.home', project.gradle.gradleUserHomeDir } } diff --git a/buildSrc/jarfilter/README.md b/buildSrc/jarfilter/README.md deleted file mode 100644 index 0f627cc415..0000000000 --- a/buildSrc/jarfilter/README.md +++ /dev/null @@ -1,218 +0,0 @@ -# JarFilter - -Deletes annotated elements at the byte-code level from a JAR of Java/Kotlin code. In the case of Kotlin -code, it also modifies the `@kotlin.Metadata` annotations not to contain any functions, properties or -type aliases that have been deleted. This prevents the Kotlin compiler from successfully compiling against -any elements which no longer exist. - -We use this plugin together with ProGuard to generate Corda's `core-deterministic` and `serialization-deterministic` -modules. See [here](../../docs/source/deterministic-modules.rst) for more information. - -## Usage -This plugin is automatically available on Gradle's classpath since it lives in Corda's `buildSrc` directory. -You need only `import` the plugin's task classes in the `build.gradle` file and then use them to declare -tasks. - -You can enable the tasks' logging output using Gradle's `--info` or `--debug` command-line options. - -### The `JarFilter` task -The `JarFilter` task removes unwanted elements from `class` files, namely: -- Deleting both Java methods/fields and Kotlin functions/properties/type aliases. -- Stubbing out methods by replacing the byte-code of their implementations. -- Removing annotations from classes/methods/fields. - -It supports the following configuration options: -```gradle -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - // Task(s) whose JAR outputs should be filtered. - jars jar - - // The annotations assigned to each filtering role. For example: - annotations { - forDelete = [ - "org.testing.DeleteMe" - ] - forStub = [ - "org.testing.StubMeOut" - ] - forRemove = [ - "org.testing.RemoveMe" - ] - } - - // Location for filtered JARs. Defaults to "$buildDir/filtered-libs". - outputDir file(...) - - // Whether the timestamps on the JARs' entries should be preserved "as is" - // or set to a platform-independent constant value (1st February 1980). - preserveTimestamps = {true|false} - - // The maximum number of times (>= 1) to pass the JAR through the filter. - maxPasses = 5 - - // Writes more information about each pass of the filter. - verbose = {true|false} -} -``` - -You can specify as many annotations for each role as you like. The only constraint is that a given -annotation cannot be assigned to more than one role. - -#### Removing unwanted default parameter values -It is possible to assign non-deterministic expressions as default values for Kotlin constructors and functions. For -example: -```kotlin -data class UniqueIdentifier(val externalId: String? = null, val id: UUID = UUID.randomUUID()) -``` - -The Kotlin compiler will generate _two_ constructors in this case: -``` -UniqueIdentifier(String?, UUID) -UniqueIdentifier(String?, UUID, Int, DefaultConstructorMarker) -``` - -The first constructor is the primary constructor that we would expect (and which we'd like to keep), whereas the -second is a public synthetic constructor that Kotlin applications invoke to handle the different combinations of -default parameter values. Unfortunately, this synthetic constructor is therefore also part of the Kotlin ABI and -so we _cannot_ rewrite the class like this to remove the default values: -```kotlin -// THIS REFACTOR WOULD BREAK THE KOTLIN ABI! -data class UniqueIdentifier(val externalId: String?, val id: UUID) { - constructor(externalId: String?) : this(externalId, UUID.randomUUID()) - constructor() : this(null) -} -``` - -The refactored class would have the following constructors, and would require client applications to be recompiled: -``` -UniqueIdentifier(String?, UUID) -UniqueIdentifier(String?) -UniqueIdentifier() -``` - -We therefore need to keep the default constructor parameters in order to preserve the ABI for the unfiltered code, -which in turn means that `JarFilter` will need to delete only the synthetic constructor and leave the primary -constructor intact. However, Kotlin does not currently allow us to annotate _specific_ constructors - see -[KT-22524](https://youtrack.jetbrains.com/issue/KT-22524). Until it does, `JarFilter` will perform an initial -"sanitising" pass over the JAR file to remove any unwanted annotations from the primary constructors. These unwanted -annotations are configured in the `JarFilter` task definition: -```gradle -task jarFilter(type: JarFilterTask) { - ... - annotations { - ... - forSanitise = [ - "org.testing.DeleteMe" - ] - } -} -``` - -This allows us to annotate the `UniqueIdentifier` class like this: -```kotlin -data class UniqueIdentifier @DeleteMe constructor(val externalId: String? = null, val id: UUID = UUID.randomUUID()) -``` - -to generate these constructors: -``` -UniqueIdentifier(String?, UUID) -@DeleteMe UniqueIdentifier(String?, UUID, Int, DefaultConstructorMarker) -``` - -We currently **do not** sanitise annotations from functions with default parameter values, although (in theory) these -may also be non-deterministic. We will need to extend the sanitation pass to include such functions if/when the need -arises. At the moment, deleting such functions _entirely_ is enough, whereas also deleting a primary constructor means -that we can no longer create instances of that class either. - -### The `MetaFixer` task -The `MetaFixer` task updates the `@kotlin.Metadata` annotations by removing references to any functions, -constructors, properties or nested classes that no longer exist in the byte-code. This is primarily to -"repair" Kotlin library code that has been processed by ProGuard. - -Kotlin type aliases exist only inside `@Metadata` and so are unaffected by this task. Similarly, the -constructors for Kotlin's annotation classes don't exist in the byte-code either because Java annotations -are interfaces really. The `MetaFixer` task will therefore ignore annotations' constructors too. - -It supports these configuration options: -```gradle -import net.corda.gradle.jarfilter.MetaFixerTask -task metafix(type: MetaFixerTask) { - // Task(s) whose JAR outputs should be fixed. - jars jar - - // Location for fixed JARs. Defaults to "$buildDir/metafixed-libs" - outputDir file(...) - - // Tag to be appended to the JAR name. Defaults to "-metafixed". - suffix = "..." - - // Whether the timestamps on the JARs' entries should be preserved "as is" - // or set to a platform-independent constant value (1st February 1980). - preserveTimestamps = {true|false} -} -``` - -## Implementation Details - -### Code Coverage -You can generate a JaCoCo code coverage report for the unit tests using: -```bash -$ cd buildSrc -$ ../gradlew jarfilter:jacocoTestReport -``` - -### Kotlin Metadata -The Kotlin compiler encodes information about each class inside its `@kotlin.Metadata` annotation. - -```kotlin -import kotlin.annotation.AnnotationRetention.* - -@Retention(RUNTIME) -annotation class Metadata { - val k: Int = 1 - val d1: Array = [] - val d2: Array = [] - // ... -} -``` - -This is an internal feature of Kotlin which is read by Kotlin Reflection. There is no public API -for writing this information, and the content format of arrays `d1` and `d2` depends upon the -"class kind" `k`. For the kinds that we are interested in, `d1` contains a buffer of ProtoBuf -data and `d2` contains an array of `String` identifiers which the ProtoBuf data refers to by index. - -Although ProtoBuf generates functions for both reading and writing the data buffer, the -Kotlin Reflection artifact only contains the functions for reading. This is almost certainly -because the writing functionality has been removed from the `kotlin-reflect` JAR using -ProGuard. However, the complete set of generated ProtoBuf classes is still available in the -`kotlin-compiler-embeddable` JAR. The `jarfilter:kotlin-metadata` module uses ProGuard to -extracts these classes into a new `kotlin-metdata` JAR, discarding any classes that the -ProtoBuf ones do not need and obfuscating any other ones that they do. - -The custom `kotlin-metadata` object was originally created as a workaround for -[KT-18621](https://youtrack.jetbrains.com/issue/KT-18621). However, reducing the number of unwanted -classes on the classpath anyway can only be a Good Thing(TM). - -At runtime, `JarFilter` decompiles the ProtoBuf buffer into POJOs, deletes the elements that -no longer exist in the byte-code and then recompiles the POJOs into a new ProtoBuf buffer. The -`@Metadata` annotation is then rewritten using this new buffer for `d1` and the _original_ `String` -identifiers for `d2`. While some of these identifiers are very likely no longer used after this, -removing them would also require re-indexing the ProtoBuf data. It is therefore simpler just to -leave them as harmless cruft in the byte-code's constant pool. - -The majority of `JarFilter`'s unit tests use Kotlin and Java reflection and so should not be -brittle as Kotlin evolves because `kotlin-reflect` is public API. Also, Kotlin's requirement that -it remain backwards-compatible with itself should imply that the ProtoBuf logic shouldn't change -(much). However, the ProtoBuf classes are still internal to Kotlin and so it _is_ possible that they -will occasionally move between packages. This has already happened for Kotlin 1.2.3x -> 1.2.4x, but -I am hoping this means that they will not move again for a while. - -### JARs vs ZIPs -The `JarFilter` and `MetaFixer` tasks _deliberately_ use `ZipFile` and `ZipOutputStream` rather -than `JarInputStream` and `JarOutputStream` when reading and writing their JAR files. This is to -ensure that the original `META-INF/MANIFEST.MF` files are passed through unaltered. Note also that -there is no `ZipInputStream.getComment()` method, and so we need to use `ZipFile` in order to -preserve any JAR comments. - -Neither `JarFilter` nor `MetaFixer` should change the order of the entries inside the JAR files. diff --git a/buildSrc/jarfilter/build.gradle b/buildSrc/jarfilter/build.gradle deleted file mode 100644 index f4067d6e7a..0000000000 --- a/buildSrc/jarfilter/build.gradle +++ /dev/null @@ -1,46 +0,0 @@ -plugins { - id 'java-gradle-plugin' - id 'jacoco' -} -apply plugin: 'kotlin' - -repositories { - mavenLocal() - mavenCentral() - jcenter() -} - -gradlePlugin { - plugins { - jarFilterPlugin { - id = 'net.corda.plugins.jar-filter' - implementationClass = 'net.corda.gradle.jarfilter.JarFilterPlugin' - } - } -} - -configurations { - jacocoRuntime -} - -processTestResources { - filesMatching('**/build.gradle') { - expand(['kotlin_version': kotlin_version]) - } - filesMatching('gradle.properties') { - expand(['jacocoAgent': configurations.jacocoRuntime.asPath.replace('\\', '/'), - 'buildDir': buildDir]) - } -} - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" - implementation project(':jarfilter:kotlin-metadata') - implementation "org.ow2.asm:asm:$asm_version" - testImplementation "org.jetbrains.kotlin:kotlin-test-junit" - testImplementation "org.jetbrains.kotlin:kotlin-reflect" - testImplementation "org.assertj:assertj-core:$assertj_version" - testImplementation "junit:junit:$junit_version" - testImplementation project(':jarfilter:unwanteds') - jacocoRuntime "org.jacoco:org.jacoco.agent:${jacoco.toolVersion}:runtime" -} diff --git a/buildSrc/jarfilter/kotlin-metadata/build.gradle b/buildSrc/jarfilter/kotlin-metadata/build.gradle deleted file mode 100644 index b2b685dca1..0000000000 --- a/buildSrc/jarfilter/kotlin-metadata/build.gradle +++ /dev/null @@ -1,84 +0,0 @@ -plugins { - id 'base' -} - -description "Kotlin's metadata-handling classes" - -repositories { - mavenLocal() - jcenter() -} - -configurations { - proguard - runtime - configurations.default.extendsFrom runtime -} - -dependencies { - proguard "org.jetbrains.kotlin:kotlin-compiler-embeddable:$kotlin_version" - proguard "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - runtime "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" -} - -def javaHome = System.getProperty('java.home') -def originalJar = configurations.proguard.files.find { it.name.startsWith("kotlin-compiler-embeddable") } - -import proguard.gradle.ProGuardTask -task metadata(type: ProGuardTask) { - injars originalJar, filter: 'META-INF/MANIFEST.MF,META-INF/metadata*.kotlin_module,**.class' - outjars "$buildDir/libs/${project.name}-${kotlin_version}.jar" - - libraryjars "$javaHome/lib/rt.jar" - libraryjars "$javaHome/../lib/tools.jar" - configurations.proguard.forEach { - if (originalJar != it) { - libraryjars it.path, filter: '!META-INF/versions/**' - } - } - - keepattributes '*' - dontoptimize - verbose - - dontwarn 'com.sun.jna.**' - dontwarn 'org.jetbrains.annotations.**' - dontwarn 'org.jetbrains.kotlin.com.intellij.**' - dontwarn 'org.jetbrains.kotlin.com.google.j2objc.annotations.**' - dontwarn 'org.jetbrains.kotlin.com.google.errorprone.annotations.**' - dontnote - - keep 'class org.jetbrains.kotlin.load.java.JvmAnnotationNames { *; }' - keep 'class org.jetbrains.kotlin.metadata.ProtoBuf { *; }', includedescriptorclasses: true - keep 'class org.jetbrains.kotlin.metadata.ProtoBuf$* { *; }', includedescriptorclasses: true - keep 'class org.jetbrains.kotlin.metadata.deserialization.** { *; }', includedescriptorclasses: true - keep 'class org.jetbrains.kotlin.metadata.jvm.** { *; }', includedescriptorclasses: true - keep 'class org.jetbrains.kotlin.protobuf.** { *; }', includedescriptorclasses: true -} -def metadataJar = metadata.outputs.files.singleFile - -task validate(type: ProGuardTask) { - injars metadataJar - libraryjars "$javaHome/lib/rt.jar" - configurations.runtime.forEach { - libraryjars it.path, filter: '!META-INF/versions/**' - } - - keepattributes '*' - dontpreverify - dontobfuscate - dontoptimize - verbose - - dontwarn 'org.jetbrains.kotlin.com.google.errorprone.annotations.**' - dontnote - - keep 'class *' -} - -artifacts { - 'default' file: metadataJar, name: project.name, type: 'jar', extension: 'jar', builtBy: metadata -} - -defaultTasks "metadata" -metadata.finalizedBy validate diff --git a/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/Elements.kt b/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/Elements.kt deleted file mode 100644 index 17810136a8..0000000000 --- a/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/Elements.kt +++ /dev/null @@ -1,181 +0,0 @@ -@file:JvmName("Elements") -package net.corda.gradle.jarfilter - -import org.jetbrains.kotlin.metadata.ProtoBuf -import org.jetbrains.kotlin.metadata.deserialization.Flags.* -import org.jetbrains.kotlin.metadata.deserialization.NameResolver -import org.jetbrains.kotlin.metadata.deserialization.TypeTable -import org.jetbrains.kotlin.metadata.deserialization.returnType -import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf -import org.jetbrains.kotlin.metadata.jvm.deserialization.ClassMapperLite -import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil -import org.objectweb.asm.Opcodes.ACC_SYNTHETIC -import java.util.* - -private const val DEFAULT_CONSTRUCTOR_MARKER = "ILkotlin/jvm/internal/DefaultConstructorMarker;" -private const val DEFAULT_FUNCTION_MARKER = "ILjava/lang/Object;" -private const val DUMMY_PASSES = 1 - -private val DECLARES_DEFAULT_VALUE_MASK: Int = DECLARES_DEFAULT_VALUE.toFlags(true).inv() - -abstract class Element(val name: String, val descriptor: String) { - private var lifetime: Int = DUMMY_PASSES - - open val isExpired: Boolean get() = --lifetime < 0 -} - - -class MethodElement(name: String, descriptor: String, val access: Int = 0) : Element(name, descriptor) { - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other?.javaClass != javaClass) return false - other as MethodElement - return other.name == name && other.descriptor == descriptor - } - override fun hashCode(): Int = Objects.hash(name, descriptor) - override fun toString(): String = "MethodElement[name=$name, descriptor=$descriptor, access=$access]" - override val isExpired: Boolean get() = access == 0 && super.isExpired - val isConstructor: Boolean get() = isObjectConstructor || isClassConstructor - val isClassConstructor: Boolean get() = name == "" - val isObjectConstructor: Boolean get() = name == "" - val isVoidFunction: Boolean get() = !isConstructor && descriptor.endsWith(")V") - - private val suffix: String - val visibleName: String - val signature: String = name + descriptor - - init { - val idx = name.indexOf('$') - visibleName = if (idx == -1) name else name.substring(0, idx) - suffix = if (idx == -1) "" else name.drop(idx + 1) - } - - fun isKotlinSynthetic(vararg tags: String): Boolean = (access and ACC_SYNTHETIC) != 0 && tags.contains(suffix) - fun asKotlinNonDefaultConstructor(): MethodElement? { - val markerIdx = descriptor.indexOf(DEFAULT_CONSTRUCTOR_MARKER) - return if (markerIdx >= 0) { - MethodElement(name, descriptor.removeRange(markerIdx, markerIdx + DEFAULT_CONSTRUCTOR_MARKER.length)) - } else { - null - } - } -} - - -/** - * A class cannot have two fields with the same name but different types. However, - * it can define extension functions and properties. - */ -class FieldElement(name: String, descriptor: String = "?", val extension: String = "()") : Element(name, descriptor) { - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other?.javaClass != javaClass) return false - other as FieldElement - return other.name == name && other.extension == extension - } - override fun hashCode(): Int = Objects.hash(name, extension) - override fun toString(): String = "FieldElement[name=$name, descriptor=$descriptor, extension=$extension]" - override val isExpired: Boolean get() = descriptor == "?" && super.isExpired -} - -val String.extensionType: String get() = substring(0, 1 + indexOf(')')) - -/** - * Returns a fully-qualified class name as it would exist - * in the byte-code, e.g. as "a/b/c/ClassName$Nested". - */ -fun NameResolver.getClassInternalName(idx: Int): String - = getQualifiedClassName(idx).replace('.', '$') - -/** - * Construct the signatures of the synthetic methods that - * Kotlin would create to handle default parameter values. - */ -fun String.toKotlinDefaultConstructor(): String { - val closer = lastIndexOf(')') - return substring(0, closer) + DEFAULT_CONSTRUCTOR_MARKER + substring(closer) -} - -fun String.toKotlinDefaultFunction(classDescriptor: String): String { - val opener = indexOf('(') - val closer = lastIndexOf(')') - return (substring(0, opener) + "\$default(" - + classDescriptor + substring(opener + 1, closer) + DEFAULT_FUNCTION_MARKER - + substring(closer)) -} - -/** - * Convert Kotlin getter/setter method data to [MethodElement] objects. - */ -internal fun JvmProtoBuf.JvmPropertySignature.toGetter(nameResolver: NameResolver): MethodElement? { - return if (hasGetter()) { getter?.toMethodElement(nameResolver) } else { null } -} - -internal fun JvmProtoBuf.JvmPropertySignature.toSetter(nameResolver: NameResolver): MethodElement? { - return if (hasSetter()) { setter?.toMethodElement(nameResolver) } else { null } -} - -internal fun JvmProtoBuf.JvmMethodSignature.toMethodElement(nameResolver: NameResolver) - = MethodElement(nameResolver.getString(name), nameResolver.getString(desc)) - -/** - * This logic is based heavily on [JvmProtoBufUtil.getJvmFieldSignature]. - */ -internal fun JvmProtoBuf.JvmPropertySignature.toFieldElement(property: ProtoBuf.Property, nameResolver: NameResolver, typeTable: TypeTable): FieldElement { - var nameId = property.name - var descId = -1 - - if (hasField()) { - if (field.hasName()) { - nameId = field.name - } - if (field.hasDesc()) { - descId = field.desc - } - } - - val descriptor = if (descId == -1) { - val returnType = property.returnType(typeTable) - if (returnType.hasClassName()) { - ClassMapperLite.mapClass(nameResolver.getQualifiedClassName(returnType.className)) - } else { - "?" - } - } else { - nameResolver.getString(descId) - } - - return FieldElement(nameResolver.getString(nameId), descriptor) -} - -/** - * Rewrites metadata for function and constructor parameters. - */ -internal fun ProtoBuf.Constructor.Builder.updateValueParameters( - updater: (ProtoBuf.ValueParameter) -> ProtoBuf.ValueParameter -): ProtoBuf.Constructor.Builder { - for (idx in 0 until valueParameterList.size) { - setValueParameter(idx, updater(valueParameterList[idx])) - } - return this -} - -internal fun ProtoBuf.Function.Builder.updateValueParameters( - updater: (ProtoBuf.ValueParameter) -> ProtoBuf.ValueParameter -): ProtoBuf.Function.Builder { - for (idx in 0 until valueParameterList.size) { - setValueParameter(idx, updater(valueParameterList[idx])) - } - return this -} - -internal fun ProtoBuf.ValueParameter.clearDeclaresDefaultValue(): ProtoBuf.ValueParameter { - return if (DECLARES_DEFAULT_VALUE.get(flags)) { - toBuilder().setFlags(flags and DECLARES_DEFAULT_VALUE_MASK).build() - } else { - this - } -} - -internal val List.hasAnyDefaultValues - get() = any { DECLARES_DEFAULT_VALUE.get(it.flags) } diff --git a/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/FilterTransformer.kt b/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/FilterTransformer.kt deleted file mode 100644 index 164f3bf5d7..0000000000 --- a/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/FilterTransformer.kt +++ /dev/null @@ -1,356 +0,0 @@ -package net.corda.gradle.jarfilter - -import org.gradle.api.InvalidUserDataException -import org.gradle.api.logging.Logger -import org.objectweb.asm.* -import org.objectweb.asm.Opcodes.* - -/** - * ASM [ClassVisitor] for the JarFilter task that deletes unwanted class elements. - * The unwanted elements have been annotated in advance. Elements that reference - * unwanted elements are also removed to keep the byte-code consistent. Finally, - * the deleted elements are passed to the [MetadataTransformer] so that they can - * be removed from the [kotlin.Metadata] annotation. - * - * This Visitor is applied to the byte-code repeatedly until it has removed - * everything that is no longer wanted. - */ -class FilterTransformer private constructor ( - visitor: ClassVisitor, - logger: Logger, - kotlinMetadata: MutableMap>, - private val removeAnnotations: Set, - private val deleteAnnotations: Set, - private val stubAnnotations: Set, - private val unwantedElements: UnwantedCache, - private val unwantedFields: MutableSet, - private val deletedMethods: MutableSet, - private val stubbedMethods: MutableSet -) : KotlinAfterProcessor(ASM6, visitor, logger, kotlinMetadata), Repeatable { - constructor( - visitor: ClassVisitor, - logger: Logger, - removeAnnotations: Set, - deleteAnnotations: Set, - stubAnnotations: Set, - unwantedElements: UnwantedCache - ) : this( - visitor = visitor, - logger = logger, - kotlinMetadata = mutableMapOf(), - removeAnnotations = removeAnnotations, - deleteAnnotations = deleteAnnotations, - stubAnnotations = stubAnnotations, - unwantedElements = unwantedElements, - unwantedFields = mutableSetOf(), - deletedMethods = mutableSetOf(), - stubbedMethods = mutableSetOf() - ) - - var className: String = "(unknown)" - private set - - val isUnwantedClass: Boolean get() = isUnwantedClass(className) - override val hasUnwantedElements: Boolean - get() = unwantedFields.isNotEmpty() - || deletedMethods.isNotEmpty() - || stubbedMethods.isNotEmpty() - || super.hasUnwantedElements - - private fun isUnwantedClass(name: String): Boolean = unwantedElements.containsClass(name) - private fun hasDeletedSyntheticMethod(name: String): Boolean = deletedMethods.any { method -> - name.startsWith("$className\$${method.visibleName}\$") - } - - override fun recreate(visitor: ClassVisitor) = FilterTransformer( - visitor = visitor, - logger = logger, - kotlinMetadata = kotlinMetadata, - removeAnnotations = removeAnnotations, - deleteAnnotations = deleteAnnotations, - stubAnnotations = stubAnnotations, - unwantedElements = unwantedElements, - unwantedFields = unwantedFields, - deletedMethods = deletedMethods, - stubbedMethods = stubbedMethods - ) - - override fun visit(version: Int, access: Int, clsName: String, signature: String?, superName: String?, interfaces: Array?) { - className = clsName - logger.info("Class {}", clsName) - super.visit(version, access, clsName, signature, superName, interfaces) - } - - override fun visitAnnotation(descriptor: String, visible: Boolean): AnnotationVisitor? { - if (removeAnnotations.contains(descriptor)) { - logger.info("- Removing annotation {}", descriptor) - return null - } else if (deleteAnnotations.contains(descriptor)) { - if (unwantedElements.addClass(className)) { - logger.info("- Identified class {} as unwanted", className) - } - } - return super.visitAnnotation(descriptor, visible) - } - - override fun visitField(access: Int, fieldName: String, descriptor: String, signature: String?, value: Any?): FieldVisitor? { - val field = FieldElement(fieldName, descriptor) - logger.debug("--- field ---> {}", field) - if (unwantedFields.contains(field)) { - logger.info("- Deleted field {},{}", field.name, field.descriptor) - unwantedFields.remove(field) - return null - } - val fv = super.visitField(access, fieldName, descriptor, signature, value) ?: return null - return UnwantedFieldAdapter(fv, field) - } - - override fun visitMethod(access: Int, methodName: String, descriptor: String, signature: String?, exceptions: Array?): MethodVisitor? { - val method = MethodElement(methodName, descriptor, access) - logger.debug("--- method ---> {}", method) - if (deletedMethods.contains(method)) { - logger.info("- Deleted method {}{}", method.name, method.descriptor) - unwantedElements.addMethod(className, method) - deletedMethods.remove(method) - return null - } - - /* - * Write the byte-code for the method's prototype, then check whether - * we need to replace the method's body with our "stub" code. - */ - val mv = super.visitMethod(access, methodName, descriptor, signature, exceptions) ?: return null - if (stubbedMethods.contains(method)) { - logger.info("- Stubbed out method {}{}", method.name, method.descriptor) - stubbedMethods.remove(method) - return if (method.isVoidFunction) VoidStubMethodAdapter(mv) else ThrowingStubMethodAdapter(mv) - } - - return UnwantedMethodAdapter(mv, method) - } - - override fun visitInnerClass(clsName: String, outerName: String?, innerName: String?, access: Int) { - logger.debug("--- inner class {} [outer: {}, inner: {}]", clsName, outerName, innerName) - if (isUnwantedClass || hasDeletedSyntheticMethod(clsName)) { - if (unwantedElements.addClass(clsName)) { - logger.info("- Deleted inner class {}", clsName) - } - } else if (isUnwantedClass(clsName)) { - logger.info("- Deleted reference to inner class: {}", clsName) - } else { - super.visitInnerClass(clsName, outerName, innerName, access) - } - } - - override fun visitOuterClass(outerName: String, methodName: String?, methodDescriptor: String?) { - logger.debug("--- outer class {} [enclosing method {},{}]", outerName, methodName, methodDescriptor) - if (unwantedElements.containsMethod(outerName, methodName, methodDescriptor)) { - if (unwantedElements.addClass(className)) { - logger.info("- Identified class {} as unwanted by its outer class", className) - } - } else { - super.visitOuterClass(outerName, methodName, methodDescriptor) - } - } - - override fun visitEnd() { - if (isUnwantedClass) { - /* - * Optimisation: Don't rewrite the Kotlin @Metadata - * annotation if we're going to delete this class. - */ - kotlinMetadata.clear() - } - super.visitEnd() - /* - * Some elements were created based on unreliable information, - * such as Kotlin @Metadata annotations. We cannot rely on - * these actually existing in the bytecode, and so we expire - * them after a fixed number of passes. - */ - deletedMethods.removeIf(MethodElement::isExpired) - unwantedFields.removeIf(FieldElement::isExpired) - } - - /** - * Removes the deleted methods and fields from the Kotlin Class metadata. - */ - override fun processClassMetadata(d1: List, d2: List): List { - val partitioned = deletedMethods.groupBy(MethodElement::isConstructor) - val prefix = "$className$" - return ClassMetadataTransformer( - logger = logger, - deletedFields = unwantedFields, - deletedFunctions = partitioned[false] ?: emptyList(), - deletedConstructors = partitioned[true] ?: emptyList(), - deletedNestedClasses = unwantedElements.classes.filter { it.startsWith(prefix) }.map { it.drop(prefix.length) }, - deletedClasses = unwantedElements.classes, - handleExtraMethod = ::delete, - d1 = d1, - d2 = d2) - .transform() - } - - /** - * Removes the deleted methods and fields from the Kotlin Package metadata. - */ - override fun processPackageMetadata(d1: List, d2: List): List { - return PackageMetadataTransformer( - logger = logger, - deletedFields = unwantedFields, - deletedFunctions = deletedMethods, - handleExtraMethod = ::delete, - d1 = d1, - d2 = d2) - .transform() - } - - /** - * Callback function to mark extra methods for deletion. - * This will override a request for stubbing. - */ - private fun delete(method: MethodElement) { - if (deletedMethods.add(method) && stubbedMethods.remove(method)) { - logger.warn("-- method {}{} will be deleted instead of stubbed out", - method.name, method.descriptor) - } - } - - /** - * Analyses the field to decide whether it should be deleted. - */ - private inner class UnwantedFieldAdapter(fv: FieldVisitor, private val field: FieldElement) : FieldVisitor(api, fv) { - override fun visitAnnotation(descriptor: String, visible: Boolean): AnnotationVisitor? { - if (removeAnnotations.contains(descriptor)) { - logger.info("- Removing annotation {} from field {},{}", descriptor, field.name, field.descriptor) - return null - } else if (deleteAnnotations.contains(descriptor)) { - if (unwantedFields.add(field)) { - logger.info("- Identified field {},{} as unwanted", field.name, field.descriptor) - } - } - return super.visitAnnotation(descriptor, visible) - } - } - - /** - * Analyses the method to decide whether it should be deleted. - */ - private inner class UnwantedMethodAdapter(mv: MethodVisitor, private val method: MethodElement) : MethodVisitor(api, mv) { - override fun visitAnnotation(descriptor: String, visible: Boolean): AnnotationVisitor? { - if (removeAnnotations.contains(descriptor)) { - logger.info("- Removing annotation {} from method {}{}", descriptor, method.name, method.descriptor) - return null - } else if (deleteAnnotations.contains(descriptor)) { - if (deletedMethods.add(method)) { - logger.info("- Identified method {}{} for deletion", method.name, method.descriptor) - } - if (method.isKotlinSynthetic("annotations")) { - val extensionType = method.descriptor.extensionType - if (unwantedFields.add(FieldElement(name = method.visibleName, extension = extensionType))) { - logger.info("-- also identified property or typealias {},{} for deletion", method.visibleName, extensionType) - } - } - } else if (stubAnnotations.contains(descriptor) && (method.access and ACC_ABSTRACT) == 0) { - if (stubbedMethods.add(method)) { - logger.info("- Identified method {}{} for stubbing out", method.name, method.descriptor) - } - } - return super.visitAnnotation(descriptor, visible) - } - - override fun visitMethodInsn(opcode: Int, ownerName: String, methodName: String, descriptor: String, isInterface: Boolean) { - if ((isUnwantedClass(ownerName) || (ownerName == className && deletedMethods.contains(MethodElement(methodName, descriptor)))) - && !stubbedMethods.contains(method)) { - if (deletedMethods.add(method)) { - logger.info("- Unwanted invocation of method {},{}{} from method {}{}", ownerName, methodName, descriptor, method.name, method.descriptor) - } - } - super.visitMethodInsn(opcode, ownerName, methodName, descriptor, isInterface) - } - - override fun visitFieldInsn(opcode: Int, ownerName: String, fieldName: String, descriptor: String) { - if ((isUnwantedClass(ownerName) || (ownerName == className && unwantedFields.contains(FieldElement(fieldName, descriptor)))) - && !stubbedMethods.contains(method)) { - if (method.isConstructor) { - when (opcode) { - GETFIELD, GETSTATIC -> { - when (descriptor) { - "I", "S", "B", "C", "Z" -> visitIntInsn(BIPUSH, 0) - "J" -> visitInsn(LCONST_0) - "F" -> visitInsn(FCONST_0) - "D" -> visitInsn(DCONST_0) - else -> visitInsn(ACONST_NULL) - } - } - PUTFIELD, PUTSTATIC -> { - when (descriptor) { - "J", "D" -> visitInsn(POP2) - else -> visitInsn(POP) - } - } - else -> throw InvalidUserDataException("Unexpected opcode $opcode") - } - logger.info("- Unwanted reference to field {},{},{} REMOVED from constructor {}{}", - ownerName, fieldName, descriptor, method.name, method.descriptor) - return - } else if (deletedMethods.add(method)) { - logger.info("- Unwanted reference to field {},{},{} from method {}{}", - ownerName, fieldName, descriptor, method.name, method.descriptor) - } - } - super.visitFieldInsn(opcode, ownerName, fieldName, descriptor) - } - } - - /** - * Write "stub" byte-code for this method, preserving its other annotations. - * The method's original byte-code is discarded. - */ - private abstract inner class StubbingMethodAdapter(mv: MethodVisitor) : MethodVisitor(api, mv) { - override fun visitAnnotation(descriptor: String, visible: Boolean): AnnotationVisitor? { - return if (stubAnnotations.contains(descriptor)) null else mv.visitAnnotation(descriptor, visible) - } - - protected abstract fun writeStubCode() - - final override fun visitCode() { - with (mv) { - visitCode() - writeStubCode() - visitMaxs(-1, -1) // Trigger computation of the max values. - visitEnd() - } - - // Prevent this visitor from writing any more byte-code. - mv = null - } - } - - /** - * Write a method that throws [UnsupportedOperationException] with message "Method has been deleted". - */ - private inner class ThrowingStubMethodAdapter(mv: MethodVisitor) : StubbingMethodAdapter(mv) { - override fun writeStubCode() { - with (mv) { - val throwEx = Label() - visitLabel(throwEx) - visitLineNumber(0, throwEx) - visitTypeInsn(NEW, "java/lang/UnsupportedOperationException") - visitInsn(DUP) - visitLdcInsn("Method has been deleted") - visitMethodInsn(INVOKESPECIAL, "java/lang/UnsupportedOperationException", "", "(Ljava/lang/String;)V", false) - visitInsn(ATHROW) - } - } - } - - /** - * Write an empty method. Can only be applied to methods that return void. - */ - private inner class VoidStubMethodAdapter(mv: MethodVisitor) : StubbingMethodAdapter(mv) { - override fun writeStubCode() { - mv.visitInsn(RETURN) - } - } -} diff --git a/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/JarFilterPlugin.kt b/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/JarFilterPlugin.kt deleted file mode 100644 index ae33419b2b..0000000000 --- a/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/JarFilterPlugin.kt +++ /dev/null @@ -1,14 +0,0 @@ -@file:Suppress("UNUSED") -package net.corda.gradle.jarfilter - -import org.gradle.api.Plugin -import org.gradle.api.Project - -/** - * This plugin definition is only needed by the tests. - */ -class JarFilterPlugin : Plugin { - override fun apply(project: Project) { - project.logger.info("Applying JarFilter plugin") - } -} diff --git a/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/JarFilterTask.kt b/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/JarFilterTask.kt deleted file mode 100644 index 78100b2613..0000000000 --- a/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/JarFilterTask.kt +++ /dev/null @@ -1,288 +0,0 @@ -package net.corda.gradle.jarfilter - -import groovy.lang.Closure -import org.gradle.api.DefaultTask -import org.gradle.api.InvalidUserDataException -import org.gradle.api.file.ConfigurableFileCollection -import org.gradle.api.file.FileCollection -import org.gradle.api.tasks.* -import org.objectweb.asm.ClassReader -import org.objectweb.asm.ClassWriter -import org.objectweb.asm.ClassWriter.COMPUTE_MAXS -import java.io.Closeable -import java.io.File -import java.io.IOException -import java.nio.file.* -import java.nio.file.StandardCopyOption.* -import java.util.zip.Deflater.BEST_COMPRESSION -import java.util.zip.ZipFile -import java.util.zip.ZipOutputStream -import kotlin.math.max - -@Suppress("Unused", "MemberVisibilityCanBePrivate") -open class JarFilterTask : DefaultTask() { - private companion object { - private const val DEFAULT_MAX_PASSES = 5 - } - - private val _jars: ConfigurableFileCollection = project.files() - @get:SkipWhenEmpty - @get:InputFiles - val jars: FileCollection get() = _jars - - fun setJars(inputs: Any?) { - val files = inputs ?: return - _jars.setFrom(files) - } - - fun jars(inputs: Any?) = setJars(inputs) - - @get:Input - protected var forDelete: Set = emptySet() - - @get:Input - protected var forStub: Set = emptySet() - - @get:Input - protected var forRemove: Set = emptySet() - - @get:Input - protected var forSanitise: Set = emptySet() - - fun annotations(assign: Closure>) { - assign.call() - } - - @get:Console - var verbose: Boolean = false - - @get:Input - var maxPasses: Int = DEFAULT_MAX_PASSES - set(value) { - field = max(value, 1) - } - - @get:Input - var preserveTimestamps: Boolean = true - - private var _outputDir = project.buildDir.resolve("filtered-libs") - @get:Internal - val outputDir: File get() = _outputDir - - fun setOutputDir(d: File?) { - val dir = d ?: return - _outputDir = dir - } - - fun outputDir(dir: File?) = setOutputDir(dir) - - @get:OutputFiles - val filtered: FileCollection get() = project.files(jars.files.map(this::toFiltered)) - - private fun toFiltered(source: File) = File(outputDir, source.name.replace(JAR_PATTERN, "-filtered\$1")) - - @TaskAction - fun filterJars() { - logger.info("JarFiltering:") - if (forDelete.isNotEmpty()) { - logger.info("- Elements annotated with one of '{}' will be deleted", forDelete.joinToString()) - } - if (forStub.isNotEmpty()) { - logger.info("- Methods annotated with one of '{}' will be stubbed out", forStub.joinToString()) - } - if (forRemove.isNotEmpty()) { - logger.info("- Annotations '{}' will be removed entirely", forRemove.joinToString()) - } - if (forSanitise.isNotEmpty()) { - logger.info("- Annotations '{}' will be removed from primary constructors", forSanitise.joinToString()) - } - checkDistinctAnnotations() - try { - jars.forEach { jar -> - logger.info("Filtering {}", jar) - Filter(jar).run() - } - } catch (e: Exception) { - rethrowAsUncheckedException(e) - } - } - - private fun checkDistinctAnnotations() { - logger.info("Checking that all annotations are distinct.") - val annotations = forRemove.toHashSet().apply { - addAll(forDelete) - addAll(forStub) - removeAll(forRemove) - } - forDelete.forEach { - if (!annotations.remove(it)) { - failWith("Annotation '$it' also appears in JarFilter 'forDelete' section") - } - } - forStub.forEach { - if (!annotations.remove(it)) { - failWith("Annotation '$it' also appears in JarFilter 'forStub' section") - } - } - if (!annotations.isEmpty()) { - failWith("SHOULDN'T HAPPEN - Martian annotations! '${annotations.joinToString()}'") - } - } - - private fun failWith(message: String): Nothing = throw InvalidUserDataException(message) - - private fun verbose(format: String, vararg objects: Any) { - if (verbose) { - logger.info(format, *objects) - } - } - - private inner class Filter(inFile: File) { - private val unwantedElements = UnwantedCache() - private val source: Path = inFile.toPath() - private val target: Path = toFiltered(inFile).toPath() - - private val descriptorsForRemove = toDescriptors(forRemove) - private val descriptorsForDelete = toDescriptors(forDelete) - private val descriptorsForStub = toDescriptors(forStub) - private val descriptorsForSanitising = toDescriptors(forSanitise) - - init { - Files.deleteIfExists(target) - } - - fun run() { - logger.info("Filtering to: {}", target) - var input = source - - try { - if (descriptorsForSanitising.isNotEmpty() && SanitisingPass(input).use { it.run() }) { - input = target.moveToInput() - } - - var passes = 1 - while (true) { - verbose("Pass {}", passes) - val isModified = FilterPass(input).use { it.run() } - - if (!isModified) { - logger.info("No changes after latest pass - exiting.") - break - } else if (++passes > maxPasses) { - break - } - - input = target.moveToInput() - } - } catch (e: Exception) { - logger.error("Error filtering '{}' elements from {}", ArrayList(forRemove).apply { addAll(forDelete); addAll(forStub) }, input) - throw e - } - } - - private fun Path.moveToInput(): Path { - return Files.move(this, Files.createTempFile(parent, "filter-", ".tmp"), REPLACE_EXISTING).also { - verbose("New input JAR: {}", it) - } - } - - private abstract inner class Pass(input: Path): Closeable { - /** - * Use [ZipFile] instead of [java.util.jar.JarInputStream] because - * JarInputStream consumes MANIFEST.MF when it's the first or second entry. - */ - protected val inJar = ZipFile(input.toFile()) - protected val outJar = ZipOutputStream(Files.newOutputStream(target)) - protected var isModified = false - - @Throws(IOException::class) - override fun close() { - inJar.use { - outJar.close() - } - } - - abstract fun transform(inBytes: ByteArray): ByteArray - - fun run(): Boolean { - outJar.setLevel(BEST_COMPRESSION) - outJar.setComment(inJar.comment) - - for (entry in inJar.entries()) { - val entryData = inJar.getInputStream(entry) - - if (entry.isDirectory || !entry.name.endsWith(".class")) { - // This entry's byte contents have not changed, - // but may still need to be recompressed. - outJar.putNextEntry(entry.copy().withFileTimestamps(preserveTimestamps)) - entryData.copyTo(outJar) - } else { - val classData = transform(entryData.readBytes()) - if (classData.isNotEmpty()) { - // This entry's byte contents have almost certainly - // changed, and will be stored compressed. - outJar.putNextEntry(entry.asCompressed().withFileTimestamps(preserveTimestamps)) - outJar.write(classData) - } - } - } - return isModified - } - } - - private inner class SanitisingPass(input: Path) : Pass(input) { - override fun transform(inBytes: ByteArray): ByteArray { - return ClassWriter(0).let { writer -> - val transformer = SanitisingTransformer(writer, logger, descriptorsForSanitising) - ClassReader(inBytes).accept(transformer, 0) - isModified = isModified or transformer.isModified - writer.toByteArray() - } - } - } - - private inner class FilterPass(input: Path) : Pass(input) { - override fun transform(inBytes: ByteArray): ByteArray { - var reader = ClassReader(inBytes) - var writer = ClassWriter(COMPUTE_MAXS) - var transformer = FilterTransformer( - visitor = writer, - logger = logger, - removeAnnotations = descriptorsForRemove, - deleteAnnotations = descriptorsForDelete, - stubAnnotations = descriptorsForStub, - unwantedElements = unwantedElements - ) - - /* - * First pass: This might not find anything to remove! - */ - reader.accept(transformer, 0) - - if (transformer.isUnwantedClass || transformer.hasUnwantedElements) { - isModified = true - - do { - /* - * Rewrite the class without any of the unwanted elements. - * If we're deleting the class then make sure we identify all of - * its inner classes too, for the next filter pass to delete. - */ - reader = ClassReader(writer.toByteArray()) - writer = ClassWriter(COMPUTE_MAXS) - transformer = transformer.recreate(writer) - reader.accept(transformer, 0) - } while (!transformer.isUnwantedClass && transformer.hasUnwantedElements) - } - - return if (transformer.isUnwantedClass) { - // The entire class is unwanted, so don't write it out. - logger.info("Deleting class {}", transformer.className) - byteArrayOf() - } else { - writer.toByteArray() - } - } - } - } -} diff --git a/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/KotlinAwareVisitor.kt b/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/KotlinAwareVisitor.kt deleted file mode 100644 index 7c50110626..0000000000 --- a/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/KotlinAwareVisitor.kt +++ /dev/null @@ -1,159 +0,0 @@ -package net.corda.gradle.jarfilter - -import org.gradle.api.logging.LogLevel -import org.gradle.api.logging.Logger -import org.jetbrains.kotlin.load.java.JvmAnnotationNames.* -import org.objectweb.asm.AnnotationVisitor -import org.objectweb.asm.ClassVisitor - -/** - * Kotlin support: Loads the ProtoBuf data from the [kotlin.Metadata] annotation. - */ -abstract class KotlinAwareVisitor( - api: Int, - visitor: ClassVisitor, - protected val logger: Logger, - protected val kotlinMetadata: MutableMap> -) : ClassVisitor(api, visitor) { - - private companion object { - /** See [org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader.Kind]. */ - private const val KOTLIN_CLASS = 1 - private const val KOTLIN_FILE = 2 - private const val KOTLIN_SYNTHETIC = 3 - private const val KOTLIN_MULTIFILE_PART = 5 - } - - private var classKind: Int = 0 - - open val hasUnwantedElements: Boolean get() = kotlinMetadata.isNotEmpty() - protected open val level: LogLevel = LogLevel.INFO - - protected abstract fun processClassMetadata(d1: List, d2: List): List - protected abstract fun processPackageMetadata(d1: List, d2: List): List - protected abstract fun processKotlinAnnotation() - - override fun visitAnnotation(descriptor: String, visible: Boolean): AnnotationVisitor? { - val av = super.visitAnnotation(descriptor, visible) ?: return null - return if (descriptor == METADATA_DESC) KotlinMetadataAdaptor(av) else av - } - - protected fun processMetadata() { - if (kotlinMetadata.isNotEmpty()) { - logger.log(level, "- Examining Kotlin @Metadata[k={}]", classKind) - val d1 = kotlinMetadata.remove(METADATA_DATA_FIELD_NAME) - val d2 = kotlinMetadata.remove(METADATA_STRINGS_FIELD_NAME) - if (d1 != null && d1.isNotEmpty() && d2 != null) { - processMetadata(d1, d2).apply { - if (isNotEmpty()) { - kotlinMetadata[METADATA_DATA_FIELD_NAME] = this - kotlinMetadata[METADATA_STRINGS_FIELD_NAME] = d2 - } - } - } - } - } - - private fun processMetadata(d1: List, d2: List): List { - return when (classKind) { - KOTLIN_CLASS -> processClassMetadata(d1, d2) - KOTLIN_FILE, KOTLIN_MULTIFILE_PART -> processPackageMetadata(d1, d2) - KOTLIN_SYNTHETIC -> { - logger.log(level,"-- synthetic class ignored") - emptyList() - } - else -> { - /* - * For class-kind=4 (i.e. "multi-file"), we currently - * expect d1=[list of multi-file-part classes], d2=null. - */ - logger.log(level,"-- unsupported class-kind {}", classKind) - emptyList() - } - } - } - - private inner class KotlinMetadataAdaptor(av: AnnotationVisitor): AnnotationVisitor(api, av) { - override fun visit(name: String?, value: Any?) { - if (name == KIND_FIELD_NAME) { - classKind = value as Int - } - super.visit(name, value) - } - - override fun visitArray(name: String): AnnotationVisitor? { - val av = super.visitArray(name) - if (av != null) { - val data = kotlinMetadata.remove(name) ?: return ArrayAccumulator(av, name) - logger.debug("-- rewrote @Metadata.{}[{}]", name, data.size) - data.forEach { av.visit(null, it) } - av.visitEnd() - } - return null - } - - override fun visitEnd() { - super.visitEnd() - processKotlinAnnotation() - } - } - - private inner class ArrayAccumulator(av: AnnotationVisitor, private val name: String) : AnnotationVisitor(api, av) { - private val data: MutableList = mutableListOf() - - override fun visit(name: String?, value: Any?) { - super.visit(name, value) - data.add(value as String) - } - - override fun visitEnd() { - super.visitEnd() - kotlinMetadata[name] = data - logger.debug("-- read @Metadata.{}[{}]", name, data.size) - } - } -} - -/** - * Loads the ProtoBuf data from the [kotlin.Metadata] annotation, or - * writes new ProtoBuf data that was created during a previous pass. - */ -abstract class KotlinAfterProcessor( - api: Int, - visitor: ClassVisitor, - logger: Logger, - kotlinMetadata: MutableMap> -) : KotlinAwareVisitor(api, visitor, logger, kotlinMetadata) { - - /** - * Process the metadata once we have finished visiting the class. - * This will allow us to rewrite the [kotlin.Metadata] annotation - * in the next visit. - */ - override fun visitEnd() { - super.visitEnd() - processMetadata() - } - - /** - * Do nothing immediately after we have parsed [kotlin.Metadata]. - */ - final override fun processKotlinAnnotation() {} -} - -/** - * Loads the ProtoBuf data from the [kotlin.Metadata] annotation - * and then processes it before visiting the rest of the class. - */ -abstract class KotlinBeforeProcessor( - api: Int, - visitor: ClassVisitor, - logger: Logger, - kotlinMetadata: MutableMap> -) : KotlinAwareVisitor(api, visitor, logger, kotlinMetadata) { - - /** - * Process the ProtoBuf data as soon as we have parsed [kotlin.Metadata]. - */ - final override fun processKotlinAnnotation() = processMetadata() -} diff --git a/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/MetaFixerTask.kt b/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/MetaFixerTask.kt deleted file mode 100644 index 5c120cc926..0000000000 --- a/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/MetaFixerTask.kt +++ /dev/null @@ -1,128 +0,0 @@ -package net.corda.gradle.jarfilter - -import org.gradle.api.DefaultTask -import org.gradle.api.file.ConfigurableFileCollection -import org.gradle.api.file.FileCollection -import org.gradle.api.logging.Logger -import org.gradle.api.tasks.* -import java.io.Closeable -import java.io.File -import java.io.IOException -import java.nio.file.* -import java.util.zip.Deflater.BEST_COMPRESSION -import java.util.zip.ZipEntry -import java.util.zip.ZipFile -import java.util.zip.ZipOutputStream - -@Suppress("Unused", "MemberVisibilityCanBePrivate") -open class MetaFixerTask : DefaultTask() { - private val _jars: ConfigurableFileCollection = project.files() - @get:SkipWhenEmpty - @get:InputFiles - val jars: FileCollection - get() = _jars - - fun setJars(inputs: Any?) { - val files = inputs ?: return - _jars.setFrom(files) - } - - fun jars(inputs: Any?) = setJars(inputs) - - private var _outputDir = project.buildDir.resolve("metafixer-libs") - @get:Internal - val outputDir: File - get() = _outputDir - - fun setOutputDir(d: File?) { - val dir = d ?: return - _outputDir = dir - } - - fun outputDir(dir: File?) = setOutputDir(dir) - - private var _suffix: String = "-metafixed" - @get:Input - val suffix: String get() = _suffix - - fun setSuffix(input: String?) { - _suffix = input ?: return - } - - fun suffix(suffix: String?) = setSuffix(suffix) - - @get:Input - var preserveTimestamps: Boolean = true - - @TaskAction - fun fixMetadata() { - logger.info("Fixing Kotlin @Metadata") - try { - jars.forEach { jar -> - logger.info("Reading from {}", jar) - MetaFix(jar).use { it.run() } - } - } catch (e: Exception) { - rethrowAsUncheckedException(e) - } - } - - @get:OutputFiles - val metafixed: FileCollection get() = project.files(jars.files.map(this::toMetaFixed)) - - private fun toMetaFixed(source: File) = File(outputDir, source.name.replace(JAR_PATTERN, "$suffix\$1")) - - private inner class MetaFix(inFile: File) : Closeable { - /** - * Use [ZipFile] instead of [java.util.jar.JarInputStream] because - * JarInputStream consumes MANIFEST.MF when it's the first or second entry. - */ - private val target: Path = toMetaFixed(inFile).toPath() - private val inJar = ZipFile(inFile) - private val outJar: ZipOutputStream - - init { - // Default options for newOutputStream() are CREATE, TRUNCATE_EXISTING. - outJar = ZipOutputStream(Files.newOutputStream(target)).apply { - setLevel(BEST_COMPRESSION) - } - } - - @Throws(IOException::class) - override fun close() { - inJar.use { - outJar.close() - } - } - - fun run() { - logger.info("Writing to {}", target) - outJar.setComment(inJar.comment) - - val classNames = inJar.entries().asSequence().namesEndingWith(".class") - for (entry in inJar.entries()) { - val entryData = inJar.getInputStream(entry) - - if (entry.isDirectory || !entry.name.endsWith(".class")) { - // This entry's byte contents have not changed, - // but may still need to be recompressed. - outJar.putNextEntry(entry.copy().withFileTimestamps(preserveTimestamps)) - entryData.copyTo(outJar) - } else { - // This entry's byte contents have almost certainly - // changed, and will be stored compressed. - val classData = entryData.readBytes().fixMetadata(logger, classNames) - outJar.putNextEntry(entry.asCompressed().withFileTimestamps(preserveTimestamps)) - outJar.write(classData) - } - } - } - } - - private fun Sequence.namesEndingWith(suffix: String): Set { - return filter { it.name.endsWith(suffix) }.map { it.name.dropLast(suffix.length) }.toSet() - } -} - -fun ByteArray.fixMetadata(logger: Logger, classNames: Set): ByteArray - = execute({ writer -> MetaFixerVisitor(writer, logger, classNames) }) diff --git a/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/MetaFixerTransformer.kt b/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/MetaFixerTransformer.kt deleted file mode 100644 index f6d97c7a24..0000000000 --- a/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/MetaFixerTransformer.kt +++ /dev/null @@ -1,278 +0,0 @@ -package net.corda.gradle.jarfilter - -import org.gradle.api.logging.Logger -import org.jetbrains.kotlin.metadata.ProtoBuf -import org.jetbrains.kotlin.metadata.ProtoBuf.Class.Kind.* -import org.jetbrains.kotlin.metadata.deserialization.Flags.* -import org.jetbrains.kotlin.metadata.deserialization.NameResolver -import org.jetbrains.kotlin.metadata.deserialization.TypeTable -import org.jetbrains.kotlin.metadata.deserialization.getExtensionOrNull -import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf.* -import org.jetbrains.kotlin.metadata.jvm.deserialization.BitEncoding -import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmNameResolver -import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil -import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil.EXTENSION_REGISTRY -import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite -import org.jetbrains.kotlin.protobuf.MessageLite -import java.io.ByteArrayInputStream -import java.io.ByteArrayOutputStream -import java.io.InputStream - -/** - * Base class for aligning the contents of [kotlin.Metadata] annotations - * with the contents of the host byte-code. - * This is used by [MetaFixerVisitor] for [MetaFixerTask]. - */ -internal abstract class MetaFixerTransformer( - private val logger: Logger, - private val actualFields: Collection, - private val actualMethods: Collection, - private val actualNestedClasses: Collection, - private val actualClasses: Collection, - d1: List, - d2: List, - parser: (InputStream, ExtensionRegistryLite) -> T -) { - private val stringTableTypes: StringTableTypes - protected val nameResolver: NameResolver - protected val message: T - - protected abstract val typeTable: TypeTable - protected open val classDescriptor: String = "" - protected open val classKind: ProtoBuf.Class.Kind? = null - protected abstract val properties: MutableList - protected abstract val functions: MutableList - protected abstract val constructors: MutableList - protected open val nestedClassNames: MutableList get() = throw UnsupportedOperationException("No nestedClassNames") - protected open val sealedSubclassNames: MutableList get() = throw UnsupportedOperationException("No sealedSubclassNames") - - init { - val input = ByteArrayInputStream(BitEncoding.decodeBytes(d1.toTypedArray())) - stringTableTypes = StringTableTypes.parseDelimitedFrom(input, EXTENSION_REGISTRY) - nameResolver = JvmNameResolver(stringTableTypes, d2.toTypedArray()) - message = parser(input, EXTENSION_REGISTRY) - } - - abstract fun rebuild(): T - - private fun filterNestedClasses(): Int { - if (classKind == null) return 0 - - var count = 0 - var idx = 0 - while (idx < nestedClassNames.size) { - val nestedClassName = nameResolver.getString(nestedClassNames[idx]) - if (actualNestedClasses.contains(nestedClassName)) { - ++idx - } else { - logger.info("-- removing nested class: {}", nestedClassName) - nestedClassNames.removeAt(idx) - ++count - } - } - return count - } - - private fun filterSealedSubclassNames(): Int { - if (classKind == null) return 0 - - var count = 0 - var idx = 0 - while (idx < sealedSubclassNames.size) { - val sealedSubclassName = nameResolver.getClassInternalName(sealedSubclassNames[idx]) - if (actualClasses.contains(sealedSubclassName)) { - ++idx - } else { - logger.info("-- removing sealed subclass: {}", sealedSubclassName) - sealedSubclassNames.removeAt(idx) - ++count - } - } - return count - } - - private fun filterFunctions(): Int { - var count = 0 - var idx = 0 - removed@ while (idx < functions.size) { - val function = functions[idx] - val signature = JvmProtoBufUtil.getJvmMethodSignature(function, nameResolver, typeTable) - if (signature != null) { - if (!actualMethods.contains(signature)) { - logger.info("-- removing method: {}", signature) - functions.removeAt(idx) - ++count - continue@removed - } else if (function.valueParameterList.hasAnyDefaultValues - && !actualMethods.contains(signature.toKotlinDefaultFunction(classDescriptor))) { - logger.info("-- removing default parameter values: {}", signature) - functions[idx] = function.toBuilder() - .updateValueParameters(ProtoBuf.ValueParameter::clearDeclaresDefaultValue) - .build() - ++count - } - } - ++idx - } - return count - } - - private fun filterConstructors(): Int { - var count = 0 - var idx = 0 - removed@ while (idx < constructors.size) { - val constructor = constructors[idx] - val signature = JvmProtoBufUtil.getJvmConstructorSignature(constructor, nameResolver, typeTable) - if (signature != null) { - if (!actualMethods.contains(signature)) { - logger.info("-- removing constructor: {}", signature) - constructors.removeAt(idx) - ++count - continue@removed - } else if (constructor.valueParameterList.hasAnyDefaultValues - && !actualMethods.contains(signature.toKotlinDefaultConstructor())) { - logger.info("-- removing default parameter values: {}", signature) - constructors[idx] = constructor.toBuilder() - .updateValueParameters(ProtoBuf.ValueParameter::clearDeclaresDefaultValue) - .build() - ++count - } - } - ++idx - } - return count - } - - private fun filterProperties(): Int { - var count = 0 - var idx = 0 - removed@ while (idx < properties.size) { - val property = properties[idx] - val signature = property.getExtensionOrNull(propertySignature) - if (signature != null) { - val field = signature.toFieldElement(property, nameResolver, typeTable) - val getterMethod = signature.toGetter(nameResolver) - - /** - * A property annotated with [JvmField] will use a field instead of a getter method. - * But properties without [JvmField] will also usually have a backing field. So we only - * remove a property that has either lost its getter method, or never had a getter method - * and has lost its field. - * - * Having said that, we cannot remove [JvmField] properties from a companion object class - * because these properties are implemented as static fields on the companion's host class. - */ - val isValidProperty = if (getterMethod == null) { - actualFields.contains(field) || classKind == COMPANION_OBJECT - } else { - actualMethods.contains(getterMethod.signature) - } - - if (!isValidProperty) { - logger.info("-- removing property: {},{}", field.name, field.descriptor) - properties.removeAt(idx) - ++count - continue@removed - } - } - ++idx - } - return count - } - - fun transform(): List { - var count = filterProperties() + filterFunctions() + filterNestedClasses() + filterSealedSubclassNames() - if (classKind != ANNOTATION_CLASS) { - count += filterConstructors() - } - if (count == 0) { - return emptyList() - } - - val bytes = ByteArrayOutputStream() - stringTableTypes.writeDelimitedTo(bytes) - rebuild().writeTo(bytes) - return BitEncoding.encodeBytes(bytes.toByteArray()).toList() - } -} - -/** - * Aligns a [kotlin.Metadata] annotation containing a [ProtoBuf.Class] object - * in its [d1][kotlin.Metadata.d1] field with the byte-code of its host class. - */ -internal class ClassMetaFixerTransformer( - logger: Logger, - actualFields: Collection, - actualMethods: Collection, - actualNestedClasses: Collection, - actualClasses: Collection, - d1: List, - d2: List -) : MetaFixerTransformer( - logger, - actualFields, - actualMethods, - actualNestedClasses, - actualClasses, - d1, - d2, - ProtoBuf.Class::parseFrom -) { - override val typeTable = TypeTable(message.typeTable) - override val classDescriptor = "L${nameResolver.getClassInternalName(message.fqName)};" - override val classKind: ProtoBuf.Class.Kind = CLASS_KIND.get(message.flags) - override val properties = mutableList(message.propertyList) - override val functions = mutableList(message.functionList) - override val constructors = mutableList(message.constructorList) - override val nestedClassNames = mutableList(message.nestedClassNameList) - override val sealedSubclassNames= mutableList(message.sealedSubclassFqNameList) - - override fun rebuild(): ProtoBuf.Class = message.toBuilder().apply { - clearConstructor().addAllConstructor(constructors) - clearFunction().addAllFunction(functions) - - if (nestedClassNames.size != nestedClassNameCount) { - clearNestedClassName().addAllNestedClassName(nestedClassNames) - } - if (sealedSubclassNames.size != sealedSubclassFqNameCount) { - clearSealedSubclassFqName().addAllSealedSubclassFqName(sealedSubclassNames) - } - if (properties.size != propertyCount) { - clearProperty().addAllProperty(properties) - } - }.build() -} - -/** - * Aligns a [kotlin.Metadata] annotation containing a [ProtoBuf.Package] object - * in its [d1][kotlin.Metadata.d1] field with the byte-code of its host class. - */ -internal class PackageMetaFixerTransformer( - logger: Logger, - actualFields: Collection, - actualMethods: Collection, - d1: List, - d2: List -) : MetaFixerTransformer( - logger, - actualFields, - actualMethods, - emptyList(), - emptyList(), - d1, - d2, - ProtoBuf.Package::parseFrom -) { - override val typeTable = TypeTable(message.typeTable) - override val properties = mutableList(message.propertyList) - override val functions = mutableList(message.functionList) - override val constructors = mutableListOf() - - override fun rebuild(): ProtoBuf.Package = message.toBuilder().apply { - clearFunction().addAllFunction(functions) - - if (properties.size != propertyCount) { - clearProperty().addAllProperty(properties) - } - }.build() -} diff --git a/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/MetaFixerVisitor.kt b/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/MetaFixerVisitor.kt deleted file mode 100644 index bce68310bc..0000000000 --- a/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/MetaFixerVisitor.kt +++ /dev/null @@ -1,76 +0,0 @@ -package net.corda.gradle.jarfilter - -import org.gradle.api.logging.Logger -import org.objectweb.asm.* -import org.objectweb.asm.Opcodes.* - -/** - * ASM [ClassVisitor] for the MetaFixer task. This visitor inventories every function, - * property and inner class within the byte-code and then passes this information to - * the [MetaFixerTransformer]. - */ -class MetaFixerVisitor private constructor( - visitor: ClassVisitor, - logger: Logger, - kotlinMetadata: MutableMap>, - private val classNames: Set, - private val fields: MutableSet, - private val methods: MutableSet, - private val nestedClasses: MutableSet -) : KotlinAfterProcessor(ASM6, visitor, logger, kotlinMetadata), Repeatable { - constructor(visitor: ClassVisitor, logger: Logger, classNames: Set) - : this(visitor, logger, mutableMapOf(), classNames, mutableSetOf(), mutableSetOf(), mutableSetOf()) - - override fun recreate(visitor: ClassVisitor) = MetaFixerVisitor(visitor, logger, kotlinMetadata, classNames, fields, methods, nestedClasses) - - private var className: String = "(unknown)" - - override fun visit(version: Int, access: Int, clsName: String, signature: String?, superName: String?, interfaces: Array?) { - className = clsName - logger.info("Class {}", clsName) - super.visit(version, access, clsName, signature, superName, interfaces) - } - - override fun visitField(access: Int, fieldName: String, descriptor: String, signature: String?, value: Any?): FieldVisitor? { - if (fields.add(FieldElement(fieldName, descriptor))) { - logger.info("- field {},{}", fieldName, descriptor) - } - return super.visitField(access, fieldName, descriptor, signature, value) - } - - override fun visitMethod(access: Int, methodName: String, descriptor: String, signature: String?, exceptions: Array?): MethodVisitor? { - if (methods.add(methodName + descriptor)) { - logger.info("- method {}{}", methodName, descriptor) - } - return super.visitMethod(access, methodName, descriptor, signature, exceptions) - } - - override fun visitInnerClass(clsName: String, outerName: String?, innerName: String?, access: Int) { - if (outerName == className && innerName != null && nestedClasses.add(innerName)) { - logger.info("- inner class {}", clsName) - } - return super.visitInnerClass(clsName, outerName, innerName, access) - } - - override fun processClassMetadata(d1: List, d2: List): List { - return ClassMetaFixerTransformer( - logger = logger, - actualFields = fields, - actualMethods = methods, - actualNestedClasses = nestedClasses, - actualClasses = classNames, - d1 = d1, - d2 = d2) - .transform() - } - - override fun processPackageMetadata(d1: List, d2: List): List { - return PackageMetaFixerTransformer( - logger = logger, - actualFields = fields, - actualMethods = methods, - d1 = d1, - d2 = d2) - .transform() - } -} diff --git a/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/MetadataTransformer.kt b/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/MetadataTransformer.kt deleted file mode 100644 index 1701654c18..0000000000 --- a/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/MetadataTransformer.kt +++ /dev/null @@ -1,319 +0,0 @@ -package net.corda.gradle.jarfilter - -import org.gradle.api.logging.Logger -import org.jetbrains.kotlin.metadata.ProtoBuf -import org.jetbrains.kotlin.metadata.deserialization.Flags.* -import org.jetbrains.kotlin.metadata.deserialization.NameResolver -import org.jetbrains.kotlin.metadata.deserialization.TypeTable -import org.jetbrains.kotlin.metadata.deserialization.getExtensionOrNull -import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf.* -import org.jetbrains.kotlin.metadata.jvm.deserialization.BitEncoding -import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmNameResolver -import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil -import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil.EXTENSION_REGISTRY -import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite -import org.jetbrains.kotlin.protobuf.MessageLite -import java.io.ByteArrayInputStream -import java.io.ByteArrayOutputStream -import java.io.InputStream - -/** - * Base class for removing unwanted elements from [kotlin.Metadata] annotations. - * This is used by [FilterTransformer] for [JarFilterTask]. - */ -internal abstract class MetadataTransformer( - private val logger: Logger, - private val deletedFields: Collection, - private val deletedFunctions: Collection, - private val deletedConstructors: Collection, - private val deletedNestedClasses: Collection, - private val deletedClasses: Collection, - private val handleExtraMethod: (MethodElement) -> Unit, - d1: List, - d2: List, - parser: (InputStream, ExtensionRegistryLite) -> T -) { - private val stringTableTypes: StringTableTypes - protected val nameResolver: NameResolver - protected val message: T - - protected abstract val typeTable: TypeTable - protected open val className: String get() = throw UnsupportedOperationException("No className") - protected open val nestedClassNames: MutableList get() = throw UnsupportedOperationException("No nestedClassNames") - protected open val sealedSubclassNames: MutableList get() = throw UnsupportedOperationException("No sealedSubclassNames") - protected abstract val properties: MutableList - protected abstract val functions: MutableList - protected open val constructors: MutableList get() = throw UnsupportedOperationException("No constructors") - protected abstract val typeAliases: MutableList - - init { - val input = ByteArrayInputStream(BitEncoding.decodeBytes(d1.toTypedArray())) - stringTableTypes = StringTableTypes.parseDelimitedFrom(input, EXTENSION_REGISTRY) - nameResolver = JvmNameResolver(stringTableTypes, d2.toTypedArray()) - message = parser(input, EXTENSION_REGISTRY) - } - - abstract fun rebuild(): T - - fun transform(): List { - val count = ( - filterProperties() - + filterFunctions() - + filterConstructors() - + filterNestedClasses() - + filterTypeAliases() - + filterSealedSubclasses() - ) - if (count == 0) { - return emptyList() - } - - val bytes = ByteArrayOutputStream() - stringTableTypes.writeDelimitedTo(bytes) - rebuild().writeTo(bytes) - return BitEncoding.encodeBytes(bytes.toByteArray()).toList() - } - - private fun filterNestedClasses(): Int { - if (deletedNestedClasses.isEmpty()) return 0 - - var count = 0 - var idx = 0 - while (idx < nestedClassNames.size) { - val nestedClassName = nameResolver.getString(nestedClassNames[idx]) - if (deletedNestedClasses.contains(nestedClassName)) { - logger.info("-- removing nested class: {}", nestedClassName) - nestedClassNames.removeAt(idx) - ++count - } else { - ++idx - } - } - return count - } - - private fun filterConstructors(): Int = deletedConstructors.count(::filterConstructor) - - private fun filterConstructor(deleted: MethodElement): Boolean { - /* - * Constructors with the default parameter marker are synthetic and DO NOT have - * entries in the metadata. So we construct an element for the "primary" one - * that it was synthesised for, and which we DO expect to find. - */ - val deletedPrimary = deleted.asKotlinNonDefaultConstructor() - - for (idx in 0 until constructors.size) { - val constructor = constructors[idx] - val signature = JvmProtoBufUtil.getJvmConstructorSignature(constructor, nameResolver, typeTable) - if (signature == deleted.signature) { - if (IS_SECONDARY.get(constructor.flags)) { - logger.info("-- removing constructor: {}", deleted.signature) - } else { - logger.warn("Removing primary constructor: {}{}", className, deleted.descriptor) - } - constructors.removeAt(idx) - return true - } else if (signature == deletedPrimary?.signature) { - constructors[idx] = constructor.toBuilder() - .updateValueParameters(ProtoBuf.ValueParameter::clearDeclaresDefaultValue) - .build() - logger.info("-- removing default parameter values: {}", signature) - return true - } - } - return false - } - - private fun filterFunctions(): Int = deletedFunctions.count(::filterFunction) - - private fun filterFunction(deleted: MethodElement): Boolean { - for (idx in 0 until functions.size) { - val function = functions[idx] - if (nameResolver.getString(function.name) == deleted.name) { - val signature = JvmProtoBufUtil.getJvmMethodSignature(function, nameResolver, typeTable) - if (signature == deleted.signature) { - logger.info("-- removing function: {}", deleted.signature) - functions.removeAt(idx) - return true - } - } - } - return false - } - - private fun filterProperties(): Int = deletedFields.count(::filterProperty) - - private fun filterProperty(deleted: FieldElement): Boolean { - for (idx in 0 until properties.size) { - val property = properties[idx] - val signature = property.getExtensionOrNull(propertySignature) ?: continue - val field = signature.toFieldElement(property, nameResolver, typeTable) - if (field.name.toVisible() == deleted.name) { - // Check that this property's getter has the correct descriptor. - // If it doesn't then we have the wrong property here. - val getter = signature.toGetter(nameResolver) - if (getter != null) { - if (!getter.descriptor.startsWith(deleted.extension)) { - continue - } - deleteExtra(getter) - } - signature.toSetter(nameResolver)?.apply(::deleteExtra) - - logger.info("-- removing property: {},{}", field.name, field.descriptor) - properties.removeAt(idx) - return true - } - } - return false - } - - private fun deleteExtra(func: MethodElement) { - if (!deletedFunctions.contains(func)) { - logger.info("-- identified extra method {} for deletion", func.signature) - handleExtraMethod(func) - filterFunction(func) - } - } - - private fun filterTypeAliases(): Int { - if (deletedFields.isEmpty()) return 0 - - var count = 0 - var idx = 0 - while (idx < typeAliases.size) { - val aliasName = nameResolver.getString(typeAliases[idx].name) - if (deletedFields.any { it.name == aliasName && it.extension == "()" }) { - logger.info("-- removing typealias: {}", aliasName) - typeAliases.removeAt(idx) - ++count - } else { - ++idx - } - } - return count - } - - private fun filterSealedSubclasses(): Int { - if (deletedClasses.isEmpty()) return 0 - - var count = 0 - var idx = 0 - while (idx < sealedSubclassNames.size) { - val subclassName = nameResolver.getClassInternalName(sealedSubclassNames[idx]) - if (deletedClasses.contains(subclassName)) { - logger.info("-- removing sealed subclass: {}", subclassName) - sealedSubclassNames.removeAt(idx) - ++count - } else { - ++idx - } - } - return count - } - - /** - * Removes any Kotlin suffix, e.g. "$delegate" or "$annotations". - */ - private fun String.toVisible(): String { - val idx = indexOf('$') - return if (idx == -1) this else substring(0, idx) - } -} - -/** - * Removes elements from a [kotlin.Metadata] annotation that contains - * a [ProtoBuf.Class] object in its [d1][kotlin.Metadata.d1] field. - */ -internal class ClassMetadataTransformer( - logger: Logger, - deletedFields: Collection, - deletedFunctions: Collection, - deletedConstructors: Collection, - deletedNestedClasses: Collection, - deletedClasses: Collection, - handleExtraMethod: (MethodElement) -> Unit, - d1: List, - d2: List -) : MetadataTransformer( - logger, - deletedFields, - deletedFunctions, - deletedConstructors, - deletedNestedClasses, - deletedClasses, - handleExtraMethod, - d1, - d2, - ProtoBuf.Class::parseFrom -) { - override val typeTable = TypeTable(message.typeTable) - override val className = nameResolver.getClassInternalName(message.fqName) - override val nestedClassNames = mutableList(message.nestedClassNameList) - override val sealedSubclassNames = mutableList(message.sealedSubclassFqNameList) - override val properties = mutableList(message.propertyList) - override val functions = mutableList(message.functionList) - override val constructors = mutableList(message.constructorList) - override val typeAliases = mutableList(message.typeAliasList) - - override fun rebuild(): ProtoBuf.Class = message.toBuilder().apply { - clearConstructor().addAllConstructor(constructors) - - if (nestedClassNames.size != nestedClassNameCount) { - clearNestedClassName().addAllNestedClassName(nestedClassNames) - } - if (functions.size != functionCount) { - clearFunction().addAllFunction(functions) - } - if (properties.size != propertyCount) { - clearProperty().addAllProperty(properties) - } - if (typeAliases.size != typeAliasCount) { - clearTypeAlias().addAllTypeAlias(typeAliases) - } - if (sealedSubclassNames.size != sealedSubclassFqNameCount) { - clearSealedSubclassFqName().addAllSealedSubclassFqName(sealedSubclassNames) - } - }.build() -} - -/** - * Removes elements from a [kotlin.Metadata] annotation that contains - * a [ProtoBuf.Package] object in its [d1][kotlin.Metadata.d1] field. - */ -internal class PackageMetadataTransformer( - logger: Logger, - deletedFields: Collection, - deletedFunctions: Collection, - handleExtraMethod: (MethodElement) -> Unit, - d1: List, - d2: List -) : MetadataTransformer( - logger, - deletedFields, - deletedFunctions, - emptyList(), - emptyList(), - emptyList(), - handleExtraMethod, - d1, - d2, - ProtoBuf.Package::parseFrom -) { - override val typeTable = TypeTable(message.typeTable) - override val properties = mutableList(message.propertyList) - override val functions = mutableList(message.functionList) - override val typeAliases = mutableList(message.typeAliasList) - - override fun rebuild(): ProtoBuf.Package = message.toBuilder().apply { - if (functions.size != functionCount) { - clearFunction().addAllFunction(functions) - } - if (properties.size != propertyCount) { - clearProperty().addAllProperty(properties) - } - if (typeAliases.size != typeAliasCount) { - clearTypeAlias().addAllTypeAlias(typeAliases) - } - }.build() -} diff --git a/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/Repeatable.kt b/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/Repeatable.kt deleted file mode 100644 index 4123fb3de4..0000000000 --- a/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/Repeatable.kt +++ /dev/null @@ -1,8 +0,0 @@ -package net.corda.gradle.jarfilter - -import org.objectweb.asm.ClassVisitor - -interface Repeatable { - fun recreate(visitor: ClassVisitor): T - val hasUnwantedElements: Boolean -} diff --git a/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/SanitisingTransformer.kt b/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/SanitisingTransformer.kt deleted file mode 100644 index e4dcdf822a..0000000000 --- a/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/SanitisingTransformer.kt +++ /dev/null @@ -1,81 +0,0 @@ -package net.corda.gradle.jarfilter - -import org.gradle.api.logging.LogLevel -import org.gradle.api.logging.Logger -import org.jetbrains.kotlin.metadata.ProtoBuf -import org.jetbrains.kotlin.metadata.deserialization.Flags.* -import org.jetbrains.kotlin.metadata.deserialization.TypeTable -import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf.* -import org.jetbrains.kotlin.metadata.jvm.deserialization.BitEncoding -import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmNameResolver -import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil.EXTENSION_REGISTRY -import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil.getJvmConstructorSignature -import org.objectweb.asm.AnnotationVisitor -import org.objectweb.asm.ClassVisitor -import org.objectweb.asm.MethodVisitor -import org.objectweb.asm.Opcodes.* -import java.io.ByteArrayInputStream - -/** - * This is (hopefully?!) a temporary solution for classes with [JvmOverloads] constructors. - * We need to be able to annotate ONLY the secondary constructors for such classes, but Kotlin - * will apply any annotation to all constructors equally. Nor can we replace the overloaded - * constructor with individual constructors because this will break ABI compatibility. (Kotlin - * generates a synthetic public constructor to handle default parameter values.) - * - * This transformer identifies a class's primary constructor and removes all of its unwanted annotations. - * It will become superfluous when Kotlin allows us to target only the secondary constructors with our - * filtering annotations in the first place. - */ -class SanitisingTransformer(visitor: ClassVisitor, logger: Logger, private val unwantedAnnotations: Set) - : KotlinBeforeProcessor(ASM6, visitor, logger, mutableMapOf()) { - - var isModified: Boolean = false - private set - override val level: LogLevel = LogLevel.DEBUG - - private var className: String = "(unknown)" - private var primaryConstructor: MethodElement? = null - - override fun processPackageMetadata(d1: List, d2: List): List = emptyList() - - override fun processClassMetadata(d1: List, d2: List): List { - val input = ByteArrayInputStream(BitEncoding.decodeBytes(d1.toTypedArray())) - val stringTableTypes = StringTableTypes.parseDelimitedFrom(input, EXTENSION_REGISTRY) - val nameResolver = JvmNameResolver(stringTableTypes, d2.toTypedArray()) - val message = ProtoBuf.Class.parseFrom(input, EXTENSION_REGISTRY) - val typeTable = TypeTable(message.typeTable) - - for (constructor in message.constructorList) { - if (!IS_SECONDARY.get(constructor.flags)) { - val signature = getJvmConstructorSignature(constructor, nameResolver, typeTable) ?: break - primaryConstructor = MethodElement("", signature.drop("".length)) - logger.log(level, "Class {} has primary constructor {}", className, signature) - break - } - } - return emptyList() - } - - override fun visit(version: Int, access: Int, clsName: String, signature: String?, superName: String?, interfaces: Array?) { - className = clsName - super.visit(version, access, clsName, signature, superName, interfaces) - } - - override fun visitMethod(access: Int, methodName: String, descriptor: String, signature: String?, exceptions: Array?): MethodVisitor? { - val method = MethodElement(methodName, descriptor, access) - val mv = super.visitMethod(access, methodName, descriptor, signature, exceptions) ?: return null - return if (method == primaryConstructor) SanitisingMethodAdapter(mv, method) else mv - } - - private inner class SanitisingMethodAdapter(mv: MethodVisitor, private val method: MethodElement) : MethodVisitor(api, mv) { - override fun visitAnnotation(descriptor: String, visible: Boolean): AnnotationVisitor? { - if (unwantedAnnotations.contains(descriptor)) { - logger.info("Sanitising annotation {} from method {}.{}{}", descriptor, className, method.name, method.descriptor) - isModified = true - return null - } - return super.visitAnnotation(descriptor, visible) - } - } -} diff --git a/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/UnwantedCache.kt b/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/UnwantedCache.kt deleted file mode 100644 index 5a8d28bc73..0000000000 --- a/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/UnwantedCache.kt +++ /dev/null @@ -1,46 +0,0 @@ -package net.corda.gradle.jarfilter - -import java.util.Collections.unmodifiableMap - -/** - * A persistent cache of all of the classes and methods that JarFilter has - * removed. This cache belongs to the Gradle task itself and so is shared - * by successive filter passes. - * - * The internal method cache is only required for those classes which are - * being kept. When an entire class is declared as "unwanted", any entry - * it may have in the method cache is removed. - */ -class UnwantedCache { - private val _classes: MutableSet = mutableSetOf() - private val _classMethods: MutableMap> = mutableMapOf() - - val classes: Set get() = _classes - val classMethods: Map> get() = unmodifiableMap(_classMethods) - - fun containsClass(className: String): Boolean = _classes.contains(className) - - fun addClass(className: String): Boolean { - return _classes.add(className).also { isAdded -> - if (isAdded) { - _classMethods.remove(className) - } - } - } - - fun addMethod(className: String, method: MethodElement) { - if (!containsClass(className)) { - _classMethods.getOrPut(className) { mutableSetOf() }.add(method) - } - } - - private fun containsMethod(className: String, method: MethodElement): Boolean { - return _classMethods[className]?.contains(method) ?: false - } - - fun containsMethod(className: String, methodName: String?, methodDescriptor: String?): Boolean { - return containsClass(className) || - (methodName != null && methodDescriptor != null && containsMethod(className, MethodElement(methodName, methodDescriptor))) - } -} - diff --git a/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/Utils.kt b/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/Utils.kt deleted file mode 100644 index 9b52c5419f..0000000000 --- a/buildSrc/jarfilter/src/main/kotlin/net/corda/gradle/jarfilter/Utils.kt +++ /dev/null @@ -1,92 +0,0 @@ -@file:JvmName("Utils") -package net.corda.gradle.jarfilter - -import org.gradle.api.GradleException -import org.objectweb.asm.ClassReader -import org.objectweb.asm.ClassVisitor -import org.objectweb.asm.ClassWriter -import java.nio.file.attribute.FileTime -import java.util.* -import java.util.Calendar.FEBRUARY -import java.util.zip.ZipEntry -import java.util.zip.ZipEntry.DEFLATED -import java.util.zip.ZipEntry.STORED -import kotlin.math.max -import kotlin.text.RegexOption.* - -internal val JAR_PATTERN = "(\\.jar)$".toRegex(IGNORE_CASE) - -// Use the same constant file timestamp as Gradle. -private val CONSTANT_TIME: FileTime = FileTime.fromMillis( - GregorianCalendar(1980, FEBRUARY, 1).apply { timeZone = TimeZone.getTimeZone("UTC") }.timeInMillis -) - -internal fun rethrowAsUncheckedException(e: Exception): Nothing - = throw (e as? RuntimeException) ?: GradleException(e.message ?: "", e) - -/** - * Recreates a [ZipEntry] object. The entry's byte contents - * will be compressed automatically, and its CRC, size and - * compressed size fields populated. - */ -internal fun ZipEntry.asCompressed(): ZipEntry { - return ZipEntry(name).also { entry -> - entry.lastModifiedTime = lastModifiedTime - lastAccessTime?.also { at -> entry.lastAccessTime = at } - creationTime?.also { ct -> entry.creationTime = ct } - entry.comment = comment - entry.method = DEFLATED - entry.extra = extra - } -} - -internal fun ZipEntry.copy(): ZipEntry { - return if (method == STORED) ZipEntry(this) else asCompressed() -} - -internal fun ZipEntry.withFileTimestamps(preserveTimestamps: Boolean): ZipEntry { - if (!preserveTimestamps) { - lastModifiedTime = CONSTANT_TIME - lastAccessTime?.apply { lastAccessTime = CONSTANT_TIME } - creationTime?.apply { creationTime = CONSTANT_TIME } - } - return this -} - -internal fun mutableList(c: Collection): MutableList = ArrayList(c) - -/** - * Converts Java class names to Java descriptors. - */ -internal fun toDescriptors(classNames: Iterable): Set { - return classNames.map(String::descriptor).toSet() -} - -internal val String.toPathFormat: String get() = replace('.', '/') -internal val String.descriptor: String get() = "L$toPathFormat;" - - -/** - * Performs the given number of passes of the repeatable visitor over the byte-code. - * Used by [MetaFixerVisitor], but also by some of the test visitors. - */ -internal fun ByteArray.execute(visitor: (ClassVisitor) -> T, flags: Int = 0, passes: Int = 2): ByteArray - where T : ClassVisitor, - T : Repeatable { - var bytecode = this - var writer = ClassWriter(flags) - var transformer = visitor(writer) - var count = max(passes, 1) - - while (--count >= 0) { - ClassReader(bytecode).accept(transformer, 0) - bytecode = writer.toByteArray() - - if (!transformer.hasUnwantedElements) break - - writer = ClassWriter(flags) - transformer = transformer.recreate(writer) - } - - return bytecode -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/AbstractFunctionTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/AbstractFunctionTest.kt deleted file mode 100644 index fb4bbc63a0..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/AbstractFunctionTest.kt +++ /dev/null @@ -1,69 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.jarfilter.matcher.* -import org.hamcrest.core.IsCollectionContaining.hasItem -import org.hamcrest.core.IsNot.not -import org.junit.Assert.* -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import java.lang.reflect.Modifier.* -import kotlin.reflect.full.declaredFunctions -import kotlin.test.assertFailsWith - -class AbstractFunctionTest { - companion object { - private const val FUNCTION_CLASS = "net.corda.gradle.AbstractFunctions" - - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "abstract-function") - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - } - - @Test - fun deleteAbstractFunction() { - val longFunction = isFunction("toDelete", Long::class, Long::class) - - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(FUNCTION_CLASS).apply { - getMethod("toDelete", Long::class.java).also { method -> - assertEquals(ABSTRACT, method.modifiers and ABSTRACT) - } - assertThat("toDelete(J) not found", kotlin.declaredFunctions, hasItem(longFunction)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(FUNCTION_CLASS).apply { - assertFailsWith { getMethod("toDelete", Long::class.java) } - assertThat("toDelete(J) still exists", kotlin.declaredFunctions, not(hasItem(longFunction))) - } - } - } - - @Test - fun cannotStubAbstractFunction() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(FUNCTION_CLASS).apply { - getMethod("toStubOut", Long::class.java).also { method -> - assertEquals(ABSTRACT, method.modifiers and ABSTRACT) - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(FUNCTION_CLASS).apply { - getMethod("toStubOut", Long::class.java).also { method -> - assertEquals(ABSTRACT, method.modifiers and ABSTRACT) - } - } - } - } -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteAndStubTests.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteAndStubTests.kt deleted file mode 100644 index 40e61b2706..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteAndStubTests.kt +++ /dev/null @@ -1,188 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.jarfilter.matcher.* -import net.corda.gradle.unwanted.* -import org.assertj.core.api.Assertions.* -import org.hamcrest.core.IsCollectionContaining.* -import org.hamcrest.core.IsNot.* -import org.junit.Assert.* -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import kotlin.reflect.full.declaredMemberFunctions -import kotlin.reflect.full.declaredMemberProperties -import kotlin.test.assertFailsWith - -class DeleteAndStubTests { - companion object { - private const val VAR_PROPERTY_CLASS = "net.corda.gradle.HasVarPropertyForDeleteAndStub" - private const val VAL_PROPERTY_CLASS = "net.corda.gradle.HasValPropertyForDeleteAndStub" - private const val DELETED_FUN_CLASS = "net.corda.gradle.DeletedFunctionInsideStubbed" - private const val DELETED_VAR_CLASS = "net.corda.gradle.DeletedVarInsideStubbed" - private const val DELETED_VAL_CLASS = "net.corda.gradle.DeletedValInsideStubbed" - private const val DELETED_PKG_CLASS = "net.corda.gradle.DeletePackageWithStubbed" - - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "delete-and-stub") - private val stringVal = isProperty("stringVal", String::class) - private val longVar = isProperty("longVar", Long::class) - private val getStringVal = isMethod("getStringVal", String::class.java) - private val getLongVar = isMethod("getLongVar", Long::class.java) - private val setLongVar = isMethod("setLongVar", Void.TYPE, Long::class.java) - private val stringData = isFunction("stringData", String::class) - private val unwantedFun = isFunction("unwantedFun", String::class, String::class) - private val unwantedVar = isProperty("unwantedVar", String::class) - private val unwantedVal = isProperty("unwantedVal", String::class) - private val stringDataJava = isMethod("stringData", String::class.java) - private val getUnwantedVal = isMethod("getUnwantedVal", String::class.java) - private val getUnwantedVar = isMethod("getUnwantedVar", String::class.java) - private val setUnwantedVar = isMethod("setUnwantedVar", Void.TYPE, String::class.java) - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - } - - @Test - fun deleteValProperty() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(VAL_PROPERTY_CLASS).apply { - getDeclaredConstructor(String::class.java).newInstance(MESSAGE).also { obj -> - assertEquals(MESSAGE, obj.stringVal) - } - assertThat("stringVal not found", kotlin.declaredMemberProperties, hasItem(stringVal)) - assertThat("getStringVal() not found", kotlin.javaDeclaredMethods, hasItem(getStringVal)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(VAL_PROPERTY_CLASS).apply { - assertNotNull(getDeclaredConstructor(String::class.java).newInstance(MESSAGE)) - assertThat("stringVal still exists", kotlin.declaredMemberProperties, not(hasItem(stringVal))) - assertThat("getStringVal() still exists", kotlin.javaDeclaredMethods, not(hasItem(getStringVal))) - } - } - } - - @Test - fun deleteVarProperty() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(VAR_PROPERTY_CLASS).apply { - getDeclaredConstructor(Long::class.java).newInstance(BIG_NUMBER).also { obj -> - assertEquals(BIG_NUMBER, obj.longVar) - } - assertThat("longVar not found", kotlin.declaredMemberProperties, hasItem(longVar)) - assertThat("getLongVar() not found", kotlin.javaDeclaredMethods, hasItem(getLongVar)) - assertThat("setLongVar() not found", kotlin.javaDeclaredMethods, hasItem(setLongVar)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(VAR_PROPERTY_CLASS).apply { - assertNotNull(getDeclaredConstructor(Long::class.java).newInstance(BIG_NUMBER)) - assertThat("longVar still exists", kotlin.declaredMemberProperties, not(hasItem(longVar))) - assertThat("getLongVar() still exists", kotlin.javaDeclaredMethods, not(hasItem(getLongVar))) - assertThat("setLongVar() still exists", kotlin.javaDeclaredMethods, not(hasItem(setLongVar))) - } - } - } - - @Test - fun deletedFunctionInsideStubbed() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(DELETED_FUN_CLASS).apply { - getDeclaredConstructor(String::class.java).newInstance(DEFAULT_MESSAGE).also { obj -> - assertEquals(DEFAULT_MESSAGE, obj.stringData()) - assertEquals(MESSAGE, (obj as HasUnwantedFun).unwantedFun(MESSAGE)) - } - assertThat("unwantedFun not found", kotlin.declaredMemberFunctions, hasItem(unwantedFun)) - assertThat("stringData() not found", kotlin.declaredMemberFunctions, hasItem(stringData)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(DELETED_FUN_CLASS).apply { - getDeclaredConstructor(String::class.java).newInstance(DEFAULT_MESSAGE).also { obj -> - assertFailsWith { obj.stringData() }.also { ex -> - assertThat(ex).hasMessage("Method has been deleted") - } - assertFailsWith { (obj as HasUnwantedFun).unwantedFun(MESSAGE) } - } - assertThat("unwantedFun still exists", kotlin.declaredMemberFunctions, not(hasItem(unwantedFun))) - assertThat("stringData() not found", kotlin.declaredMemberFunctions, hasItem(stringData)) - } - } - } - - @Test - fun deletedVarInsideStubbed() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(DELETED_VAR_CLASS).apply { - getDeclaredConstructor(String::class.java).newInstance(DEFAULT_MESSAGE).also { obj -> - assertEquals(DEFAULT_MESSAGE, obj.stringData()) - (obj as HasUnwantedVar).also { - assertEquals(DEFAULT_MESSAGE, it.unwantedVar) - it.unwantedVar = MESSAGE - assertEquals(MESSAGE, it.unwantedVar) - } - } - assertThat("unwantedVar not found", kotlin.declaredMemberProperties, hasItem(unwantedVar)) - assertThat("stringData() not found", kotlin.declaredMemberFunctions, hasItem(stringData)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(DELETED_VAR_CLASS).apply { - assertNotNull(getDeclaredConstructor(String::class.java).newInstance(MESSAGE)) - assertThat("unwantedVar still exists", kotlin.declaredMemberProperties, not(hasItem(unwantedVar))) - assertThat("getUnwantedVar() still exists", kotlin.javaDeclaredMethods, not(hasItem(getUnwantedVar))) - assertThat("setUnwantedVar() still exists", kotlin.javaDeclaredMethods, not(hasItem(setUnwantedVar))) - assertThat("stringData() not found", kotlin.declaredMemberFunctions, hasItem(stringData)) - assertThat("stringData() not found", kotlin.javaDeclaredMethods, hasItem(stringDataJava)) - } - } - } - - @Test - fun deletedValInsideStubbed() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(DELETED_VAL_CLASS).apply { - getDeclaredConstructor(String::class.java).newInstance(MESSAGE).also { obj -> - assertEquals(MESSAGE, obj.stringData()) - assertEquals(MESSAGE, (obj as HasUnwantedVal).unwantedVal) - } - assertThat("unwantedVal not found", kotlin.declaredMemberProperties, hasItem(unwantedVal)) - assertThat("stringData() not found", kotlin.declaredMemberFunctions, hasItem(stringData)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(DELETED_VAL_CLASS).apply { - assertNotNull(getDeclaredConstructor(String::class.java).newInstance(MESSAGE)) - assertThat("unwantedVal still exists", kotlin.declaredMemberProperties, not(hasItem(unwantedVal))) - assertThat("getUnwantedVal() still exists", kotlin.javaDeclaredMethods, not(hasItem(getUnwantedVal))) - assertThat("stringData() not found", kotlin.declaredMemberFunctions, hasItem(stringData)) - assertThat("stringData() not found", kotlin.javaDeclaredMethods, hasItem(stringDataJava)) - } - } - } - - @Test - fun deletePackageWithStubbed() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(DELETED_PKG_CLASS).apply { - getDeclaredMethod("stubbed", String::class.java).also { method -> - assertEquals("[$MESSAGE]", method.invoke(null, MESSAGE)) - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - assertFailsWith { cl.load(DELETED_PKG_CLASS) } - } - } -} \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteConstructorTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteConstructorTest.kt deleted file mode 100644 index 8a8651ef41..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteConstructorTest.kt +++ /dev/null @@ -1,165 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.jarfilter.matcher.* -import net.corda.gradle.unwanted.HasAll -import net.corda.gradle.unwanted.HasInt -import net.corda.gradle.unwanted.HasLong -import net.corda.gradle.unwanted.HasString -import org.hamcrest.core.IsCollectionContaining.hasItem -import org.hamcrest.core.IsNot.not -import org.junit.Assert.* -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import kotlin.jvm.kotlin -import kotlin.reflect.full.primaryConstructor -import kotlin.test.assertFailsWith - -class DeleteConstructorTest { - companion object { - private const val STRING_PRIMARY_CONSTRUCTOR_CLASS = "net.corda.gradle.PrimaryStringConstructorToDelete" - private const val LONG_PRIMARY_CONSTRUCTOR_CLASS = "net.corda.gradle.PrimaryLongConstructorToDelete" - private const val INT_PRIMARY_CONSTRUCTOR_CLASS = "net.corda.gradle.PrimaryIntConstructorToDelete" - private const val SECONDARY_CONSTRUCTOR_CLASS = "net.corda.gradle.HasConstructorToDelete" - - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "delete-constructor") - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - } - - @Test - fun deleteConstructorWithLongParameter() { - val longConstructor = isConstructor(SECONDARY_CONSTRUCTOR_CLASS, Long::class) - - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(SECONDARY_CONSTRUCTOR_CLASS).apply { - getDeclaredConstructor(Long::class.java).newInstance(BIG_NUMBER).also { - assertEquals(BIG_NUMBER, it.longData()) - } - assertThat("(J) not found", kotlin.constructors, hasItem(longConstructor)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(SECONDARY_CONSTRUCTOR_CLASS).apply { - assertFailsWith { getDeclaredConstructor(Long::class.java) } - assertThat("(J) still exists", kotlin.constructors, not(hasItem(longConstructor))) - assertNotNull("primary constructor missing", kotlin.primaryConstructor) - } - } - } - - @Test - fun deleteConstructorWithStringParameter() { - val stringConstructor = isConstructor(SECONDARY_CONSTRUCTOR_CLASS, String::class) - - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(SECONDARY_CONSTRUCTOR_CLASS).apply { - getDeclaredConstructor(String::class.java).newInstance(MESSAGE).also { - assertEquals(MESSAGE, it.stringData()) - } - assertThat("(String) not found", kotlin.constructors, hasItem(stringConstructor)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(SECONDARY_CONSTRUCTOR_CLASS).apply { - assertFailsWith { getDeclaredConstructor(String::class.java) } - assertThat("(String) still exists", kotlin.constructors, not(hasItem(stringConstructor))) - assertNotNull("primary constructor missing", kotlin.primaryConstructor) - } - } - } - - @Test - fun showUnannotatedConstructorIsUnaffected() { - val intConstructor = isConstructor(SECONDARY_CONSTRUCTOR_CLASS, Int::class) - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(SECONDARY_CONSTRUCTOR_CLASS).apply { - getDeclaredConstructor(Int::class.java).newInstance(NUMBER).also { - assertEquals(NUMBER, it.intData()) - assertEquals(NUMBER.toLong(), it.longData()) - assertEquals("", it.stringData()) - } - assertThat("(Int) not found", kotlin.constructors, hasItem(intConstructor)) - assertNotNull("primary constructor missing", kotlin.primaryConstructor) - } - } - } - - @Test - fun deletePrimaryConstructorWithStringParameter() { - val stringConstructor = isConstructor(STRING_PRIMARY_CONSTRUCTOR_CLASS, String::class) - - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(STRING_PRIMARY_CONSTRUCTOR_CLASS).apply { - getDeclaredConstructor(String::class.java).newInstance(MESSAGE).also { - assertEquals(MESSAGE, it.stringData()) - } - assertThat("(String) not found", kotlin.constructors, hasItem(stringConstructor)) - assertThat("primary constructor missing", kotlin.primaryConstructor!!, stringConstructor) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(STRING_PRIMARY_CONSTRUCTOR_CLASS).apply { - assertFailsWith { getDeclaredConstructor(String::class.java) } - assertThat("(String) still exists", kotlin.constructors, not(hasItem(stringConstructor))) - assertNull("primary constructor still exists", kotlin.primaryConstructor) - } - } - } - - @Test - fun deletePrimaryConstructorWithLongParameter() { - val longConstructor = isConstructor(LONG_PRIMARY_CONSTRUCTOR_CLASS, Long::class) - - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(LONG_PRIMARY_CONSTRUCTOR_CLASS).apply { - getDeclaredConstructor(Long::class.java).newInstance(BIG_NUMBER).also { - assertEquals(BIG_NUMBER, it.longData()) - } - assertThat("(J) not found", kotlin.constructors, hasItem(longConstructor)) - assertThat("primary constructor missing", kotlin.primaryConstructor!!, longConstructor) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(LONG_PRIMARY_CONSTRUCTOR_CLASS).apply { - assertFailsWith { getDeclaredConstructor(Long::class.java) } - assertThat("(J) still exists", kotlin.constructors, not(hasItem(longConstructor))) - assertNull("primary constructor still exists", kotlin.primaryConstructor) - } - } - } - - @Test - fun deletePrimaryConstructorWithIntParameter() { - val intConstructor = isConstructor(INT_PRIMARY_CONSTRUCTOR_CLASS, Int::class) - - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(INT_PRIMARY_CONSTRUCTOR_CLASS).apply { - getDeclaredConstructor(Int::class.java).newInstance(NUMBER).also { - assertEquals(NUMBER, it.intData()) - } - assertThat("(I) not found", kotlin.constructors, hasItem(intConstructor)) - assertThat("primary constructor missing", kotlin.primaryConstructor!!, intConstructor) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(INT_PRIMARY_CONSTRUCTOR_CLASS).apply { - assertFailsWith { getDeclaredConstructor(Int::class.java) } - assertThat("(I) still exists", kotlin.constructors, not(hasItem(intConstructor))) - assertNull("primary constructor still exists", kotlin.primaryConstructor) - } - } - } -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteExtensionValPropertyTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteExtensionValPropertyTest.kt deleted file mode 100644 index 4723caef19..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteExtensionValPropertyTest.kt +++ /dev/null @@ -1,52 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.jarfilter.matcher.isMethod -import net.corda.gradle.jarfilter.matcher.isProperty -import net.corda.gradle.jarfilter.matcher.javaDeclaredMethods -import net.corda.gradle.unwanted.HasUnwantedVal -import org.hamcrest.core.IsCollectionContaining.* -import org.hamcrest.core.IsNot.* -import org.junit.Assert.* -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import kotlin.reflect.full.declaredMemberExtensionProperties -import kotlin.reflect.full.declaredMemberProperties - -class DeleteExtensionValPropertyTest { - companion object { - private const val PROPERTY_CLASS = "net.corda.gradle.HasValExtension" - - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "delete-extension-val") - private val unwantedVal = isProperty("unwantedVal", String::class) - private val getUnwantedVal = isMethod("getUnwantedVal", String::class.java, List::class.java) - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - } - - @Test - fun deleteExtensionProperty() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - assertThat("unwantedVal not found", kotlin.declaredMemberProperties, hasItem(unwantedVal)) - assertThat("getUnwantedVal not found", kotlin.javaDeclaredMethods, hasItem(getUnwantedVal)) - assertThat("List.unwantedVal not found", kotlin.declaredMemberExtensionProperties, hasItem(unwantedVal)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - assertThat("unwantedVal not found", kotlin.declaredMemberProperties, hasItem(unwantedVal)) - assertThat("getUnwantedVal still exists", kotlin.javaDeclaredMethods, not(hasItem(getUnwantedVal))) - assertThat("List.unwantedVal still exists", kotlin.declaredMemberExtensionProperties, not(hasItem(unwantedVal))) - } - } - } -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteFieldTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteFieldTest.kt deleted file mode 100644 index 4be9530f20..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteFieldTest.kt +++ /dev/null @@ -1,99 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.jarfilter.matcher.* -import org.hamcrest.core.IsCollectionContaining.hasItem -import org.hamcrest.core.IsNot.not -import org.junit.Assert.* -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import kotlin.reflect.full.declaredMemberProperties -import kotlin.test.assertFailsWith - -class DeleteFieldTest { - companion object { - private const val STRING_FIELD_CLASS = "net.corda.gradle.HasStringFieldToDelete" - private const val INTEGER_FIELD_CLASS = "net.corda.gradle.HasIntFieldToDelete" - private const val LONG_FIELD_CLASS = "net.corda.gradle.HasLongFieldToDelete" - - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "delete-field") - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - } - - @Test - fun deleteStringField() { - val stringField = isProperty("stringField", String::class) - - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(STRING_FIELD_CLASS).apply { - val obj: Any = getDeclaredConstructor(String::class.java).newInstance(MESSAGE) - getDeclaredField("stringField").also { field -> - assertEquals(MESSAGE, field.get(obj)) - } - assertThat("stringField not found", kotlin.declaredMemberProperties, hasItem(stringField)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(STRING_FIELD_CLASS).apply { - assertNotNull(getDeclaredConstructor(String::class.java).newInstance(MESSAGE)) - assertFailsWith { getDeclaredField("stringField") } - assertThat("stringField still exists", kotlin.declaredMemberProperties, not(hasItem(stringField))) - } - } - } - - @Test - fun deleteLongField() { - val longField = isProperty("longField", Long::class) - - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(LONG_FIELD_CLASS).apply { - val obj: Any = getDeclaredConstructor(Long::class.java).newInstance(BIG_NUMBER) - getDeclaredField("longField").also { field -> - assertEquals(BIG_NUMBER, field.get(obj)) - } - assertThat("longField not found", kotlin.declaredMemberProperties, hasItem(longField)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(LONG_FIELD_CLASS).apply { - assertNotNull(getDeclaredConstructor(Long::class.java).newInstance(BIG_NUMBER)) - assertFailsWith { getDeclaredField("longField") } - assertThat("longField still exists", kotlin.declaredMemberProperties, not(hasItem(longField))) - } - } - } - - @Test - fun deleteIntegerField() { - val intField = isProperty("intField", Int::class) - - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(INTEGER_FIELD_CLASS).apply { - val obj: Any = getDeclaredConstructor(Int::class.java).newInstance(NUMBER) - getDeclaredField("intField").also { field -> - assertEquals(NUMBER, field.get(obj)) - } - assertThat("intField not found", kotlin.declaredMemberProperties, hasItem(intField)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(INTEGER_FIELD_CLASS).apply { - assertNotNull(getDeclaredConstructor(Int::class.java).newInstance(NUMBER)) - assertFailsWith { getDeclaredField("intField") } - assertThat("intField still exists", kotlin.declaredMemberProperties, not(hasItem(intField))) - } - } - } -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteFunctionTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteFunctionTest.kt deleted file mode 100644 index 8e035fead8..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteFunctionTest.kt +++ /dev/null @@ -1,81 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.jarfilter.matcher.* -import net.corda.gradle.unwanted.HasString -import net.corda.gradle.unwanted.HasUnwantedFun -import org.hamcrest.core.IsCollectionContaining.hasItem -import org.hamcrest.core.IsNot.not -import org.junit.Assert.* -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import kotlin.jvm.kotlin -import kotlin.reflect.full.declaredFunctions -import kotlin.test.assertFailsWith - -class DeleteFunctionTest { - companion object { - private const val FUNCTION_CLASS = "net.corda.gradle.HasFunctionToDelete" - private const val INDIRECT_CLASS = "net.corda.gradle.HasIndirectFunctionToDelete" - - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "delete-function") - private val unwantedFun = isFunction("unwantedFun", String::class, String::class) - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - } - - @Test - fun deleteFunction() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(FUNCTION_CLASS).apply { - newInstance().also { - assertEquals(MESSAGE, it.unwantedFun(MESSAGE)) - } - assertThat("unwantedFun(String) not found", kotlin.declaredFunctions, hasItem(unwantedFun)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(FUNCTION_CLASS).apply { - newInstance().also { - assertFailsWith { it.unwantedFun(MESSAGE) } - } - assertThat("unwantedFun(String) still exists", kotlin.declaredFunctions, not(hasItem(unwantedFun))) - } - } - } - - @Test - fun deleteIndirectFunction() { - val stringData = isFunction("stringData", String::class) - - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(INDIRECT_CLASS).apply { - getDeclaredConstructor(String::class.java).newInstance(MESSAGE).also { - assertEquals(MESSAGE, it.unwantedFun(MESSAGE)) - assertEquals(MESSAGE, (it as HasString).stringData()) - } - assertThat("unwantedFun(String) not found", kotlin.declaredFunctions, hasItem(unwantedFun)) - assertThat("stringData() not found", kotlin.declaredFunctions, hasItem(stringData)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(INDIRECT_CLASS).apply { - getDeclaredConstructor(String::class.java).newInstance(MESSAGE).also { - assertFailsWith { it.unwantedFun(MESSAGE) } - assertFailsWith { (it as HasString).stringData() } - } - assertThat("unwantedFun(String) still exists", kotlin.declaredFunctions, not(hasItem(unwantedFun))) - assertThat("stringData still exists", kotlin.declaredFunctions, not(hasItem(stringData))) - } - } - } -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteInnerLambdaTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteInnerLambdaTest.kt deleted file mode 100644 index 14f1f4edc9..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteInnerLambdaTest.kt +++ /dev/null @@ -1,84 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.jarfilter.matcher.isConstructor -import net.corda.gradle.unwanted.HasInt -import org.assertj.core.api.Assertions.assertThat -import org.hamcrest.core.IsCollectionContaining.* -import org.hamcrest.core.IsNot.* -import org.junit.Assert.* -import org.junit.BeforeClass -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import kotlin.test.assertFailsWith - -class DeleteInnerLambdaTest { - companion object { - private const val LAMBDA_CLASS = "net.corda.gradle.HasInnerLambda" - private const val SIZE = 64 - - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "delete-inner-lambda") - private val constructInt = isConstructor(LAMBDA_CLASS, Int::class) - private val constructBytes = isConstructor(LAMBDA_CLASS, ByteArray::class) - - private lateinit var sourceClasses: List - private lateinit var filteredClasses: List - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - - @BeforeClass - @JvmStatic - fun setup() { - sourceClasses = testProject.sourceJar.getClassNames(LAMBDA_CLASS) - filteredClasses = testProject.filteredJar.getClassNames(LAMBDA_CLASS) - } - } - - @Test - fun `test lambda class is deleted`() { - assertThat(sourceClasses) - .contains(LAMBDA_CLASS) - .hasSize(2) - assertThat(filteredClasses).containsExactly(LAMBDA_CLASS) - } - - @Test - fun `test host class`() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(LAMBDA_CLASS).apply { - getConstructor(Int::class.java).newInstance(SIZE).also { obj -> - assertEquals(SIZE, obj.intData()) - } - kotlin.constructors.also { ctors -> - assertThat("(Int) not found", ctors, hasItem(constructInt)) - assertThat("(byte[]) not found", ctors, hasItem(constructBytes)) - } - - getConstructor(ByteArray::class.java).newInstance(ByteArray(SIZE)).also { obj -> - assertEquals(SIZE, obj.intData()) - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(LAMBDA_CLASS).apply { - assertFailsWith { getConstructor(Int::class.java) } - kotlin.constructors.also { ctors -> - assertThat("(Int) still exists", ctors, not(hasItem(constructInt))) - assertThat("(byte[]) not found", ctors, hasItem(constructBytes)) - } - - getConstructor(ByteArray::class.java).newInstance(ByteArray(SIZE)).also { obj -> - assertEquals(SIZE, obj.intData()) - } - } - } - } -} \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteLazyTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteLazyTest.kt deleted file mode 100644 index ac217fea87..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteLazyTest.kt +++ /dev/null @@ -1,71 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.jarfilter.matcher.* -import net.corda.gradle.unwanted.HasUnwantedVal -import org.assertj.core.api.Assertions.* -import org.hamcrest.core.IsCollectionContaining.* -import org.hamcrest.core.IsNot.* -import org.junit.Assert.* -import org.junit.BeforeClass -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import kotlin.reflect.full.declaredMemberProperties -import kotlin.test.assertFailsWith - -class DeleteLazyTest { - companion object { - private const val LAZY_VAL_CLASS = "net.corda.gradle.HasLazyVal" - - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "delete-lazy") - private val unwantedVal = isProperty("unwantedVal", String::class) - private val getUnwantedVal = isMethod("getUnwantedVal", String::class.java) - private lateinit var sourceClasses: List - private lateinit var filteredClasses: List - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - - @BeforeClass - @JvmStatic - fun setup() { - sourceClasses = testProject.sourceJar.getClassNames(LAZY_VAL_CLASS) - filteredClasses = testProject.filteredJar.getClassNames(LAZY_VAL_CLASS) - } - } - - @Test - fun deletedClasses() { - assertThat(sourceClasses).contains(LAZY_VAL_CLASS) - assertThat(filteredClasses).containsExactly(LAZY_VAL_CLASS) - } - - @Test - fun deleteLazyVal() { - assertThat(sourceClasses).anyMatch { it.contains("\$unwantedVal\$") } - - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(LAZY_VAL_CLASS).apply { - getConstructor(String::class.java).newInstance(MESSAGE).also { obj -> - assertEquals(MESSAGE, obj.unwantedVal) - } - assertThat("getUnwantedVal not found", kotlin.javaDeclaredMethods, hasItem(getUnwantedVal)) - assertThat("unwantedVal not found", kotlin.declaredMemberProperties, hasItem(unwantedVal)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(LAZY_VAL_CLASS).apply { - assertFailsWith { getConstructor(String::class.java) } - assertThat("getUnwantedVal still exists", kotlin.javaDeclaredMethods, not(hasItem(getUnwantedVal))) - assertThat("unwantedVal still exists", kotlin.declaredMemberProperties, not(hasItem(unwantedVal))) - } - } - } -} \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteMultiFileTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteMultiFileTest.kt deleted file mode 100644 index 4c7333c41a..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteMultiFileTest.kt +++ /dev/null @@ -1,90 +0,0 @@ -package net.corda.gradle.jarfilter - -import org.assertj.core.api.Assertions.* -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import kotlin.test.assertFailsWith - -class DeleteMultiFileTest { - companion object { - private const val MULTIFILE_CLASS = "net.corda.gradle.HasMultiData" - private const val STRING_METHOD = "stringToDelete" - private const val LONG_METHOD = "longToDelete" - private const val INT_METHOD = "intToDelete" - - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "delete-multifile") - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - } - - @Test - fun deleteStringFunction() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(MULTIFILE_CLASS).apply { - getMethod(STRING_METHOD, String::class.java).also { method -> - method.invoke(null, MESSAGE).also { result -> - assertThat(result) - .isInstanceOf(String::class.java) - .isEqualTo(MESSAGE) - } - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(MULTIFILE_CLASS).apply { - assertFailsWith { getMethod(STRING_METHOD, String::class.java) } - } - } - } - - @Test - fun deleteLongFunction() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(MULTIFILE_CLASS).apply { - getMethod(LONG_METHOD, Long::class.java).also { method -> - method.invoke(null, BIG_NUMBER).also { result -> - assertThat(result) - .isInstanceOf(Long::class.javaObjectType) - .isEqualTo(BIG_NUMBER) - } - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(MULTIFILE_CLASS).apply { - assertFailsWith { getMethod(LONG_METHOD, Long::class.java) } - } - } - } - - @Test - fun deleteIntFunction() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(MULTIFILE_CLASS).apply { - getMethod(INT_METHOD, Int::class.java).also { method -> - method.invoke(null, NUMBER).also { result -> - assertThat(result) - .isInstanceOf(Int::class.javaObjectType) - .isEqualTo(NUMBER) - } - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(MULTIFILE_CLASS).apply { - assertFailsWith { getMethod(INT_METHOD, Int::class.java) } - } - } - } -} \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteNestedClassTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteNestedClassTest.kt deleted file mode 100644 index 934a2797bc..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteNestedClassTest.kt +++ /dev/null @@ -1,90 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.jarfilter.asm.classMetadata -import net.corda.gradle.jarfilter.matcher.isClass -import org.assertj.core.api.Assertions.* -import org.hamcrest.core.IsCollectionContaining.hasItem -import org.hamcrest.core.IsNot.not -import org.junit.Assert.* -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import kotlin.test.assertFailsWith - -class DeleteNestedClassTest { - companion object { - private const val HOST_CLASS = "net.corda.gradle.HasNestedClasses" - private const val KEPT_CLASS = "$HOST_CLASS\$OneToKeep" - private const val DELETED_CLASS = "$HOST_CLASS\$OneToThrowAway" - - private const val SEALED_CLASS = "net.corda.gradle.SealedClass" - private const val WANTED_SUBCLASS = "$SEALED_CLASS\$Wanted" - private const val UNWANTED_SUBCLASS = "$SEALED_CLASS\$Unwanted" - - private val keptClass = isClass(KEPT_CLASS) - private val deletedClass = isClass(DELETED_CLASS) - private val wantedSubclass = isClass(WANTED_SUBCLASS) - private val unwantedSubclass = isClass(UNWANTED_SUBCLASS) - - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "delete-nested-class") - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - } - - @Test - fun deleteNestedClass() { - classLoaderFor(testProject.sourceJar).use { cl -> - val deleted = cl.load(DELETED_CLASS) - val kept = cl.load(KEPT_CLASS) - cl.load(HOST_CLASS).apply { - assertThat(declaredClasses).containsExactlyInAnyOrder(deleted, kept) - assertThat("OneToThrowAway class is missing", kotlin.nestedClasses, hasItem(deletedClass)) - assertThat("OneToKeep class is missing", kotlin.nestedClasses, hasItem(keptClass)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - assertFailsWith { cl.load(DELETED_CLASS) } - val kept = cl.load(KEPT_CLASS) - cl.load(HOST_CLASS).apply { - assertThat(declaredClasses).containsExactly(kept) - assertThat("OneToThrowAway class still exists", kotlin.nestedClasses, not(hasItem(deletedClass))) - assertThat("OneToKeep class is missing", kotlin.nestedClasses, hasItem(keptClass)) - } - } - } - - @Test - fun deleteFromSealedClass() { - classLoaderFor(testProject.sourceJar).use { cl -> - val unwanted = cl.load(UNWANTED_SUBCLASS) - val wanted = cl.load(WANTED_SUBCLASS) - cl.load(SEALED_CLASS).apply { - assertTrue(kotlin.isSealed) - assertThat(declaredClasses).containsExactlyInAnyOrder(wanted, unwanted) - assertThat("Wanted class is missing", kotlin.nestedClasses, hasItem(wantedSubclass)) - assertThat("Unwanted class is missing", kotlin.nestedClasses, hasItem(unwantedSubclass)) - assertThat(classMetadata.sealedSubclasses).containsExactlyInAnyOrder(WANTED_SUBCLASS, UNWANTED_SUBCLASS) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - assertFailsWith { cl.load(UNWANTED_SUBCLASS) } - val wanted = cl.load(WANTED_SUBCLASS) - cl.load(SEALED_CLASS).apply { - assertTrue(kotlin.isSealed) - assertThat(declaredClasses).containsExactly(wanted) - assertThat("Unwanted class still exists", kotlin.nestedClasses, not(hasItem(unwantedSubclass))) - assertThat("Wanted class is missing", kotlin.nestedClasses, hasItem(wantedSubclass)) - assertThat(classMetadata.sealedSubclasses).containsExactly(WANTED_SUBCLASS) - } - } - } -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteObjectTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteObjectTest.kt deleted file mode 100644 index 5e6db4a4b1..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteObjectTest.kt +++ /dev/null @@ -1,89 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.unwanted.HasUnwantedFun -import org.assertj.core.api.Assertions.* -import org.junit.Assert.* -import org.junit.BeforeClass -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import kotlin.test.assertFailsWith - -class DeleteObjectTest { - companion object { - private const val OBJECT_CLASS = "net.corda.gradle.HasObjects" - private const val UNWANTED_OBJ_METHOD = "getUnwantedObj" - private const val UNWANTED_OBJ_FIELD = "unwantedObj" - private const val UNWANTED_FUN_METHOD = "unwantedFun" - - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "delete-object") - private lateinit var sourceClasses: List - private lateinit var filteredClasses: List - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - - @BeforeClass - @JvmStatic - fun setup() { - sourceClasses = testProject.sourceJar.getClassNames(OBJECT_CLASS) - filteredClasses = testProject.filteredJar.getClassNames(OBJECT_CLASS) - } - } - - @Test - fun deletedClasses() { - assertThat(sourceClasses).contains(OBJECT_CLASS) - assertThat(filteredClasses).containsExactly(OBJECT_CLASS) - } - - @Test - fun deleteObject() { - assertThat(sourceClasses).anyMatch { it.contains("\$unwantedObj\$") } - - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(OBJECT_CLASS).apply { - getDeclaredMethod(UNWANTED_OBJ_METHOD).also { method -> - (method.invoke(null) as HasUnwantedFun).also { obj -> - assertEquals(MESSAGE, obj.unwantedFun(MESSAGE)) - } - } - getDeclaredField(UNWANTED_OBJ_FIELD).also { field -> - assertFalse(field.isAccessible) - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(OBJECT_CLASS).apply { - assertFailsWith { getDeclaredMethod(UNWANTED_OBJ_METHOD) } - assertFailsWith { getDeclaredField(UNWANTED_OBJ_FIELD) } - } - } - } - - @Test - fun deleteFunctionWithObject() { - assertThat(sourceClasses).anyMatch { it.contains("\$unwantedFun\$") } - - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(OBJECT_CLASS).apply { - getDeclaredMethod(UNWANTED_FUN_METHOD).also { method -> - assertEquals("", method.invoke(null)) - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(OBJECT_CLASS).apply { - assertFailsWith { getDeclaredMethod(UNWANTED_FUN_METHOD) } - } - } - } -} \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteSealedSubclassTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteSealedSubclassTest.kt deleted file mode 100644 index eeb90e4c7f..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteSealedSubclassTest.kt +++ /dev/null @@ -1,56 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.jarfilter.asm.classMetadata -import org.assertj.core.api.Assertions.assertThat -import org.junit.Assert.* -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import kotlin.test.assertFailsWith - -/** - * Sealed classes can have non-nested subclasses, so long as those subclasses - * are declared in the same file as the sealed class. Check that the metadata - * is still updated correctly in this case. - */ -class DeleteSealedSubclassTest { - companion object { - private const val SEALED_CLASS = "net.corda.gradle.SealedBaseClass" - private const val WANTED_SUBCLASS = "net.corda.gradle.WantedSubclass" - private const val UNWANTED_SUBCLASS = "net.corda.gradle.UnwantedSubclass" - - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "delete-sealed-subclass") - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - } - - @Test - fun deleteUnwantedSubclass() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(WANTED_SUBCLASS) - cl.load(UNWANTED_SUBCLASS) - cl.load(SEALED_CLASS).apply { - assertTrue(kotlin.isSealed) - assertThat(classMetadata.sealedSubclasses) - .containsExactlyInAnyOrder(WANTED_SUBCLASS, UNWANTED_SUBCLASS) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(WANTED_SUBCLASS) - assertFailsWith { cl.load(UNWANTED_SUBCLASS) } - cl.load(SEALED_CLASS).apply { - assertTrue(kotlin.isSealed) - assertThat(classMetadata.sealedSubclasses) - .containsExactly(WANTED_SUBCLASS) - } - } - } -} \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteStaticFieldTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteStaticFieldTest.kt deleted file mode 100644 index 1b3d668035..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteStaticFieldTest.kt +++ /dev/null @@ -1,74 +0,0 @@ -package net.corda.gradle.jarfilter - -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import kotlin.test.assertEquals -import kotlin.test.assertFailsWith - -class DeleteStaticFieldTest { - companion object { - private const val PROPERTY_CLASS = "net.corda.gradle.StaticFieldsToDelete" - private const val DEFAULT_BIG_NUMBER: Long = 123456789L - private const val DEFAULT_NUMBER: Int = 123456 - - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "delete-static-field") - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - } - - @Test - fun deleteStringField() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - val getter = getDeclaredField("stringField") - assertEquals(DEFAULT_MESSAGE, getter.get(null)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - assertFailsWith { getDeclaredField("stringField") } - } - } - } - - @Test - fun deleteLongField() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - val getter = getDeclaredField("longField") - assertEquals(DEFAULT_BIG_NUMBER, getter.get(null)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - assertFailsWith { getDeclaredField("longField") } - } - } - } - - @Test - fun deleteIntField() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - val getter = getDeclaredField("intField") - assertEquals(DEFAULT_NUMBER, getter.get(null)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - assertFailsWith { getDeclaredField("intField") } - } - } - } -} \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteStaticFunctionTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteStaticFunctionTest.kt deleted file mode 100644 index 5ad8102dfb..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteStaticFunctionTest.kt +++ /dev/null @@ -1,87 +0,0 @@ -package net.corda.gradle.jarfilter - -import org.assertj.core.api.Assertions.* -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import kotlin.test.assertFailsWith - -class DeleteStaticFunctionTest { - companion object { - private const val FUNCTION_CLASS = "net.corda.gradle.StaticFunctionsToDelete" - - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "delete-static-function") - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - } - - @Test - fun deleteStringFunction() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(FUNCTION_CLASS).apply { - getMethod("unwantedStringToDelete", String::class.java).also { method -> - method.invoke(null, MESSAGE).also { result -> - assertThat(result) - .isInstanceOf(String::class.java) - .isEqualTo(MESSAGE) - } - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(FUNCTION_CLASS).apply { - assertFailsWith { getMethod("unwantedStringToDelete", String::class.java) } - } - } - } - - @Test - fun deleteLongFunction() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(FUNCTION_CLASS).apply { - getMethod("unwantedLongToDelete", Long::class.java).also { method -> - method.invoke(null, BIG_NUMBER).also { result -> - assertThat(result) - .isInstanceOf(Long::class.javaObjectType) - .isEqualTo(BIG_NUMBER) - } - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(FUNCTION_CLASS).apply { - assertFailsWith { getMethod("unwantedLongToDelete", Long::class.java) } - } - } - } - - @Test - fun deleteIntFunction() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(FUNCTION_CLASS).apply { - getMethod("unwantedIntToDelete", Int::class.java).also { method -> - method.invoke(null, NUMBER).also { result -> - assertThat(result) - .isInstanceOf(Int::class.javaObjectType) - .isEqualTo(NUMBER) - } - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(FUNCTION_CLASS).apply { - assertFailsWith { getMethod("unwantedIntToDelete", Int::class.java) } - } - } - } -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteStaticValPropertyTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteStaticValPropertyTest.kt deleted file mode 100644 index e24afa4b99..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteStaticValPropertyTest.kt +++ /dev/null @@ -1,91 +0,0 @@ -package net.corda.gradle.jarfilter - -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import kotlin.test.assertEquals -import kotlin.test.assertFailsWith - -class DeleteStaticValPropertyTest { - companion object { - private const val PROPERTY_CLASS = "net.corda.gradle.StaticValToDelete" - private const val DEFAULT_BIG_NUMBER: Long = 123456789L - private const val DEFAULT_NUMBER: Int = 123456 - private object LocalBlob - - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "delete-static-val") - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - } - - @Test - fun deleteStringVal() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - val getter = getDeclaredMethod("getStringVal") - assertEquals(DEFAULT_MESSAGE, getter.invoke(null)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - assertFailsWith { getDeclaredMethod("getStringVal") } - } - } - } - - @Test - fun deleteLongVal() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - val getter = getDeclaredMethod("getLongVal") - assertEquals(DEFAULT_BIG_NUMBER, getter.invoke(null)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - assertFailsWith { getDeclaredMethod("getLongVal") } - } - } - } - - @Test - fun deleteIntVal() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - val getter = getDeclaredMethod("getIntVal") - assertEquals(DEFAULT_NUMBER, getter.invoke(null)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - assertFailsWith { getDeclaredMethod("getIntVal") } - } - } - } - - @Test - fun deleteMemberVal() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - val getter = getDeclaredMethod("getMemberVal", Any::class.java) - assertEquals(LocalBlob, getter.invoke(null, LocalBlob)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - assertFailsWith { getDeclaredMethod("getMemberVal", Any::class.java) } - } - } - } -} \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteStaticVarPropertyTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteStaticVarPropertyTest.kt deleted file mode 100644 index 9bac98c37b..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteStaticVarPropertyTest.kt +++ /dev/null @@ -1,106 +0,0 @@ -package net.corda.gradle.jarfilter - -import org.junit.Assert.* -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import kotlin.test.assertFailsWith - -class DeleteStaticVarPropertyTest { - companion object { - private const val PROPERTY_CLASS = "net.corda.gradle.StaticVarToDelete" - private const val DEFAULT_BIG_NUMBER: Long = 123456789L - private const val DEFAULT_NUMBER: Int = 123456 - private object LocalBlob - - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "delete-static-var") - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - } - - @Test - fun deleteStringVar() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - val getter = getDeclaredMethod("getStringVar") - val setter = getDeclaredMethod("setStringVar", String::class.java) - assertEquals(DEFAULT_MESSAGE, getter.invoke(null)) - setter.invoke(null, MESSAGE) - assertEquals(MESSAGE, getter.invoke(null)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - assertFailsWith { getDeclaredMethod("getStringVar") } - assertFailsWith { getDeclaredMethod("setStringVar", String::class.java) } - } - } - } - - @Test - fun deleteLongVar() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - val getter = getDeclaredMethod("getLongVar") - val setter = getDeclaredMethod("setLongVar", Long::class.java) - assertEquals(DEFAULT_BIG_NUMBER, getter.invoke(null)) - setter.invoke(null, BIG_NUMBER) - assertEquals(BIG_NUMBER, getter.invoke(null)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - assertFailsWith { getDeclaredMethod("getLongVar") } - assertFailsWith { getDeclaredMethod("setLongVar", Long::class.java) } - } - } - } - - @Test - fun deleteIntVar() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - val getter = getDeclaredMethod("getIntVar") - val setter = getDeclaredMethod("setIntVar", Int::class.java) - assertEquals(DEFAULT_NUMBER, getter.invoke(null)) - setter.invoke(null, NUMBER) - assertEquals(NUMBER, getter.invoke(null)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - assertFailsWith { getDeclaredMethod("getIntVar") } - assertFailsWith { getDeclaredMethod("setIntVar", Int::class.java) } - } - } - } - - @Test - fun deleteMemberVar() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - val getter = getDeclaredMethod("getMemberVar", Any::class.java) - val setter = getDeclaredMethod("setMemberVar", Any::class.java, Any::class.java) - assertEquals(LocalBlob, getter.invoke(null, LocalBlob)) - setter.invoke(null, LocalBlob, LocalBlob) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - assertFailsWith { getDeclaredMethod("getMemberVar", Any::class.java) } - assertFailsWith { getDeclaredMethod("setMemberVar", Any::class.java, Any::class.java) } - } - } - } -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteTypeAliasFromFileTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteTypeAliasFromFileTest.kt deleted file mode 100644 index bb2dc6f2a7..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteTypeAliasFromFileTest.kt +++ /dev/null @@ -1,48 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.jarfilter.asm.fileMetadata -import org.assertj.core.api.Assertions.assertThat -import org.junit.BeforeClass -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule - -class DeleteTypeAliasFromFileTest { - companion object { - private const val TYPEALIAS_CLASS = "net.corda.gradle.FileWithTypeAlias" - - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "delete-file-typealias") - private lateinit var sourceClasses: List - private lateinit var filteredClasses: List - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - - @BeforeClass - @JvmStatic - fun setup() { - sourceClasses = testProject.sourceJar.getClassNames(TYPEALIAS_CLASS) - filteredClasses = testProject.filteredJar.getClassNames(TYPEALIAS_CLASS) - } - } - - @Test - fun deleteTypeAlias() { - classLoaderFor(testProject.sourceJar).use { cl -> - val metadata = cl.load(TYPEALIAS_CLASS).fileMetadata - assertThat(metadata.typeAliasNames) - .containsExactlyInAnyOrder("FileWantedType", "FileUnwantedType") - } - classLoaderFor(testProject.filteredJar).use { cl -> - val metadata = cl.load(TYPEALIAS_CLASS).fileMetadata - assertThat(metadata.typeAliasNames) - .containsExactly("FileWantedType") - } - } -} \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteValPropertyTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteValPropertyTest.kt deleted file mode 100644 index 75d59b4e54..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteValPropertyTest.kt +++ /dev/null @@ -1,102 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.jarfilter.matcher.* -import net.corda.gradle.unwanted.HasUnwantedVal -import org.hamcrest.core.IsCollectionContaining.* -import org.hamcrest.core.IsNot.* -import org.junit.Assert.* -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import kotlin.reflect.full.declaredMemberProperties -import kotlin.test.assertFailsWith - -class DeleteValPropertyTest { - companion object { - private const val PROPERTY_CLASS = "net.corda.gradle.HasValPropertyForDelete" - private const val GETTER_CLASS = "net.corda.gradle.HasValGetterForDelete" - private const val JVM_FIELD_CLASS = "net.corda.gradle.HasValJvmFieldForDelete" - - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "delete-val-property") - private val unwantedVal = isProperty("unwantedVal", String::class) - private val getUnwantedVal = isMethod("getUnwantedVal", String::class.java) - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - } - - @Test - fun deleteProperty() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - getDeclaredConstructor(String::class.java).newInstance(MESSAGE).also { obj -> - assertEquals(MESSAGE, obj.unwantedVal) - } - assertFalse(getDeclaredField("unwantedVal").isAccessible) - assertThat("unwantedVal not found", kotlin.declaredMemberProperties, hasItem(unwantedVal)) - assertThat("getUnwantedVal not found", kotlin.javaDeclaredMethods, hasItem(getUnwantedVal)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - getDeclaredConstructor(String::class.java).newInstance(MESSAGE).also { obj -> - assertFailsWith { obj.unwantedVal } - } - assertFailsWith { getDeclaredField("unwantedVal") } - assertThat("unwantedVal still exists", kotlin.declaredMemberProperties, not(hasItem(unwantedVal))) - assertThat("getUnwantedVal still exists", kotlin.javaDeclaredMethods, not(hasItem(getUnwantedVal))) - } - } - } - - @Test - fun deleteGetter() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(GETTER_CLASS).apply { - getDeclaredConstructor(String::class.java).newInstance(MESSAGE).also { obj -> - assertEquals(MESSAGE, obj.unwantedVal) - } - assertFalse(getDeclaredField("unwantedVal").isAccessible) - assertThat("getUnwantedVal not found", kotlin.javaDeclaredMethods, hasItem(getUnwantedVal)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(GETTER_CLASS).apply { - getDeclaredConstructor(String::class.java).newInstance(MESSAGE).also { obj -> - assertFailsWith { obj.unwantedVal } - } - assertFalse(getDeclaredField("unwantedVal").isAccessible) - assertThat("getUnwantedVal still exists", kotlin.javaDeclaredMethods, not(hasItem(getUnwantedVal))) - } - } - } - - @Test - fun deleteJvmField() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(JVM_FIELD_CLASS).apply { - val obj = getDeclaredConstructor(String::class.java).newInstance(MESSAGE) - getDeclaredField("unwantedVal").also { field -> - assertEquals(MESSAGE, field.get(obj)) - } - assertThat("unwantedVal not found", kotlin.declaredMemberProperties, hasItem(unwantedVal)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(JVM_FIELD_CLASS).apply { - assertNotNull(getDeclaredConstructor(String::class.java).newInstance(MESSAGE)) - assertFailsWith { getDeclaredField("unwantedVal") } - assertThat("unwantedVal still exists", kotlin.declaredMemberProperties, not(hasItem(unwantedVal))) - } - } - } -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteVarPropertyTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteVarPropertyTest.kt deleted file mode 100644 index 392f9466ea..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DeleteVarPropertyTest.kt +++ /dev/null @@ -1,141 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.jarfilter.matcher.* -import net.corda.gradle.unwanted.HasUnwantedVar -import org.hamcrest.core.IsCollectionContaining.* -import org.hamcrest.core.IsNot.* -import org.junit.Assert.* -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import kotlin.reflect.full.declaredMemberProperties -import kotlin.test.assertFailsWith - -class DeleteVarPropertyTest { - companion object { - private const val PROPERTY_CLASS = "net.corda.gradle.HasUnwantedVarPropertyForDelete" - private const val GETTER_CLASS = "net.corda.gradle.HasUnwantedGetForDelete" - private const val SETTER_CLASS = "net.corda.gradle.HasUnwantedSetForDelete" - private const val JVM_FIELD_CLASS = "net.corda.gradle.HasVarJvmFieldForDelete" - - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "delete-var-property") - private val unwantedVar = isProperty("unwantedVar", String::class) - private val getUnwantedVar = isMethod("getUnwantedVar", String::class.java) - private val setUnwantedVar = isMethod("setUnwantedVar", Void.TYPE, String::class.java) - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - } - - @Test - fun deleteProperty() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - getDeclaredConstructor(String::class.java).newInstance(DEFAULT_MESSAGE).also { obj -> - assertEquals(DEFAULT_MESSAGE, obj.unwantedVar) - obj.unwantedVar = MESSAGE - assertEquals(MESSAGE, obj.unwantedVar) - } - assertFalse(getDeclaredField("unwantedVar").isAccessible) - assertThat("unwantedVar not found", kotlin.declaredMemberProperties, hasItem(unwantedVar)) - assertThat("getUnwantedVar not found", kotlin.javaDeclaredMethods, hasItem(getUnwantedVar)) - assertThat("setUnwantedVar not found", kotlin.javaDeclaredMethods, hasItem(setUnwantedVar)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - getDeclaredConstructor(String::class.java).newInstance(DEFAULT_MESSAGE).also { obj -> - assertFailsWith { obj.unwantedVar } - assertFailsWith { obj.unwantedVar = MESSAGE } - } - assertFailsWith { getDeclaredField("unwantedVar") } - assertThat("unwantedVar still exists", kotlin.declaredMemberProperties, not(hasItem(unwantedVar))) - assertThat("getUnwantedVar still exists", kotlin.javaDeclaredMethods, not(hasItem(getUnwantedVar))) - assertThat("setUnwantedVar still exists", kotlin.javaDeclaredMethods, not(hasItem(setUnwantedVar))) - } - } - } - - @Test - fun deleteGetter() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(GETTER_CLASS).apply { - getDeclaredConstructor(String::class.java).newInstance(MESSAGE).also { obj -> - assertEquals(MESSAGE, obj.unwantedVar) - } - assertFalse(getDeclaredField("unwantedVar").isAccessible) - assertThat("getUnwantedVar not found", kotlin.javaDeclaredMethods, hasItem(getUnwantedVar)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(GETTER_CLASS).apply { - getDeclaredConstructor(String::class.java).newInstance(MESSAGE).also { obj -> - assertFailsWith { obj.unwantedVar } - } - assertFalse(getDeclaredField("unwantedVar").isAccessible) - assertThat("getUnwantedVar still exists", kotlin.javaDeclaredMethods, not(hasItem(getUnwantedVar))) - } - } - } - - @Test - fun deleteSetter() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(SETTER_CLASS).apply { - getConstructor(String::class.java).newInstance(DEFAULT_MESSAGE).also { obj -> - assertEquals(DEFAULT_MESSAGE, obj.unwantedVar) - obj.unwantedVar = MESSAGE - assertEquals(MESSAGE, obj.unwantedVar) - } - getDeclaredField("unwantedVar").also { field -> - assertFalse(field.isAccessible) - } - assertThat("setUnwantedVar not found", kotlin.javaDeclaredMethods, hasItem(setUnwantedVar)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(SETTER_CLASS).apply { - getConstructor(String::class.java).newInstance(DEFAULT_MESSAGE).also { obj -> - assertEquals(DEFAULT_MESSAGE, obj.unwantedVar) - assertFailsWith { obj.unwantedVar = MESSAGE } - } - getDeclaredField("unwantedVar").also { field -> - assertFalse(field.isAccessible) - } - assertThat("setUnwantedVar still exists", kotlin.javaDeclaredMethods, not(hasItem(setUnwantedVar))) - } - } - } - - @Test - fun deleteJvmField() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(JVM_FIELD_CLASS).apply { - val obj: Any = getDeclaredConstructor(String::class.java).newInstance(DEFAULT_MESSAGE) - getDeclaredField("unwantedVar").also { field -> - assertEquals(DEFAULT_MESSAGE, field.get(obj)) - field.set(obj, MESSAGE) - assertEquals(MESSAGE, field.get(obj)) - } - assertThat("unwantedVar not found", kotlin.declaredMemberProperties, hasItem(unwantedVar)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(JVM_FIELD_CLASS).apply { - assertNotNull(getDeclaredConstructor(String::class.java).newInstance(DEFAULT_MESSAGE)) - assertFailsWith { getDeclaredField("unwantedVar") } - assertThat("unwantedVar still exists", kotlin.declaredMemberProperties, not(hasItem(unwantedVar))) - } - } - } -} \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DummyJar.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DummyJar.kt deleted file mode 100644 index 7e768fc80b..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/DummyJar.kt +++ /dev/null @@ -1,103 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.jarfilter.asm.bytecode -import net.corda.gradle.jarfilter.asm.resourceName -import org.assertj.core.api.Assertions.* -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import org.junit.runner.Description -import org.junit.runners.model.Statement -import java.nio.file.Files -import java.nio.file.Path -import java.util.jar.Attributes.Name.MANIFEST_VERSION -import java.util.jar.JarOutputStream -import java.util.jar.Manifest -import java.util.zip.CRC32 -import java.util.zip.Deflater.NO_COMPRESSION -import java.util.zip.ZipEntry -import java.util.zip.ZipEntry.* - -/** - * Creates a dummy jar containing the following: - * - META-INF/MANIFEST.MF - * - A compressed class file - * - A compressed binary non-class file - * - An uncompressed text file - * - A directory entry - * - * The compression level is set to NO_COMPRESSION - * in order to force the Gradle task to compress - * the entries properly. - */ -class DummyJar( - private val projectDir: TemporaryFolder, - private val testClass: Class<*>, - private val name: String -) : TestRule { - private companion object { - private const val DATA_SIZE = 512 - - private fun uncompressed(name: String, data: ByteArray) = ZipEntry(name).apply { - method = STORED - compressedSize = data.size.toLong() - size = data.size.toLong() - crc = CRC32().let { crc -> - crc.update(data) - crc.value - } - } - - private fun compressed(name: String) = ZipEntry(name).apply { method = DEFLATED } - - private fun directoryOf(type: Class<*>) - = directory(type.`package`.name.toPathFormat + '/') - - private fun directory(name: String) = ZipEntry(name).apply { - method = STORED - compressedSize = 0 - size = 0 - crc = 0 - } - } - - private lateinit var _path: Path - val path: Path get() = _path - - override fun apply(base: Statement, description: Description): Statement { - return object : Statement() { - override fun evaluate() { - val manifest = Manifest().apply { - mainAttributes.also { main -> - main[MANIFEST_VERSION] = "1.0" - } - } - _path = projectDir.pathOf("$name.jar") - JarOutputStream(Files.newOutputStream(_path), manifest).use { jar -> - jar.setComment(testClass.name) - jar.setLevel(NO_COMPRESSION) - - // One directory entry (stored) - jar.putNextEntry(directoryOf(testClass)) - - // One compressed class file - jar.putNextEntry(compressed(testClass.resourceName)) - jar.write(testClass.bytecode) - - // One compressed non-class file - jar.putNextEntry(compressed("binary.dat")) - jar.write(arrayOfJunk(DATA_SIZE)) - - // One uncompressed text file - val text = """Jar: ${_path.toAbsolutePath()} -Class: ${testClass.name} -""".toByteArray() - jar.putNextEntry(uncompressed("comment.txt", text)) - jar.write(text) - } - assertThat(_path).isRegularFile() - - base.evaluate() - } - } - } -} \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/EmptyPackage.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/EmptyPackage.kt deleted file mode 100644 index bbb76a8036..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/EmptyPackage.kt +++ /dev/null @@ -1,8 +0,0 @@ -@file:JvmName("EmptyPackage") -@file:Suppress("UNUSED") -package net.corda.gradle.jarfilter - -/* - * We need to put something in here so that Kotlin will create a class file. - */ -const val PLACEHOLDER = 0 diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/FieldElementTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/FieldElementTest.kt deleted file mode 100644 index 0d54ecba27..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/FieldElementTest.kt +++ /dev/null @@ -1,32 +0,0 @@ -package net.corda.gradle.jarfilter - -import org.junit.Assert.* -import org.junit.Test - -class FieldElementTest { - private companion object { - private const val DESCRIPTOR = "Ljava.lang.String;" - } - - @Test - fun testFieldsMatchByNameOnly() { - val elt = FieldElement(name = "fieldName", descriptor = DESCRIPTOR) - assertEquals(FieldElement(name = "fieldName"), elt) - } - - @Test - fun testFieldWithDescriptorDoesNotExpire() { - val elt = FieldElement(name = "fieldName", descriptor = DESCRIPTOR) - assertFalse(elt.isExpired) - assertFalse(elt.isExpired) - assertFalse(elt.isExpired) - } - - @Test - fun testFieldWithoutDescriptorDoesExpire() { - val elt = FieldElement(name = "fieldName") - assertFalse(elt.isExpired) - assertTrue(elt.isExpired) - assertTrue(elt.isExpired) - } -} \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/FieldRemovalTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/FieldRemovalTest.kt deleted file mode 100644 index 9e99d4e470..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/FieldRemovalTest.kt +++ /dev/null @@ -1,212 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.jarfilter.annotations.Deletable -import net.corda.gradle.jarfilter.asm.bytecode -import net.corda.gradle.jarfilter.asm.toClass -import net.corda.gradle.jarfilter.matcher.isProperty -import org.gradle.api.logging.Logger -import org.hamcrest.core.IsCollectionContaining.hasItem -import org.hamcrest.core.IsEqual.equalTo -import org.hamcrest.core.IsNot.not -import org.junit.Assert.assertArrayEquals -import org.junit.Assert.assertThat -import org.junit.Test -import org.objectweb.asm.ClassWriter.COMPUTE_MAXS -import kotlin.reflect.full.declaredMemberProperties -import kotlin.reflect.jvm.jvmName -import kotlin.test.assertEquals -import kotlin.test.assertFailsWith -import kotlin.test.assertTrue - -/** - * Demonstrate that we can still instantiate objects, even after we've deleted - * one of their properties. (Check we haven't blown the constructor away!) - */ -class FieldRemovalTest { - companion object { - private val logger: Logger = StdOutLogging(FieldRemovalTest::class) - private const val SHORT_NUMBER = 999.toShort() - private const val BYTE_NUMBER = 99.toByte() - private const val BIG_FLOATING_POINT = 9999999.9999 - private const val FLOATING_POINT = 9999.99f - - private val objectField = isProperty(equalTo("objectField"), equalTo("T")) - private val longField = isProperty("longField", Long::class) - private val intField = isProperty("intField", Int::class) - private val shortField = isProperty("shortField", Short::class) - private val byteField = isProperty("byteField", Byte::class) - private val charField = isProperty("charField", Char::class) - private val booleanField = isProperty("booleanField", Boolean::class) - private val doubleField = isProperty("doubleField", Double::class) - private val floatField = isProperty("floatField", Float::class) - private val arrayField = isProperty("arrayField", ByteArray::class) - } - - private inline fun transform(): Class = transform(T::class.java, R::class.java) - - private fun transform(type: Class, asType: Class): Class { - val bytecode = type.bytecode.execute({ writer -> - FilterTransformer( - visitor = writer, - logger = logger, - removeAnnotations = emptySet(), - deleteAnnotations = setOf(Deletable::class.jvmName.descriptor), - stubAnnotations = emptySet(), - unwantedElements = UnwantedCache() - ) - }, COMPUTE_MAXS) - return bytecode.toClass(type, asType) - } - - @Test - fun removeObject() { - val sourceField = SampleGenericField(MESSAGE) - assertEquals(MESSAGE, sourceField.objectField) - assertThat("objectField not found", sourceField::class.declaredMemberProperties, hasItem(objectField)) - - val targetField = transform, HasGenericField>() - .getDeclaredConstructor(Any::class.java).newInstance(MESSAGE) - assertFailsWith { targetField.objectField } - assertFailsWith { targetField.objectField = "New Value" } - assertThat("objectField still exists", targetField::class.declaredMemberProperties, not(hasItem(objectField))) - } - - @Test - fun removeLong() { - val sourceField = SampleLongField(BIG_NUMBER) - assertEquals(BIG_NUMBER, sourceField.longField) - assertThat("longField not found", sourceField::class.declaredMemberProperties, hasItem(longField)) - - val targetField = transform() - .getDeclaredConstructor(Long::class.java).newInstance(BIG_NUMBER) - assertFailsWith { targetField.longField } - assertFailsWith { targetField.longField = 10L } - assertThat("longField still exists", targetField::class.declaredMemberProperties, not(hasItem(longField))) - } - - @Test - fun removeInt() { - val sourceField = SampleIntField(NUMBER) - assertEquals(NUMBER, sourceField.intField) - assertThat("intField not found", sourceField::class.declaredMemberProperties, hasItem(intField)) - - val targetField = transform() - .getDeclaredConstructor(Int::class.java).newInstance(NUMBER) - assertFailsWith { targetField.intField } - assertFailsWith { targetField.intField = 100 } - assertThat("intField still exists", targetField::class.declaredMemberProperties, not(hasItem(intField))) - } - - @Test - fun removeShort() { - val sourceField = SampleShortField(SHORT_NUMBER) - assertEquals(SHORT_NUMBER, sourceField.shortField) - assertThat("shortField not found", sourceField::class.declaredMemberProperties, hasItem(shortField)) - - val targetField = transform() - .getDeclaredConstructor(Short::class.java).newInstance(SHORT_NUMBER) - assertFailsWith { targetField.shortField } - assertFailsWith { targetField.shortField = 15 } - assertThat("shortField still exists", targetField::class.declaredMemberProperties, not(hasItem(shortField))) - } - - @Test - fun removeByte() { - val sourceField = SampleByteField(BYTE_NUMBER) - assertEquals(BYTE_NUMBER, sourceField.byteField) - assertThat("byteField not found", sourceField::class.declaredMemberProperties, hasItem(byteField)) - - val targetField = transform() - .getDeclaredConstructor(Byte::class.java).newInstance(BYTE_NUMBER) - assertFailsWith { targetField.byteField } - assertFailsWith { targetField.byteField = 16 } - assertThat("byteField still exists", targetField::class.declaredMemberProperties, not(hasItem(byteField))) - } - - @Test - fun removeBoolean() { - val sourceField = SampleBooleanField(true) - assertTrue(sourceField.booleanField) - assertThat("booleanField not found", sourceField::class.declaredMemberProperties, hasItem(booleanField)) - - val targetField = transform() - .getDeclaredConstructor(Boolean::class.java).newInstance(true) - assertFailsWith { targetField.booleanField } - assertFailsWith { targetField.booleanField = false } - assertThat("booleanField still exists", targetField::class.declaredMemberProperties, not(hasItem(booleanField))) - } - - @Test - fun removeChar() { - val sourceField = SampleCharField('?') - assertEquals('?', sourceField.charField) - assertThat("charField not found", sourceField::class.declaredMemberProperties, hasItem(charField)) - - val targetField = transform() - .getDeclaredConstructor(Char::class.java).newInstance('?') - assertFailsWith { targetField.charField } - assertFailsWith { targetField.charField = 'A' } - assertThat("charField still exists", targetField::class.declaredMemberProperties, not(hasItem(charField))) - } - - @Test - fun removeDouble() { - val sourceField = SampleDoubleField(BIG_FLOATING_POINT) - assertEquals(BIG_FLOATING_POINT, sourceField.doubleField) - assertThat("doubleField not found", sourceField::class.declaredMemberProperties, hasItem(doubleField)) - - val targetField = transform() - .getDeclaredConstructor(Double::class.java).newInstance(BIG_FLOATING_POINT) - assertFailsWith { targetField.doubleField } - assertFailsWith { targetField.doubleField = 12345.678 } - assertThat("doubleField still exists", targetField::class.declaredMemberProperties, not(hasItem(doubleField))) - } - - @Test - fun removeFloat() { - val sourceField = SampleFloatField(FLOATING_POINT) - assertEquals(FLOATING_POINT, sourceField.floatField) - assertThat("floatField not found", sourceField::class.declaredMemberProperties, hasItem(floatField)) - - val targetField = transform() - .getDeclaredConstructor(Float::class.java).newInstance(FLOATING_POINT) - assertFailsWith { targetField.floatField } - assertFailsWith { targetField.floatField = 123.45f } - assertThat("floatField still exists", targetField::class.declaredMemberProperties, not(hasItem(floatField))) - } - - @Test - fun removeArray() { - val sourceField = SampleArrayField(byteArrayOf()) - assertArrayEquals(byteArrayOf(), sourceField.arrayField) - assertThat("arrayField not found", sourceField::class.declaredMemberProperties, hasItem(arrayField)) - - val targetField = transform() - .getDeclaredConstructor(ByteArray::class.java).newInstance(byteArrayOf()) - assertFailsWith { targetField.arrayField } - assertFailsWith { targetField.arrayField = byteArrayOf(0x35, 0x73) } - assertThat("arrayField still exists", targetField::class.declaredMemberProperties, not(hasItem(arrayField))) - } -} - -interface HasGenericField { var objectField: T } -interface HasLongField { var longField: Long } -interface HasIntField { var intField: Int } -interface HasShortField { var shortField: Short } -interface HasByteField { var byteField: Byte } -interface HasBooleanField { var booleanField: Boolean } -interface HasCharField { var charField: Char } -interface HasFloatField { var floatField: Float } -interface HasDoubleField { var doubleField: Double } -interface HasArrayField { var arrayField: ByteArray } - -internal class SampleGenericField(@Deletable override var objectField: T) : HasGenericField -internal class SampleLongField(@Deletable override var longField: Long) : HasLongField -internal class SampleIntField(@Deletable override var intField: Int) : HasIntField -internal class SampleShortField(@Deletable override var shortField: Short) : HasShortField -internal class SampleByteField(@Deletable override var byteField: Byte) : HasByteField -internal class SampleBooleanField(@Deletable override var booleanField: Boolean) : HasBooleanField -internal class SampleCharField(@Deletable override var charField: Char) : HasCharField -internal class SampleFloatField(@Deletable override var floatField: Float) : HasFloatField -internal class SampleDoubleField(@Deletable override var doubleField: Double) : HasDoubleField -internal class SampleArrayField(@Deletable override var arrayField: ByteArray) : HasArrayField diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/InterfaceFunctionTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/InterfaceFunctionTest.kt deleted file mode 100644 index 452f26d140..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/InterfaceFunctionTest.kt +++ /dev/null @@ -1,61 +0,0 @@ -package net.corda.gradle.jarfilter - -import org.junit.Assert.* -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import java.lang.reflect.Modifier.* -import kotlin.test.assertFailsWith - -class InterfaceFunctionTest { - companion object { - private const val FUNCTION_CLASS = "net.corda.gradle.InterfaceFunctions" - - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "interface-function") - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - } - - @Test - fun deleteInterfaceFunction() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(FUNCTION_CLASS).apply { - getMethod("toDelete", Long::class.java).also { method -> - assertEquals(ABSTRACT, method.modifiers and ABSTRACT) - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(FUNCTION_CLASS).apply { - assertFailsWith { getMethod("toDelete", Long::class.java) } - } - } - } - - @Test - fun cannotStubInterfaceFunction() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(FUNCTION_CLASS).apply { - getMethod("toStubOut", Long::class.java).also { method -> - assertEquals(ABSTRACT, method.modifiers and ABSTRACT) - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(FUNCTION_CLASS).apply { - getMethod("toStubOut", Long::class.java).also { method -> - assertEquals(ABSTRACT, method.modifiers and ABSTRACT) - } - } - } - } -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/JarFilterConfigurationTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/JarFilterConfigurationTest.kt deleted file mode 100644 index 1e52fd4198..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/JarFilterConfigurationTest.kt +++ /dev/null @@ -1,272 +0,0 @@ -package net.corda.gradle.jarfilter - -import org.assertj.core.api.Assertions.* -import org.gradle.testkit.runner.BuildResult -import org.gradle.testkit.runner.BuildTask -import org.gradle.testkit.runner.GradleRunner -import org.gradle.testkit.runner.TaskOutcome.* -import org.junit.Assert.* -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.rules.TemporaryFolder - -class JarFilterConfigurationTest { - private companion object { - private const val AMBIGUOUS = "net.corda.gradle.jarfilter.Ambiguous" - private const val DELETE = "net.corda.gradle.jarfilter.DeleteMe" - private const val REMOVE = "net.corda.gradle.jarfilter.RemoveMe" - private const val STUB = "net.corda.gradle.jarfilter.StubMeOut" - } - - @Rule - @JvmField - val testProjectDir = TemporaryFolder() - - private lateinit var output: String - - @Before - fun setup() { - testProjectDir.installResource("gradle.properties") - } - - @Test - fun checkNoJarMeansNoSource() { - val result = gradleProject(""" -plugins { - id 'java' - id 'net.corda.plugins.jar-filter' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - annotations { - forDelete = ["$DELETE"] - } -} -""").build() - output = result.output - println(output) - - val jarFilter = result.forTask("jarFilter") - assertEquals(NO_SOURCE, jarFilter.outcome) - } - - @Test - fun checkWithMissingJar() { - val result = gradleProject(""" -plugins { - id 'net.corda.plugins.jar-filter' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars = file('does-not-exist.jar') -} -""").buildAndFail() - output = result.output - println(output) - - assertThat(output).containsSubsequence( - "Caused by: org.gradle.api.GradleException:", - "Caused by: java.io.FileNotFoundException:" - ) - - val jarFilter = result.forTask("jarFilter") - assertEquals(FAILED, jarFilter.outcome) - } - - @Test - fun checkSameAnnotationForRemoveAndDelete() { - val result = gradleProject(""" -plugins { - id 'java' - id 'net.corda.plugins.jar-filter' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars = jar - annotations { - forDelete = ["$AMBIGUOUS"] - forRemove = ["$AMBIGUOUS"] - } -} -""").buildAndFail() - output = result.output - println(output) - - assertThat(output).containsSequence( - "Caused by: org.gradle.api.InvalidUserDataException: Annotation 'net.corda.gradle.jarfilter.Ambiguous' also appears in JarFilter 'forDelete' section" - ) - - val jarFilter = result.forTask("jarFilter") - assertEquals(FAILED, jarFilter.outcome) - } - - @Test - fun checkSameAnnotationForRemoveAndStub() { - val result = gradleProject(""" -plugins { - id 'java' - id 'net.corda.plugins.jar-filter' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars = jar - annotations { - forStub = ["$AMBIGUOUS"] - forRemove = ["$AMBIGUOUS"] - } -} -""").buildAndFail() - output = result.output - println(output) - - assertThat(output).containsSequence( - "Caused by: org.gradle.api.InvalidUserDataException: Annotation 'net.corda.gradle.jarfilter.Ambiguous' also appears in JarFilter 'forStub' section" - ) - - val jarFilter = result.forTask("jarFilter") - assertEquals(FAILED, jarFilter.outcome) - } - - @Test - fun checkSameAnnotationForStubAndDelete() { - val result = gradleProject(""" -plugins { - id 'java' - id 'net.corda.plugins.jar-filter' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars = jar - annotations { - forStub = ["$AMBIGUOUS"] - forDelete = ["$AMBIGUOUS"] - } -} -""").buildAndFail() - output = result.output - println(output) - - assertThat(output).containsSequence( - "Caused by: org.gradle.api.InvalidUserDataException: Annotation 'net.corda.gradle.jarfilter.Ambiguous' also appears in JarFilter 'forStub' section" - ) - - val jarFilter = result.forTask("jarFilter") - assertEquals(FAILED, jarFilter.outcome) - } - - @Test - fun checkSameAnnotationForStubAndDeleteAndRemove() { - val result = gradleProject(""" -plugins { - id 'java' - id 'net.corda.plugins.jar-filter' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars = jar - annotations { - forStub = ["$AMBIGUOUS"] - forDelete = ["$AMBIGUOUS"] - forRemove = ["$AMBIGUOUS"] - } -} -""").buildAndFail() - output = result.output - println(output) - - assertThat(output).containsSequence( - "Caused by: org.gradle.api.InvalidUserDataException: Annotation 'net.corda.gradle.jarfilter.Ambiguous' also appears in JarFilter 'forDelete' section" - ) - - val jarFilter = result.forTask("jarFilter") - assertEquals(FAILED, jarFilter.outcome) - } - - @Test - fun checkRepeatedAnnotationForDelete() { - val result = gradleProject(""" -plugins { - id 'java' - id 'net.corda.plugins.jar-filter' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars = jar - annotations { - forDelete = ["$DELETE", "$DELETE"] - } -} -""").build() - output = result.output - println(output) - - val jarFilter = result.forTask("jarFilter") - assertEquals(SUCCESS, jarFilter.outcome) - } - - @Test - fun checkRepeatedAnnotationForStub() { - val result = gradleProject(""" -plugins { - id 'java' - id 'net.corda.plugins.jar-filter' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars = jar - annotations { - forStub = ["$STUB", "$STUB"] - } -} -""").build() - output = result.output - println(output) - - val jarFilter = result.forTask("jarFilter") - assertEquals(SUCCESS, jarFilter.outcome) - } - - @Test - fun checkRepeatedAnnotationForRemove() { - val result = gradleProject(""" -plugins { - id 'java' - id 'net.corda.plugins.jar-filter' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars = jar - annotations { - forRemove = ["$REMOVE", "$REMOVE"] - } -} -""").build() - output = result.output - println(output) - - val jarFilter = result.forTask("jarFilter") - assertEquals(SUCCESS, jarFilter.outcome) - } - - private fun gradleProject(script: String): GradleRunner { - testProjectDir.newFile("build.gradle").writeText(script) - return GradleRunner.create() - .withProjectDir(testProjectDir.root) - .withArguments(getBasicArgsForTasks("jarFilter")) - .withPluginClasspath() - } - - private fun BuildResult.forTask(name: String): BuildTask { - return task(":$name") ?: throw AssertionError("No outcome for $name task") - } -} \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/JarFilterProject.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/JarFilterProject.kt deleted file mode 100644 index 1a2e3cb128..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/JarFilterProject.kt +++ /dev/null @@ -1,56 +0,0 @@ -package net.corda.gradle.jarfilter - -import org.assertj.core.api.Assertions.* -import org.gradle.testkit.runner.GradleRunner -import org.gradle.testkit.runner.TaskOutcome.* -import org.junit.Assert.* -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import org.junit.runner.Description -import org.junit.runners.model.Statement -import java.io.FileNotFoundException -import java.nio.file.Path - -class JarFilterProject(private val projectDir: TemporaryFolder, private val name: String) : TestRule { - private var _sourceJar: Path? = null - val sourceJar: Path get() = _sourceJar ?: throw FileNotFoundException("Input not found") - - private var _filteredJar: Path? = null - val filteredJar: Path get() = _filteredJar ?: throw FileNotFoundException("Output not found") - - private var _output: String = "" - val output: String get() = _output - - override fun apply(statement: Statement, description: Description): Statement { - return object : Statement() { - override fun evaluate() { - projectDir.installResources( - "$name/build.gradle", - "repositories.gradle", - "gradle.properties", - "settings.gradle" - ) - - val result = GradleRunner.create() - .withProjectDir(projectDir.root) - .withArguments(getGradleArgsForTasks("jarFilter")) - .withPluginClasspath() - .build() - _output = result.output - println(output) - - val jarFilter = result.task(":jarFilter") - ?: throw AssertionError("No outcome for jarFilter task") - assertEquals(SUCCESS, jarFilter.outcome) - - _sourceJar = projectDir.pathOf("build", "libs", "$name.jar") - assertThat(sourceJar).isRegularFile() - - _filteredJar = projectDir.pathOf("build", "filtered-libs", "$name-filtered.jar") - assertThat(filteredJar).isRegularFile() - - statement.evaluate() - } - } - } -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/JarFilterTimestampTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/JarFilterTimestampTest.kt deleted file mode 100644 index d57aca4b65..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/JarFilterTimestampTest.kt +++ /dev/null @@ -1,107 +0,0 @@ -package net.corda.gradle.jarfilter - -import org.assertj.core.api.Assertions.* -import org.gradle.testkit.runner.GradleRunner -import org.gradle.testkit.runner.TaskOutcome.* -import org.junit.Assert.* -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import org.junit.runners.model.Statement -import java.nio.file.Path -import java.nio.file.attribute.FileTime -import java.util.* -import java.util.Calendar.FEBRUARY -import java.util.zip.ZipEntry -import java.util.zip.ZipFile - -class JarFilterTimestampTest { - companion object { - private val testProjectDir = TemporaryFolder() - private val sourceJar = DummyJar(testProjectDir, JarFilterTimestampTest::class.java, "timestamps") - - private val CONSTANT_TIME: FileTime = FileTime.fromMillis( - GregorianCalendar(1980, FEBRUARY, 1).apply { - timeZone = TimeZone.getTimeZone("UTC") - }.timeInMillis - ) - - private lateinit var filteredJar: Path - private lateinit var output: String - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(sourceJar) - .around(createTestProject()) - - private fun createTestProject() = TestRule { base, _ -> - object : Statement() { - override fun evaluate() { - testProjectDir.installResource("gradle.properties") - testProjectDir.newFile("build.gradle").writeText(""" -plugins { - id 'net.corda.plugins.jar-filter' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars file("${sourceJar.path.toUri()}") - preserveTimestamps = false -} -""") - val result = GradleRunner.create() - .withProjectDir(testProjectDir.root) - .withArguments(getGradleArgsForTasks("jarFilter")) - .withPluginClasspath() - .build() - output = result.output - println(output) - - val metafix = result.task(":jarFilter") - ?: throw AssertionError("No outcome for jarFilter task") - assertEquals(SUCCESS, metafix.outcome) - - filteredJar = testProjectDir.pathOf("build", "filtered-libs", "timestamps-filtered.jar") - assertThat(filteredJar).isRegularFile() - - base.evaluate() - } - } - } - - private val ZipEntry.methodName: String get() = if (method == ZipEntry.STORED) "Stored" else "Deflated" - } - - @Test - fun fileTimestampsAreRemoved() { - var directoryCount = 0 - var classCount = 0 - var otherCount = 0 - - ZipFile(filteredJar.toFile()).use { jar -> - for (entry in jar.entries()) { - println("Entry: ${entry.name}") - println("- ${entry.methodName} (${entry.size} size / ${entry.compressedSize} compressed) bytes") - assertThat(entry.lastModifiedTime).isEqualTo(CONSTANT_TIME) - assertThat(entry.lastAccessTime).isNull() - assertThat(entry.creationTime).isNull() - - if (entry.isDirectory) { - ++directoryCount - } else if (entry.name.endsWith(".class")) { - ++classCount - } else { - ++otherCount - } - } - } - - assertThat(directoryCount).isGreaterThan(0) - assertThat(classCount).isGreaterThan(0) - assertThat(otherCount).isGreaterThan(0) - } -} \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixAnnotationTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixAnnotationTest.kt deleted file mode 100644 index 1fdcc44e7e..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixAnnotationTest.kt +++ /dev/null @@ -1,47 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.jarfilter.asm.bytecode -import net.corda.gradle.jarfilter.asm.toClass -import net.corda.gradle.jarfilter.matcher.isConstructor -import org.gradle.api.logging.Logger -import org.hamcrest.core.IsCollectionContaining.* -import org.junit.Assert.* -import org.junit.Test - -class MetaFixAnnotationTest { - companion object { - private val logger: Logger = StdOutLogging(MetaFixAnnotationTest::class) - private val defaultCon = isConstructor( - returnType = SimpleAnnotation::class - ) - private val valueCon = isConstructor( - returnType = AnnotationWithValue::class, - parameters = *arrayOf(String::class) - ) - } - - @Test - fun testSimpleAnnotation() { - val sourceClass = SimpleAnnotation::class.java - assertThat("() not found", sourceClass.kotlin.constructors, hasItem(defaultCon)) - - // Rewrite the metadata according to the contents of the bytecode. - val fixedClass = sourceClass.bytecode.fixMetadata(logger, pathsOf(SimpleAnnotation::class)) - .toClass() - assertThat("() not found", fixedClass.kotlin.constructors, hasItem(defaultCon)) - } - - @Test - fun testAnnotationWithValue() { - val sourceClass = AnnotationWithValue::class.java - assertThat("(String) not found", sourceClass.kotlin.constructors, hasItem(valueCon)) - - // Rewrite the metadata according to the contents of the bytecode. - val fixedClass = sourceClass.bytecode.fixMetadata(logger, pathsOf(AnnotationWithValue::class)) - .toClass() - assertThat("(String) not found", fixedClass.kotlin.constructors, hasItem(valueCon)) - } -} - -annotation class AnnotationWithValue(val str: String) -annotation class SimpleAnnotation diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixConfigurationTests.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixConfigurationTests.kt deleted file mode 100644 index 84944f6a3f..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixConfigurationTests.kt +++ /dev/null @@ -1,79 +0,0 @@ -package net.corda.gradle.jarfilter - -import org.assertj.core.api.Assertions.* -import org.gradle.testkit.runner.BuildResult -import org.gradle.testkit.runner.BuildTask -import org.gradle.testkit.runner.GradleRunner -import org.gradle.testkit.runner.TaskOutcome.* -import org.junit.Assert.* -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.rules.TemporaryFolder - -class MetaFixConfigurationTests { - @Rule - @JvmField - val testProjectDir = TemporaryFolder() - - private lateinit var output: String - - @Before - fun setup() { - testProjectDir.installResource("gradle.properties") - } - - @Test - fun checkNoJarMeansNoSource() { - val result = gradleProject(""" -plugins { - id 'java' - id 'net.corda.plugins.jar-filter' -} - -import net.corda.gradle.jarfilter.MetaFixerTask -task metafix(type: MetaFixerTask) -""").build() - output = result.output - println(output) - - val metafix = result.forTask("metafix") - assertEquals(NO_SOURCE, metafix.outcome) - } - - @Test - fun checkWithMissingJar() { - val result = gradleProject(""" -plugins { - id 'net.corda.plugins.jar-filter' -} - -import net.corda.gradle.jarfilter.MetaFixerTask -task metafix(type: MetaFixerTask) { - jars = file('does-not-exist.jar') -} -""").buildAndFail() - output = result.output - println(output) - - assertThat(output).containsSubsequence( - "Caused by: org.gradle.api.GradleException:", - "Caused by: java.io.FileNotFoundException:" - ) - - val metafix = result.forTask("metafix") - assertEquals(FAILED, metafix.outcome) - } - - private fun gradleProject(script: String): GradleRunner { - testProjectDir.newFile("build.gradle").writeText(script) - return GradleRunner.create() - .withProjectDir(testProjectDir.root) - .withArguments(getBasicArgsForTasks("metafix")) - .withPluginClasspath() - } - - private fun BuildResult.forTask(name: String): BuildTask { - return task(":$name") ?: throw AssertionError("No outcome for $name task") - } -} \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixConstructorDefaultParameterTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixConstructorDefaultParameterTest.kt deleted file mode 100644 index df36c6e08c..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixConstructorDefaultParameterTest.kt +++ /dev/null @@ -1,110 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.jarfilter.asm.recodeMetadataFor -import net.corda.gradle.jarfilter.asm.toClass -import net.corda.gradle.jarfilter.matcher.isConstructor -import net.corda.gradle.unwanted.HasAll -import org.assertj.core.api.Assertions.* -import org.gradle.api.logging.Logger -import org.hamcrest.core.IsCollectionContaining.* -import org.junit.Assert.* -import org.junit.BeforeClass -import org.junit.Test -import kotlin.reflect.full.primaryConstructor - -class MetaFixConstructorDefaultParameterTest { - companion object { - private val logger: Logger = StdOutLogging(MetaFixConstructorDefaultParameterTest::class) - private val primaryCon - = isConstructor(WithConstructorParameters::class, Long::class, Int::class, String::class) - private val secondaryCon - = isConstructor(WithConstructorParameters::class, Char::class, String::class) - - lateinit var sourceClass: Class - lateinit var fixedClass: Class - - @BeforeClass - @JvmStatic - fun setup() { - val bytecode = recodeMetadataFor() - sourceClass = bytecode.toClass() - fixedClass = bytecode.fixMetadata(logger, pathsOf(WithConstructorParameters::class)) - .toClass() - } - } - - @Test - fun `test source constructor has optional parameters`() { - with(sourceClass.kotlin.constructors) { - assertThat(size).isEqualTo(2) - assertThat("source primary constructor missing", this, hasItem(primaryCon)) - assertThat("source secondary constructor missing", this, hasItem(secondaryCon)) - } - - val sourcePrimary = sourceClass.kotlin.primaryConstructor - ?: throw AssertionError("source primary constructor missing") - sourcePrimary.call(BIG_NUMBER, NUMBER, MESSAGE).apply { - assertThat(longData()).isEqualTo(BIG_NUMBER) - assertThat(intData()).isEqualTo(NUMBER) - assertThat(stringData()).isEqualTo(MESSAGE) - } - - val sourceSecondary = sourceClass.kotlin.constructors.firstOrNull { it != sourcePrimary } - ?: throw AssertionError("source secondary constructor missing") - sourceSecondary.call('X', MESSAGE).apply { - assertThat(stringData()).isEqualTo("X$MESSAGE") - } - - assertTrue("All source parameters should have defaults", sourcePrimary.hasAllOptionalParameters) - } - - @Test - fun `test fixed constructors exist`() { - with(fixedClass.kotlin.constructors) { - assertThat(size).isEqualTo(2) - assertThat("fixed primary constructor missing", this, hasItem(primaryCon)) - assertThat("fixed secondary constructor missing", this, hasItem(secondaryCon)) - } - } - - @Test - fun `test fixed primary constructor has mandatory parameters`() { - val fixedPrimary = fixedClass.kotlin.primaryConstructor - ?: throw AssertionError("fixed primary constructor missing") - assertTrue("All fixed parameters should be mandatory", fixedPrimary.hasAllMandatoryParameters) - } - - @Test - fun `test fixed secondary constructor still has optional parameters`() { - val fixedSecondary = (fixedClass.kotlin.constructors - fixedClass.kotlin.primaryConstructor).firstOrNull() - ?: throw AssertionError("fixed secondary constructor missing") - assertTrue("Some fixed parameters should be optional", fixedSecondary.hasAnyOptionalParameters) - } - - class MetadataTemplate( - private val longData: Long = 0, - private val intData: Int = 0, - private val message: String = DEFAULT_MESSAGE - ) : HasAll { - @Suppress("UNUSED") - constructor(prefix: Char, message: String = DEFAULT_MESSAGE) : this(message = prefix + message) - - override fun longData(): Long = longData - override fun intData(): Int = intData - override fun stringData(): String = message - } -} - -class WithConstructorParameters( - private val longData: Long, - private val intData: Int, - private val message: String -) : HasAll { - @Suppress("UNUSED") - constructor(prefix: Char, message: String = DEFAULT_MESSAGE) : this(0, 0, prefix + message) - - override fun longData(): Long = longData - override fun intData(): Int = intData - override fun stringData(): String = message -} - diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixConstructorTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixConstructorTest.kt deleted file mode 100644 index 35630a82a3..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixConstructorTest.kt +++ /dev/null @@ -1,53 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.unwanted.* -import net.corda.gradle.jarfilter.asm.* -import net.corda.gradle.jarfilter.matcher.* -import org.gradle.api.logging.Logger -import org.hamcrest.core.IsCollectionContaining.hasItem -import org.hamcrest.core.IsNot.not -import org.junit.Assert.* -import org.junit.Test -import kotlin.jvm.kotlin - -class MetaFixConstructorTest { - companion object { - private val logger: Logger = StdOutLogging(MetaFixConstructorTest::class) - private val unwantedCon = isConstructor(WithConstructor::class, Int::class, Long::class) - private val wantedCon = isConstructor(WithConstructor::class, Long::class) - } - - @Test - fun testConstructorRemovedFromMetadata() { - val bytecode = recodeMetadataFor() - val sourceClass = bytecode.toClass() - - // Check that the unwanted constructor has been successfully - // added to the metadata, and that the class is valid. - val sourceObj = sourceClass.getDeclaredConstructor(Long::class.java).newInstance(BIG_NUMBER) - assertEquals(BIG_NUMBER, sourceObj.longData()) - with(sourceClass.kotlin.constructors) { - assertThat("(Int,Long) not found", this, hasItem(unwantedCon)) - assertThat("(Long) not found", this, hasItem(wantedCon)) - } - - // Rewrite the metadata according to the contents of the bytecode. - val fixedClass = bytecode.fixMetadata(logger, pathsOf(WithConstructor::class)).toClass() - val fixedObj = fixedClass.getDeclaredConstructor(Long::class.java).newInstance(BIG_NUMBER) - assertEquals(BIG_NUMBER, fixedObj.longData()) - with(fixedClass.kotlin.constructors) { - assertThat("(Int,Long) still exists", this, not(hasItem(unwantedCon))) - assertThat("(Long) not found", this, hasItem(wantedCon)) - } - } - - class MetadataTemplate(private val longData: Long) : HasLong { - @Suppress("UNUSED_PARAMETER", "UNUSED") - constructor(intData: Int, longData: Long) : this(longData) - override fun longData(): Long = longData - } -} - -class WithConstructor(private val longData: Long) : HasLong { - override fun longData(): Long = longData -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixFunctionDefaultParameterTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixFunctionDefaultParameterTest.kt deleted file mode 100644 index 65ed6a300f..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixFunctionDefaultParameterTest.kt +++ /dev/null @@ -1,96 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.jarfilter.asm.recodeMetadataFor -import net.corda.gradle.jarfilter.asm.toClass -import net.corda.gradle.jarfilter.matcher.isFunction -import org.assertj.core.api.Assertions.* -import org.gradle.api.logging.Logger -import org.hamcrest.core.IsCollectionContaining.* -import org.junit.Assert.* -import org.junit.BeforeClass -import org.junit.Test -import kotlin.reflect.KFunction -import kotlin.reflect.full.declaredFunctions - -class MetaFixFunctionDefaultParameterTest { - companion object { - private val logger: Logger = StdOutLogging(MetaFixFunctionDefaultParameterTest::class) - private val hasMandatoryParams - = isFunction("hasMandatoryParams", String::class, Long::class, Int::class, String::class) - private val hasOptionalParams - = isFunction("hasOptionalParams", String::class, String::class) - - lateinit var sourceClass: Class - lateinit var fixedClass: Class - - @BeforeClass - @JvmStatic - fun setup() { - val bytecode = recodeMetadataFor() - sourceClass = bytecode.toClass() - fixedClass = bytecode.fixMetadata(logger, pathsOf(WithFunctionParameters::class)) - .toClass() - } - } - - @Test - fun `test source functions have default parameters`() { - with(sourceClass.kotlin.declaredFunctions) { - assertThat(size).isEqualTo(2) - assertThat("source mandatory parameters missing", this, hasItem(hasMandatoryParams)) - assertThat("source optional parameters missing", this, hasItem(hasOptionalParams)) - } - - val sourceUnwanted = sourceClass.kotlin.declaredFunctions.findOrFail("hasMandatoryParams") - assertThat(sourceUnwanted.call(sourceClass.newInstance(), BIG_NUMBER, NUMBER, MESSAGE)) - .isEqualTo("Long: $BIG_NUMBER, Int: $NUMBER, String: $MESSAGE") - - assertTrue("All source parameters should be optional", sourceUnwanted.hasAllOptionalParameters) - - val sourceWanted = sourceClass.kotlin.declaredFunctions.findOrFail("hasOptionalParams") - assertThat(sourceWanted.call(sourceClass.newInstance(), MESSAGE)) - .isEqualTo(MESSAGE) - - assertTrue("All source parameters should be optional", sourceWanted.hasAllOptionalParameters) - } - - @Test - fun `test fixed functions exist`() { - with(fixedClass.kotlin.declaredFunctions) { - assertThat(size).isEqualTo(2) - assertThat("fixed mandatory parameters missing", this, hasItem(hasMandatoryParams)) - assertThat("fixed optional parameters missing", this, hasItem(hasOptionalParams)) - } - } - - @Test - fun `test unwanted default parameters are removed`() { - val fixedMandatory = fixedClass.kotlin.declaredFunctions.findOrFail("hasMandatoryParams") - assertTrue("All fixed parameters should be mandatory", fixedMandatory.hasAllMandatoryParameters) - } - - @Test - fun `test wanted default parameters are kept`() { - val fixedOptional = fixedClass.kotlin.declaredFunctions.findOrFail("hasOptionalParams") - assertTrue("All fixed parameters should be optional", fixedOptional.hasAllOptionalParameters) - } - - @Suppress("UNUSED") - abstract class MetadataTemplate { - abstract fun hasMandatoryParams(longData: Long = 0, intData: Int = 0, message: String = DEFAULT_MESSAGE): String - abstract fun hasOptionalParams(message: String = DEFAULT_MESSAGE): String - } - - private fun Iterable>.findOrFail(name: String): KFunction { - return find { it.name == name } ?: throw AssertionError("$name missing") - } -} - -@Suppress("UNUSED") -class WithFunctionParameters { - fun hasMandatoryParams(longData: Long, intData: Int, message: String): String { - return "Long: $longData, Int: $intData, String: $message" - } - - fun hasOptionalParams(message: String = DEFAULT_MESSAGE): String = message -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixFunctionTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixFunctionTest.kt deleted file mode 100644 index 1aad6b1929..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixFunctionTest.kt +++ /dev/null @@ -1,53 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.unwanted.* -import net.corda.gradle.jarfilter.asm.* -import net.corda.gradle.jarfilter.matcher.* -import org.gradle.api.logging.Logger -import org.hamcrest.core.IsCollectionContaining.hasItem -import org.hamcrest.core.IsNot.not -import org.junit.Assert.* -import org.junit.Test -import kotlin.jvm.kotlin -import kotlin.reflect.full.declaredFunctions - -class MetaFixFunctionTest { - companion object { - private val logger: Logger = StdOutLogging(MetaFixFunctionTest::class) - private val longData = isFunction("longData", Long::class) - private val unwantedFun = isFunction("unwantedFun", String::class, String::class) - } - - @Test - fun testFunctionRemovedFromMetadata() { - val bytecode = recodeMetadataFor() - val sourceClass = bytecode.toClass() - - // Check that the unwanted function has been successfully - // added to the metadata, and that the class is valid. - val sourceObj = sourceClass.newInstance() - assertEquals(BIG_NUMBER, sourceObj.longData()) - with(sourceClass.kotlin.declaredFunctions) { - assertThat("unwantedFun(String) not found", this, hasItem(unwantedFun)) - assertThat("longData not found", this, hasItem(longData)) - } - - // Rewrite the metadata according to the contents of the bytecode. - val fixedClass = bytecode.fixMetadata(logger, pathsOf(WithFunction::class)).toClass() - val fixedObj = fixedClass.newInstance() - assertEquals(BIG_NUMBER, fixedObj.longData()) - with(fixedClass.kotlin.declaredFunctions) { - assertThat("unwantedFun(String) still exists", this, not(hasItem(unwantedFun))) - assertThat("longData not found", this, hasItem(longData)) - } - } - - class MetadataTemplate : HasLong { - override fun longData(): Long = 0 - @Suppress("UNUSED") fun unwantedFun(str: String): String = "UNWANTED[$str]" - } -} - -class WithFunction : HasLong { - override fun longData(): Long = BIG_NUMBER -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixNestedClassTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixNestedClassTest.kt deleted file mode 100644 index d460e9c453..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixNestedClassTest.kt +++ /dev/null @@ -1,57 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.jarfilter.asm.* -import org.assertj.core.api.Assertions.* -import org.gradle.api.logging.Logger -import org.junit.Test -import kotlin.reflect.jvm.jvmName - -/** - * Kotlin reflection will attempt to validate the nested classes stored in the [kotlin.Metadata] - * annotation rather than just reporting what is there, which means that it can tell us nothing - * about what the MetaFixer task has done. - */ -class MetaFixNestedClassTest { - companion object { - private val logger: Logger = StdOutLogging(MetaFixNestedClassTest::class) - private val WANTED_CLASS: String = WithNestedClass.Wanted::class.jvmName - private val UNWANTED_CLASS: String = "${WithNestedClass::class.jvmName}\$Unwanted" - } - - @Test - fun testNestedClassRemovedFromMetadata() { - val bytecode = recodeMetadataFor() - val sourceClass = bytecode.toClass() - assertThat(sourceClass.classMetadata.nestedClasses).containsExactlyInAnyOrder(WANTED_CLASS, UNWANTED_CLASS) - - // Rewrite the metadata according to the contents of the bytecode. - val fixedClass = bytecode.fixMetadata(logger, pathsOf(WithNestedClass::class, WithNestedClass.Wanted::class)) - .toClass() - assertThat(fixedClass.classMetadata.nestedClasses).containsExactly(WANTED_CLASS) - } - - @Test - fun testAllNestedClassesRemovedFromMetadata() { - val bytecode = recodeMetadataFor() - val sourceClass = bytecode.toClass() - assertThat(sourceClass.classMetadata.nestedClasses) - .containsExactlyInAnyOrder("${WithoutNestedClass::class.jvmName}\$Wanted", "${WithoutNestedClass::class.jvmName}\$Unwanted") - - // Rewrite the metadata according to the contents of the bytecode. - val fixedClass = bytecode.fixMetadata(logger, pathsOf(WithoutNestedClass::class)) - .toClass() - assertThat(fixedClass.classMetadata.nestedClasses).isEmpty() - } - - @Suppress("UNUSED") - class MetadataTemplate { - class Wanted - class Unwanted - } -} - -class WithNestedClass { - class Wanted -} - -class WithoutNestedClass \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixPackageDefaultParameterTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixPackageDefaultParameterTest.kt deleted file mode 100644 index 74bb986fac..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixPackageDefaultParameterTest.kt +++ /dev/null @@ -1,39 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.jarfilter.asm.metadataAs -import net.corda.gradle.jarfilter.asm.toClass -import org.gradle.api.logging.Logger -import org.junit.BeforeClass -import org.junit.Test -import kotlin.reflect.full.declaredFunctions -import kotlin.test.assertFailsWith - -/** - * These tests cannot actually "test" anything until Kotlin reflection - * supports package metadata. Until then, we can only execute the code - * paths to ensure they don't throw any exceptions. - */ -class MetaFixPackageDefaultParameterTest { - companion object { - private const val TEMPLATE_CLASS = "net.corda.gradle.jarfilter.template.PackageWithDefaultParameters" - private const val DEFAULT_PARAMETERS_CLASS = "net.corda.gradle.jarfilter.PackageWithDefaultParameters" - private val logger: Logger = StdOutLogging(MetaFixPackageDefaultParameterTest::class) - - lateinit var sourceClass: Class - lateinit var fixedClass: Class - - @BeforeClass - @JvmStatic - fun setup() { - val defaultParametersClass = Class.forName(DEFAULT_PARAMETERS_CLASS) - val bytecode = defaultParametersClass.metadataAs(Class.forName(TEMPLATE_CLASS)) - sourceClass = bytecode.toClass(defaultParametersClass, Any::class.java) - fixedClass = bytecode.fixMetadata(logger, setOf(DEFAULT_PARAMETERS_CLASS)).toClass(sourceClass, Any::class.java) - } - } - - @Test - fun `test package functions`() { - assertFailsWith { fixedClass.kotlin.declaredFunctions } - } -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixPackageTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixPackageTest.kt deleted file mode 100644 index 37948f219b..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixPackageTest.kt +++ /dev/null @@ -1,66 +0,0 @@ -@file:JvmName("PackageTemplate") -@file:Suppress("UNUSED") -package net.corda.gradle.jarfilter - -import net.corda.gradle.jarfilter.asm.* -import net.corda.gradle.jarfilter.matcher.* -import org.gradle.api.logging.Logger -import org.junit.BeforeClass -import org.junit.Test -import kotlin.jvm.kotlin -import kotlin.reflect.full.declaredFunctions -import kotlin.reflect.full.declaredMembers -import kotlin.test.assertFailsWith - -/** - * These tests cannot actually "test" anything until Kotlin reflection - * supports package metadata. Until then, we can only execute the code - * paths to ensure they don't throw any exceptions. - */ -class MetaFixPackageTest { - companion object { - private const val TEMPLATE_CLASS = "net.corda.gradle.jarfilter.PackageTemplate" - private const val EMPTY_CLASS = "net.corda.gradle.jarfilter.EmptyPackage" - private val logger: Logger = StdOutLogging(MetaFixPackageTest::class) - private val staticVal = isProperty("templateVal", Long::class) - private val staticVar = isProperty("templateVar", Int::class) - private val staticFun = isFunction("templateFun", String::class) - - private lateinit var sourceClass: Class - private lateinit var fixedClass: Class - - @BeforeClass - @JvmStatic - fun setup() { - val emptyClass = Class.forName(EMPTY_CLASS) - val bytecode = emptyClass.metadataAs(Class.forName(TEMPLATE_CLASS)) - sourceClass = bytecode.toClass(emptyClass, Any::class.java) - fixedClass = bytecode.fixMetadata(logger, setOf(EMPTY_CLASS)).toClass(sourceClass, Any::class.java) - } - } - - @Test - fun testPackageFunction() { - assertFailsWith { fixedClass.kotlin.declaredFunctions } - //assertThat("templateFun() not found", sourceClass.kotlin.declaredFunctions, hasItem(staticFun)) - //assertThat("templateFun() still exists", fixedClass.kotlin.declaredFunctions, not(hasItem(staticFun))) - } - - @Test - fun testPackageVal() { - assertFailsWith { fixedClass.kotlin.declaredMembers } - //assertThat("templateVal not found", sourceClass.kotlin.declaredMembers, hasItem(staticVal)) - //assertThat("templateVal still exists", fixedClass.kotlin.declaredMembers, not(hasItem(staticVal))) - } - - @Test - fun testPackageVar() { - assertFailsWith { fixedClass.kotlin.declaredMembers } - //assertThat("templateVar not found", sourceClass.kotlin.declaredMembers, hasItem(staticVar)) - //assertThat("templateVar still exists", fixedClass.kotlin.declaredMembers, not(hasItem(staticVar))) - } -} - -internal fun templateFun(): String = MESSAGE -internal const val templateVal: Long = BIG_NUMBER -internal var templateVar: Int = NUMBER \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixProject.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixProject.kt deleted file mode 100644 index 3891f14aed..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixProject.kt +++ /dev/null @@ -1,57 +0,0 @@ -package net.corda.gradle.jarfilter - -import org.assertj.core.api.Assertions.* -import org.gradle.testkit.runner.GradleRunner -import org.gradle.testkit.runner.TaskOutcome.* -import org.junit.Assert.* -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import org.junit.runner.Description -import org.junit.runners.model.Statement -import java.io.FileNotFoundException -import java.nio.file.Path - -@Suppress("UNUSED") -class MetaFixProject(private val projectDir: TemporaryFolder, private val name: String) : TestRule { - private var _sourceJar: Path? = null - val sourceJar: Path get() = _sourceJar ?: throw FileNotFoundException("Input not found") - - private var _metafixedJar: Path? = null - val metafixedJar: Path get() = _metafixedJar ?: throw FileNotFoundException("Output not found") - - private var _output: String = "" - val output: String get() = _output - - override fun apply(base: Statement, description: Description): Statement { - return object : Statement() { - override fun evaluate() { - projectDir.installResources( - "$name/build.gradle", - "repositories.gradle", - "gradle.properties", - "settings.gradle" - ) - - val result = GradleRunner.create() - .withProjectDir(projectDir.root) - .withArguments(getGradleArgsForTasks("metafix")) - .withPluginClasspath() - .build() - _output = result.output - println(output) - - val metafix = result.task(":metafix") - ?: throw AssertionError("No outcome for metafix task") - assertEquals(SUCCESS, metafix.outcome) - - _sourceJar = projectDir.pathOf("build", "libs", "$name.jar") - assertThat(sourceJar).isRegularFile() - - _metafixedJar = projectDir.pathOf("build", "metafixer-libs", "$name-metafixed.jar") - assertThat(metafixedJar).isRegularFile() - - base.evaluate() - } - } - } -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixSealedClassTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixSealedClassTest.kt deleted file mode 100644 index 53ac03edb6..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixSealedClassTest.kt +++ /dev/null @@ -1,37 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.jarfilter.asm.* -import org.assertj.core.api.Assertions.* -import org.gradle.api.logging.Logger -import org.junit.Test -import kotlin.reflect.jvm.jvmName - -class MetaFixSealedClassTest { - companion object { - private val logger: Logger = StdOutLogging(MetaFixSealedClassTest::class) - private val UNWANTED_CLASS: String = "${MetaSealedClass::class.jvmName}\$Unwanted" - private val WANTED_CLASS: String = MetaSealedClass.Wanted::class.jvmName - } - - @Test - fun testSealedSubclassRemovedFromMetadata() { - val bytecode = recodeMetadataFor() - val sourceClass = bytecode.toClass() - assertThat(sourceClass.classMetadata.sealedSubclasses).containsExactlyInAnyOrder(UNWANTED_CLASS, WANTED_CLASS) - - // Rewrite the metadata according to the contents of the bytecode. - val fixedClass = bytecode.fixMetadata(logger, pathsOf(MetaSealedClass::class, MetaSealedClass.Wanted::class)) - .toClass() - assertThat(fixedClass.classMetadata.sealedSubclasses).containsExactly(WANTED_CLASS) - } - - @Suppress("UNUSED") - sealed class MetadataTemplate { - class Wanted : MetadataTemplate() - class Unwanted : MetadataTemplate() - } -} - -sealed class MetaSealedClass { - class Wanted : MetaSealedClass() -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixTimestampTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixTimestampTest.kt deleted file mode 100644 index f96b94558c..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixTimestampTest.kt +++ /dev/null @@ -1,108 +0,0 @@ -package net.corda.gradle.jarfilter - -import org.assertj.core.api.Assertions.* -import org.gradle.testkit.runner.GradleRunner -import org.gradle.testkit.runner.TaskOutcome.* -import org.junit.Assert.* -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import org.junit.runners.model.Statement -import java.nio.file.Path -import java.nio.file.attribute.FileTime -import java.util.* -import java.util.Calendar.FEBRUARY -import java.util.zip.ZipEntry -import java.util.zip.ZipEntry.* -import java.util.zip.ZipFile - -class MetaFixTimestampTest { - companion object { - private val testProjectDir = TemporaryFolder() - private val sourceJar = DummyJar(testProjectDir, MetaFixTimestampTest::class.java, "timestamps") - - private val CONSTANT_TIME: FileTime = FileTime.fromMillis( - GregorianCalendar(1980, FEBRUARY, 1).apply { - timeZone = TimeZone.getTimeZone("UTC") - }.timeInMillis - ) - - private lateinit var metafixedJar: Path - private lateinit var output: String - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(sourceJar) - .around(createTestProject()) - - private fun createTestProject() = TestRule { base, _ -> - object : Statement() { - override fun evaluate() { - testProjectDir.installResource("gradle.properties") - testProjectDir.newFile("build.gradle").writeText(""" -plugins { - id 'net.corda.plugins.jar-filter' -} - -import net.corda.gradle.jarfilter.MetaFixerTask -task metafix(type: MetaFixerTask) { - jars file("${sourceJar.path.toUri()}") - preserveTimestamps = false -} -""") - val result = GradleRunner.create() - .withProjectDir(testProjectDir.root) - .withArguments(getGradleArgsForTasks("metafix")) - .withPluginClasspath() - .build() - output = result.output - println(output) - - val metafix = result.task(":metafix") - ?: throw AssertionError("No outcome for metafix task") - assertEquals(SUCCESS, metafix.outcome) - - metafixedJar = testProjectDir.pathOf("build", "metafixer-libs", "timestamps-metafixed.jar") - assertThat(metafixedJar).isRegularFile() - - base.evaluate() - } - } - } - - private val ZipEntry.methodName: String get() = if (method == STORED) "Stored" else "Deflated" - } - - @Test - fun fileTimestampsAreRemoved() { - var directoryCount = 0 - var classCount = 0 - var otherCount = 0 - - ZipFile(metafixedJar.toFile()).use { jar -> - for (entry in jar.entries()) { - println("Entry: ${entry.name}") - println("- ${entry.methodName} (${entry.size} size / ${entry.compressedSize} compressed) bytes") - assertThat(entry.lastModifiedTime).isEqualTo(CONSTANT_TIME) - assertThat(entry.lastAccessTime).isNull() - assertThat(entry.creationTime).isNull() - - if (entry.isDirectory) { - ++directoryCount - } else if (entry.name.endsWith(".class")) { - ++classCount - } else { - ++otherCount - } - } - } - - assertThat(directoryCount).isGreaterThan(0) - assertThat(classCount).isGreaterThan(0) - assertThat(otherCount).isGreaterThan(0) - } -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixValPropertyTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixValPropertyTest.kt deleted file mode 100644 index cef1cb2a77..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixValPropertyTest.kt +++ /dev/null @@ -1,49 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.unwanted.* -import net.corda.gradle.jarfilter.asm.* -import net.corda.gradle.jarfilter.matcher.* -import org.gradle.api.logging.Logger -import org.hamcrest.core.IsCollectionContaining.hasItem -import org.hamcrest.core.IsNot.not -import org.junit.Assert.* -import org.junit.Test -import kotlin.jvm.kotlin -import kotlin.reflect.full.declaredMemberProperties - -class MetaFixValPropertyTest { - companion object { - private val logger: Logger = StdOutLogging(MetaFixValPropertyTest::class) - private val unwantedVal = isProperty("unwantedVal", String::class) - private val intVal = isProperty("intVal", Int::class) - } - - @Test - fun testPropertyRemovedFromMetadata() { - val bytecode = recodeMetadataFor() - val sourceClass = bytecode.toClass() - - // Check that the unwanted property has been successfully - // added to the metadata, and that the class is valid. - val sourceObj = sourceClass.newInstance() - assertEquals(NUMBER, sourceObj.intVal) - assertThat("unwantedVal not found", sourceClass.kotlin.declaredMemberProperties, hasItem(unwantedVal)) - assertThat("intVal not found", sourceClass.kotlin.declaredMemberProperties, hasItem(intVal)) - - // Rewrite the metadata according to the contents of the bytecode. - val fixedClass = bytecode.fixMetadata(logger, pathsOf(WithValProperty::class)).toClass() - val fixedObj = fixedClass.newInstance() - assertEquals(NUMBER, fixedObj.intVal) - assertThat("unwantedVal still exists", fixedClass.kotlin.declaredMemberProperties, not(hasItem(unwantedVal))) - assertThat("intVal not found", fixedClass.kotlin.declaredMemberProperties, hasItem(intVal)) - } - - class MetadataTemplate : HasIntVal { - override val intVal: Int = 0 - @Suppress("UNUSED") val unwantedVal: String = "UNWANTED" - } -} - -class WithValProperty : HasIntVal { - override val intVal: Int = NUMBER -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixVarPropertyTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixVarPropertyTest.kt deleted file mode 100644 index 9d904f610a..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MetaFixVarPropertyTest.kt +++ /dev/null @@ -1,49 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.unwanted.* -import net.corda.gradle.jarfilter.asm.* -import net.corda.gradle.jarfilter.matcher.* -import org.gradle.api.logging.Logger -import org.hamcrest.core.IsCollectionContaining.hasItem -import org.hamcrest.core.IsNot.not -import org.junit.Assert.* -import org.junit.Test -import kotlin.jvm.kotlin -import kotlin.reflect.full.declaredMemberProperties - -class MetaFixVarPropertyTest { - companion object { - private val logger: Logger = StdOutLogging(MetaFixVarPropertyTest::class) - private val unwantedVar = isProperty("unwantedVar", String::class) - private val intVar = isProperty("intVar", Int::class) - } - - @Test - fun testPropertyRemovedFromMetadata() { - val bytecode = recodeMetadataFor() - val sourceClass = bytecode.toClass() - - // Check that the unwanted property has been successfully - // added to the metadata, and that the class is valid. - val sourceObj = sourceClass.newInstance() - assertEquals(NUMBER, sourceObj.intVar) - assertThat("unwantedVar not found", sourceClass.kotlin.declaredMemberProperties, hasItem(unwantedVar)) - assertThat("intVar not found", sourceClass.kotlin.declaredMemberProperties, hasItem(intVar)) - - // Rewrite the metadata according to the contents of the bytecode. - val fixedClass = bytecode.fixMetadata(logger, pathsOf(WithVarProperty::class)).toClass() - val fixedObj = fixedClass.newInstance() - assertEquals(NUMBER, fixedObj.intVar) - assertThat("unwantedVar still exists", fixedClass.kotlin.declaredMemberProperties, not(hasItem(unwantedVar))) - assertThat("intVar not found", fixedClass.kotlin.declaredMemberProperties, hasItem(intVar)) - } - - class MetadataTemplate : HasIntVar { - override var intVar: Int = 0 - @Suppress("UNUSED") var unwantedVar: String = "UNWANTED" - } -} - -class WithVarProperty : HasIntVar { - override var intVar: Int = NUMBER -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MethodElementTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MethodElementTest.kt deleted file mode 100644 index bee8d58568..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/MethodElementTest.kt +++ /dev/null @@ -1,88 +0,0 @@ -package net.corda.gradle.jarfilter - -import org.junit.Assert.* -import org.junit.Test -import org.objectweb.asm.Opcodes.* - -class MethodElementTest { - private companion object { - private const val DESCRIPTOR = "()Ljava.lang.String;" - } - - @Test - fun testMethodsMatchByNameAndDescriptor() { - val elt = MethodElement( - name = "getThing", - descriptor = DESCRIPTOR, - access = ACC_PUBLIC or ACC_ABSTRACT or ACC_FINAL - ) - assertEquals(MethodElement(name="getThing", descriptor=DESCRIPTOR), elt) - assertNotEquals(MethodElement(name="getOther", descriptor=DESCRIPTOR), elt) - assertNotEquals(MethodElement(name="getThing", descriptor="()J"), elt) - } - - @Test - fun testBasicMethodVisibleName() { - val elt = MethodElement( - name = "getThing", - descriptor = DESCRIPTOR, - access = ACC_PUBLIC - ) - assertEquals("getThing", elt.visibleName) - } - - @Test - fun testMethodVisibleNameWithSuffix() { - val elt = MethodElement( - name = "getThing\$extra", - descriptor = DESCRIPTOR, - access = ACC_PUBLIC - ) - assertEquals("getThing", elt.visibleName) - } - - @Test - fun testSyntheticMethodSuffix() { - val elt = MethodElement( - name = "getThing\$extra", - descriptor = DESCRIPTOR, - access = ACC_PUBLIC or ACC_SYNTHETIC - ) - assertTrue(elt.isKotlinSynthetic("extra")) - assertFalse(elt.isKotlinSynthetic("something")) - assertTrue(elt.isKotlinSynthetic("extra", "something")) - } - - @Test - fun testPublicMethodSuffix() { - val elt = MethodElement( - name = "getThing\$extra", - descriptor = DESCRIPTOR, - access = ACC_PUBLIC - ) - assertFalse(elt.isKotlinSynthetic("extra")) - } - - @Test - fun testMethodDoesNotExpire() { - val elt = MethodElement( - name = "getThing\$extra", - descriptor = DESCRIPTOR, - access = ACC_PUBLIC - ) - assertFalse(elt.isExpired) - assertFalse(elt.isExpired) - assertFalse(elt.isExpired) - } - - @Test - fun testArtificialMethodDoesExpire() { - val elt = MethodElement( - name = "getThing\$extra", - descriptor = DESCRIPTOR - ) - assertFalse(elt.isExpired) - assertTrue(elt.isExpired) - assertTrue(elt.isExpired) - } -} \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/PackageWithDefaultParameters.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/PackageWithDefaultParameters.kt deleted file mode 100644 index 8665cb17cd..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/PackageWithDefaultParameters.kt +++ /dev/null @@ -1,12 +0,0 @@ -@file:JvmName("PackageWithDefaultParameters") -@file:Suppress("UNUSED") -package net.corda.gradle.jarfilter - -/** - * Example package functions, one with default parameter values and one without. - * We will rewrite this class's metadata so that it expects both functions to - * have default parameter values, and then ask the [MetaFixerTask] to fix it. - */ -fun hasDefaultParameters(intData: Int=0, message: String=DEFAULT_MESSAGE): String = "$message: intData=$intData" - -fun hasMandatoryParameters(longData: Long, message: String): String = "$message: longData=$longData" diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/RemoveAnnotationsTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/RemoveAnnotationsTest.kt deleted file mode 100644 index ba074903c8..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/RemoveAnnotationsTest.kt +++ /dev/null @@ -1,176 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.unwanted.HasUnwantedFun -import net.corda.gradle.unwanted.HasUnwantedVal -import net.corda.gradle.unwanted.HasUnwantedVar -import org.junit.Assert.* -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule - -class RemoveAnnotationsTest { - companion object { - private const val ANNOTATED_CLASS = "net.corda.gradle.HasUnwantedAnnotations" - private const val REMOVE_ME_CLASS = "net.corda.gradle.jarfilter.RemoveMe" - - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "remove-annotations") - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - } - - @Test - fun deleteFromClass() { - classLoaderFor(testProject.sourceJar).use { cl -> - val removeMe = cl.load(REMOVE_ME_CLASS) - cl.load(ANNOTATED_CLASS).apply { - assertNotNull(getAnnotation(removeMe)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - val removeMe = cl.load(REMOVE_ME_CLASS) - cl.load(ANNOTATED_CLASS).apply { - assertNull(getAnnotation(removeMe)) - } - } - } - - @Test - fun deleteFromDefaultConstructor() { - classLoaderFor(testProject.sourceJar).use { cl -> - val removeMe = cl.load(REMOVE_ME_CLASS) - cl.load(ANNOTATED_CLASS).apply { - getDeclaredConstructor().also { con -> - assertNotNull(con.getAnnotation(removeMe)) - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - val removeMe = cl.load(REMOVE_ME_CLASS) - cl.load(ANNOTATED_CLASS).apply { - getDeclaredConstructor().also { con -> - assertNull(con.getAnnotation(removeMe)) - } - } - } - } - - @Test - fun deleteFromPrimaryConstructor() { - classLoaderFor(testProject.sourceJar).use { cl -> - val removeMe = cl.load(REMOVE_ME_CLASS) - cl.load(ANNOTATED_CLASS).apply { - getDeclaredConstructor(Long::class.java, String::class.java).also { con -> - assertNotNull(con.getAnnotation(removeMe)) - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - val removeMe = cl.load(REMOVE_ME_CLASS) - cl.load(ANNOTATED_CLASS).apply { - getDeclaredConstructor(Long::class.java, String::class.java).also { con -> - assertNull(con.getAnnotation(removeMe)) - } - } - } - } - - @Test - fun deleteFromField() { - classLoaderFor(testProject.sourceJar).use { cl -> - val removeMe = cl.load(REMOVE_ME_CLASS) - cl.load(ANNOTATED_CLASS).apply { - getField("longField").also { field -> - assertNotNull(field.getAnnotation(removeMe)) - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - val removeMe = cl.load(REMOVE_ME_CLASS) - cl.load(ANNOTATED_CLASS).apply { - getField("longField").also { field -> - assertNull(field.getAnnotation(removeMe)) - } - } - } - } - - @Test - fun deleteFromMethod() { - classLoaderFor(testProject.sourceJar).use { cl -> - val removeMe = cl.load(REMOVE_ME_CLASS) - cl.load(ANNOTATED_CLASS).apply { - getMethod("unwantedFun", String::class.java).also { method -> - assertNotNull(method.getAnnotation(removeMe)) - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - val removeMe = cl.load(REMOVE_ME_CLASS) - cl.load(ANNOTATED_CLASS).apply { - getMethod("unwantedFun", String::class.java).also { method -> - assertNull(method.getAnnotation(removeMe)) - } - } - } - } - - @Test - fun deleteFromValProperty() { - classLoaderFor(testProject.sourceJar).use { cl -> - val removeMe = cl.load(REMOVE_ME_CLASS) - cl.load(ANNOTATED_CLASS).apply { - getMethod("getUnwantedVal").also { method -> - assertNotNull(method.getAnnotation(removeMe)) - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - val removeMe = cl.load(REMOVE_ME_CLASS) - cl.load(ANNOTATED_CLASS).apply { - getMethod("getUnwantedVal").also { method -> - assertNull(method.getAnnotation(removeMe)) - } - } - } - } - - @Test - fun deleteFromVarProperty() { - classLoaderFor(testProject.sourceJar).use { cl -> - val removeMe = cl.load(REMOVE_ME_CLASS) - cl.load(ANNOTATED_CLASS).apply { - getMethod("getUnwantedVar").also { method -> - assertNotNull(method.getAnnotation(removeMe)) - } - getMethod("setUnwantedVar", String::class.java).also { method -> - assertNotNull(method.getAnnotation(removeMe)) - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - val removeMe = cl.load(REMOVE_ME_CLASS) - cl.load(ANNOTATED_CLASS).apply { - getMethod("getUnwantedVar").also { method -> - assertNull(method.getAnnotation(removeMe)) - } - getMethod("setUnwantedVar", String::class.java).also { method -> - assertNull(method.getAnnotation(removeMe)) - } - } - } - } -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/SanitiseDeleteConstructorTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/SanitiseDeleteConstructorTest.kt deleted file mode 100644 index 2c8c442410..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/SanitiseDeleteConstructorTest.kt +++ /dev/null @@ -1,234 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.jarfilter.matcher.* -import net.corda.gradle.unwanted.HasInt -import net.corda.gradle.unwanted.HasLong -import net.corda.gradle.unwanted.HasString -import org.assertj.core.api.Assertions.* -import org.hamcrest.core.IsCollectionContaining.hasItem -import org.junit.Assert.* -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import kotlin.jvm.kotlin -import kotlin.reflect.full.primaryConstructor -import kotlin.test.assertFailsWith - -class SanitiseDeleteConstructorTest { - companion object { - private const val COMPLEX_CONSTRUCTOR_CLASS = "net.corda.gradle.HasOverloadedComplexConstructorToDelete" - private const val COUNT_INITIAL_OVERLOADED = 1 - private const val COUNT_INITIAL_MULTIPLE = 2 - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "sanitise-delete-constructor") - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - } - - @Test - fun deleteOverloadedLongConstructor() = checkClassWithLongParameter( - "net.corda.gradle.HasOverloadedLongConstructorToDelete", - COUNT_INITIAL_OVERLOADED - ) - - @Test - fun deleteMultipleLongConstructor() = checkClassWithLongParameter( - "net.corda.gradle.HasMultipleLongConstructorsToDelete", - COUNT_INITIAL_MULTIPLE - ) - - private fun checkClassWithLongParameter(longClass: String, initialCount: Int) { - val longConstructor = isConstructor(longClass, Long::class) - - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(longClass).apply { - getDeclaredConstructor(Long::class.java).newInstance(BIG_NUMBER).also { - assertEquals(BIG_NUMBER, it.longData()) - } - kotlin.constructors.apply { - assertThat("(J) not found", this, hasItem(longConstructor)) - assertEquals(initialCount, this.size) - } - val primary = kotlin.primaryConstructor ?: throw AssertionError("primary constructor missing") - assertThat(primary.call(BIG_NUMBER).longData()).isEqualTo(BIG_NUMBER) - - val noArg = kotlin.noArgConstructor ?: throw AssertionError("no-arg constructor missing") - assertThat(noArg.callBy(emptyMap()).longData()).isEqualTo(0) - assertThat(newInstance().longData()).isEqualTo(0) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(longClass).apply { - getDeclaredConstructor(Long::class.java).newInstance(BIG_NUMBER).also { - assertEquals(BIG_NUMBER, it.longData()) - } - kotlin.constructors.apply { - assertThat("(J) not found", this, hasItem(longConstructor)) - assertEquals(1, this.size) - } - val primary = kotlin.primaryConstructor ?: throw AssertionError("primary constructor missing") - assertThat(primary.call(BIG_NUMBER).longData()).isEqualTo(BIG_NUMBER) - - assertNull("no-arg constructor exists", kotlin.noArgConstructor) - assertFailsWith { getDeclaredConstructor() } - } - } - } - - @Test - fun deleteOverloadedIntConstructor() = checkClassWithIntParameter( - "net.corda.gradle.HasOverloadedIntConstructorToDelete", - COUNT_INITIAL_OVERLOADED - ) - - @Test - fun deleteMultipleIntConstructor() = checkClassWithIntParameter( - "net.corda.gradle.HasMultipleIntConstructorsToDelete", - COUNT_INITIAL_MULTIPLE - ) - - private fun checkClassWithIntParameter(intClass: String, initialCount: Int) { - val intConstructor = isConstructor(intClass, Int::class) - - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(intClass).apply { - getDeclaredConstructor(Int::class.java).newInstance(NUMBER).also { - assertEquals(NUMBER, it.intData()) - } - kotlin.constructors.apply { - assertThat("(I) not found", this, hasItem(intConstructor)) - assertEquals(initialCount, this.size) - } - val primary = kotlin.primaryConstructor ?: throw AssertionError("primary constructor missing") - assertThat(primary.call(NUMBER).intData()).isEqualTo(NUMBER) - - val noArg = kotlin.noArgConstructor ?: throw AssertionError("no-arg constructor missing") - assertThat(noArg.callBy(emptyMap()).intData()).isEqualTo(0) - assertThat(newInstance().intData()).isEqualTo(0) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(intClass).apply { - getDeclaredConstructor(Int::class.java).newInstance(NUMBER).also { - assertEquals(NUMBER, it.intData()) - } - kotlin.constructors.apply { - assertThat("(I) not found", this, hasItem(intConstructor)) - assertEquals(1, this.size) - } - val primary = kotlin.primaryConstructor ?: throw AssertionError("primary constructor missing") - assertThat(primary.call(NUMBER).intData()).isEqualTo(NUMBER) - - assertNull("no-arg constructor exists", kotlin.noArgConstructor) - assertFailsWith { getDeclaredConstructor() } - } - } - } - - @Test - fun deleteOverloadedStringConstructor() = checkClassWithStringParameter( - "net.corda.gradle.HasOverloadedStringConstructorToDelete", - COUNT_INITIAL_OVERLOADED - ) - - @Test - fun deleteMultipleStringConstructor() = checkClassWithStringParameter( - "net.corda.gradle.HasMultipleStringConstructorsToDelete", - COUNT_INITIAL_MULTIPLE - ) - - private fun checkClassWithStringParameter(stringClass: String, initialCount: Int) { - val stringConstructor = isConstructor(stringClass, String::class) - - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(stringClass).apply { - getDeclaredConstructor(String::class.java).newInstance(MESSAGE).also { - assertEquals(MESSAGE, it.stringData()) - } - kotlin.constructors.apply { - assertThat("(String) not found", this, hasItem(stringConstructor)) - assertEquals(initialCount, this.size) - } - val primary = kotlin.primaryConstructor ?: throw AssertionError("primary constructor missing") - assertThat(primary.call(MESSAGE).stringData()).isEqualTo(MESSAGE) - - val noArg = kotlin.noArgConstructor ?: throw AssertionError("no-arg constructor missing") - assertThat(noArg.callBy(emptyMap()).stringData()).isEqualTo(DEFAULT_MESSAGE) - assertThat(newInstance().stringData()).isEqualTo(DEFAULT_MESSAGE) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(stringClass).apply { - getDeclaredConstructor(String::class.java).newInstance(MESSAGE).also { - assertEquals(MESSAGE, it.stringData()) - } - kotlin.constructors.apply { - assertThat("(String) not found", this, hasItem(stringConstructor)) - assertEquals(1, this.size) - } - val primary = kotlin.primaryConstructor ?: throw AssertionError("primary constructor missing") - assertThat(primary.call(MESSAGE).stringData()).isEqualTo(MESSAGE) - - assertNull("no-arg constructor exists", kotlin.noArgConstructor) - assertFailsWith { getDeclaredConstructor() } - } - } - } - - @Test - fun deleteOverloadedComplexConstructor() { - val complexConstructor = isConstructor(COMPLEX_CONSTRUCTOR_CLASS, Int::class, String::class) - - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(COMPLEX_CONSTRUCTOR_CLASS).apply { - kotlin.constructors.apply { - assertThat("(Int,String) not found", this, hasItem(complexConstructor)) - assertEquals(1, this.size) - } - - val primary = kotlin.primaryConstructor ?: throw AssertionError("primary constructor missing") - primary.call(NUMBER, MESSAGE).also { complex -> - assertThat((complex as HasString).stringData()).isEqualTo(MESSAGE) - assertThat((complex as HasInt).intData()).isEqualTo(NUMBER) - } - - primary.callBy(mapOf(primary.parameters[1] to MESSAGE)).also { complex -> - assertThat((complex as HasString).stringData()).isEqualTo(MESSAGE) - assertThat((complex as HasInt).intData()).isEqualTo(0) - } - getDeclaredConstructor(String::class.java).newInstance(MESSAGE).also { complex -> - assertThat((complex as HasString).stringData()).isEqualTo(MESSAGE) - assertThat((complex as HasInt).intData()).isEqualTo(0) - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(COMPLEX_CONSTRUCTOR_CLASS).apply { - kotlin.constructors.apply { - assertThat("(Int,String) not found", this, hasItem(complexConstructor)) - assertEquals(1, this.size) - } - - val primary = kotlin.primaryConstructor ?: throw AssertionError("primary constructor missing") - primary.call(NUMBER, MESSAGE).also { complex -> - assertThat((complex as HasString).stringData()).isEqualTo(MESSAGE) - assertThat((complex as HasInt).intData()).isEqualTo(NUMBER) - } - - assertThat(assertFailsWith { primary.callBy(mapOf(primary.parameters[1] to MESSAGE)) }) - .hasMessageContaining("No argument provided for a required parameter") - assertFailsWith { getDeclaredConstructor(String::class.java) } - } - } - } -} \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/SanitiseStubConstructorTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/SanitiseStubConstructorTest.kt deleted file mode 100644 index d0f55cb00b..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/SanitiseStubConstructorTest.kt +++ /dev/null @@ -1,250 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.jarfilter.matcher.* -import net.corda.gradle.unwanted.HasInt -import net.corda.gradle.unwanted.HasLong -import net.corda.gradle.unwanted.HasString -import org.assertj.core.api.Assertions.* -import org.hamcrest.core.IsCollectionContaining.hasItem -import org.junit.Assert.* -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import java.lang.reflect.InvocationTargetException -import kotlin.jvm.kotlin -import kotlin.reflect.full.primaryConstructor -import kotlin.test.assertFailsWith - -class SanitiseStubConstructorTest { - companion object { - private const val COMPLEX_CONSTRUCTOR_CLASS = "net.corda.gradle.HasOverloadedComplexConstructorToStub" - private const val COUNT_OVERLOADED = 1 - private const val COUNT_MULTIPLE = 2 - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "sanitise-stub-constructor") - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - } - - @Test - fun stubOverloadedLongConstructor() = checkClassWithLongParameter( - "net.corda.gradle.HasOverloadedLongConstructorToStub", - COUNT_OVERLOADED - ) - - @Test - fun stubMultipleLongConstructor() = checkClassWithLongParameter( - "net.corda.gradle.HasMultipleLongConstructorsToStub", - COUNT_MULTIPLE - ) - - private fun checkClassWithLongParameter(longClass: String, constructorCount: Int) { - val longConstructor = isConstructor(longClass, Long::class) - - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(longClass).apply { - getDeclaredConstructor(Long::class.java).newInstance(BIG_NUMBER).also { - assertEquals(BIG_NUMBER, it.longData()) - } - kotlin.constructors.apply { - assertThat("(J) not found", this, hasItem(longConstructor)) - assertEquals(constructorCount, this.size) - } - val primary = kotlin.primaryConstructor ?: throw AssertionError("primary constructor missing") - assertThat(primary.call(BIG_NUMBER).longData()).isEqualTo(BIG_NUMBER) - - val noArg = kotlin.noArgConstructor ?: throw AssertionError("no-arg constructor missing") - assertThat(noArg.callBy(emptyMap()).longData()).isEqualTo(0) - assertThat(newInstance().longData()).isEqualTo(0) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(longClass).apply { - getDeclaredConstructor(Long::class.java).newInstance(BIG_NUMBER).also { - assertEquals(BIG_NUMBER, it.longData()) - } - kotlin.constructors.apply { - assertThat("(J) not found", this, hasItem(longConstructor)) - assertEquals(constructorCount, this.size) - } - val primary = kotlin.primaryConstructor ?: throw AssertionError("primary constructor missing") - assertThat(primary.call(BIG_NUMBER).longData()).isEqualTo(BIG_NUMBER) - - val noArg = kotlin.noArgConstructor ?: throw AssertionError("no-arg constructor missing") - assertThat(assertFailsWith { noArg.callBy(emptyMap()) }.targetException) - .isInstanceOf(UnsupportedOperationException::class.java) - .hasMessage("Method has been deleted") - assertThat(assertFailsWith { newInstance() }) - .hasMessage("Method has been deleted") - } - } - } - - @Test - fun stubOverloadedIntConstructor() = checkClassWithIntParameter( - "net.corda.gradle.HasOverloadedIntConstructorToStub", - COUNT_OVERLOADED - ) - - @Test - fun stubMultipleIntConstructor() = checkClassWithIntParameter( - "net.corda.gradle.HasMultipleIntConstructorsToStub", - COUNT_MULTIPLE - ) - - private fun checkClassWithIntParameter(intClass: String, constructorCount: Int) { - val intConstructor = isConstructor(intClass, Int::class) - - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(intClass).apply { - getDeclaredConstructor(Int::class.java).newInstance(NUMBER).also { - assertEquals(NUMBER, it.intData()) - } - kotlin.constructors.apply { - assertThat("(I) not found", this, hasItem(intConstructor)) - assertEquals(constructorCount, this.size) - } - val primary = kotlin.primaryConstructor ?: throw AssertionError("primary constructor missing") - assertThat(primary.call(NUMBER).intData()).isEqualTo(NUMBER) - - val noArg = kotlin.noArgConstructor ?: throw AssertionError("no-arg constructor missing") - assertThat(noArg.callBy(emptyMap()).intData()).isEqualTo(0) - assertThat(newInstance().intData()).isEqualTo(0) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(intClass).apply { - getDeclaredConstructor(Int::class.java).newInstance(NUMBER).also { - assertEquals(NUMBER, it.intData()) - } - kotlin.constructors.apply { - assertThat("(I) not found", this, hasItem(intConstructor)) - assertEquals(constructorCount, this.size) - } - val primary = kotlin.primaryConstructor ?: throw AssertionError("primary constructor missing") - assertThat(primary.call(NUMBER).intData()).isEqualTo(NUMBER) - - val noArg = kotlin.noArgConstructor ?: throw AssertionError("no-arg constructor missing") - assertThat(assertFailsWith { noArg.callBy(emptyMap()) }.targetException) - .isInstanceOf(UnsupportedOperationException::class.java) - .hasMessage("Method has been deleted") - assertThat(assertFailsWith { newInstance() }) - .hasMessage("Method has been deleted") - } - } - } - - @Test - fun stubOverloadedStringConstructor() = checkClassWithStringParameter( - "net.corda.gradle.HasOverloadedStringConstructorToStub", - COUNT_OVERLOADED - ) - - @Test - fun stubMultipleStringConstructor() = checkClassWithStringParameter( - "net.corda.gradle.HasMultipleStringConstructorsToStub", - COUNT_MULTIPLE - ) - - private fun checkClassWithStringParameter(stringClass: String, constructorCount: Int) { - val stringConstructor = isConstructor(stringClass, String::class) - - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(stringClass).apply { - getDeclaredConstructor(String::class.java).newInstance(MESSAGE).also { - assertEquals(MESSAGE, it.stringData()) - } - kotlin.constructors.apply { - assertThat("(String) not found", this, hasItem(stringConstructor)) - assertEquals(constructorCount, this.size) - } - val primary = kotlin.primaryConstructor ?: throw AssertionError("primary constructor missing") - assertThat(primary.call(MESSAGE).stringData()).isEqualTo(MESSAGE) - - val noArg = kotlin.noArgConstructor ?: throw AssertionError("no-arg constructor missing") - assertThat(noArg.callBy(emptyMap()).stringData()).isEqualTo(DEFAULT_MESSAGE) - assertThat(newInstance().stringData()).isEqualTo(DEFAULT_MESSAGE) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(stringClass).apply { - getDeclaredConstructor(String::class.java).newInstance(MESSAGE).also { - assertEquals(MESSAGE, it.stringData()) - } - kotlin.constructors.apply { - assertThat("(String) not found", this, hasItem(stringConstructor)) - assertEquals(constructorCount, this.size) - } - val primary = kotlin.primaryConstructor ?: throw AssertionError("primary constructor missing") - assertThat(primary.call(MESSAGE).stringData()).isEqualTo(MESSAGE) - - val noArg = kotlin.noArgConstructor ?: throw AssertionError("no-arg constructor missing") - assertThat(assertFailsWith { noArg.callBy(emptyMap()) }.targetException) - .isInstanceOf(UnsupportedOperationException::class.java) - .hasMessage("Method has been deleted") - assertThat(assertFailsWith { newInstance() }) - .hasMessage("Method has been deleted") - } - } - } - - @Test - fun stubOverloadedComplexConstructor() { - val complexConstructor = isConstructor(COMPLEX_CONSTRUCTOR_CLASS, Int::class, String::class) - - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(COMPLEX_CONSTRUCTOR_CLASS).apply { - kotlin.constructors.apply { - assertThat("(Int,String) not found", this, hasItem(complexConstructor)) - assertEquals(1, this.size) - } - - val primary = kotlin.primaryConstructor ?: throw AssertionError("primary constructor missing") - primary.call(NUMBER, MESSAGE).also { complex -> - assertThat((complex as HasString).stringData()).isEqualTo(MESSAGE) - assertThat((complex as HasInt).intData()).isEqualTo(NUMBER) - } - - primary.callBy(mapOf(primary.parameters[1] to MESSAGE)).also { complex -> - assertThat((complex as HasString).stringData()).isEqualTo(MESSAGE) - assertThat((complex as HasInt).intData()).isEqualTo(0) - } - getDeclaredConstructor(String::class.java).newInstance(MESSAGE).also { complex -> - assertThat((complex as HasString).stringData()).isEqualTo(MESSAGE) - assertThat((complex as HasInt).intData()).isEqualTo(0) - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(COMPLEX_CONSTRUCTOR_CLASS).apply { - kotlin.constructors.apply { - assertThat("(Int,String) not found", this, hasItem(complexConstructor)) - assertEquals(1, this.size) - } - - val primary = kotlin.primaryConstructor ?: throw AssertionError("primary constructor missing") - primary.call(NUMBER, MESSAGE).also { complex -> - assertThat((complex as HasString).stringData()).isEqualTo(MESSAGE) - assertThat((complex as HasInt).intData()).isEqualTo(NUMBER) - } - - assertThat(assertFailsWith { primary.callBy(mapOf(primary.parameters[1] to MESSAGE)) }.targetException) - .isInstanceOf(kotlin.UnsupportedOperationException::class.java) - .hasMessage("Method has been deleted") - assertThat(assertFailsWith { getDeclaredConstructor(String::class.java).newInstance(MESSAGE) }.targetException) - .hasMessage("Method has been deleted") - } - } - } - -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/StaticFieldRemovalTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/StaticFieldRemovalTest.kt deleted file mode 100644 index e174ed147a..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/StaticFieldRemovalTest.kt +++ /dev/null @@ -1,102 +0,0 @@ -@file:JvmName("StaticFields") -@file:Suppress("UNUSED") -package net.corda.gradle.jarfilter - -import net.corda.gradle.jarfilter.annotations.Deletable -import net.corda.gradle.jarfilter.asm.bytecode -import net.corda.gradle.jarfilter.asm.toClass -import org.gradle.api.logging.Logger -import org.junit.Assert.* -import org.junit.BeforeClass -import org.junit.Test -import org.objectweb.asm.ClassWriter.COMPUTE_MAXS -import kotlin.reflect.jvm.jvmName -import kotlin.test.assertFailsWith - -/** - * Static properties are all initialised in the same block. - * Show that deleting some field references doesn't break the other - * properties' initialisation code. - */ -class StaticFieldRemovalTest { - companion object { - private val logger: Logger = StdOutLogging(StaticFieldRemovalTest::class) - private const val FIELD_CLASS = "net.corda.gradle.jarfilter.StaticFields" - - private lateinit var sourceClass: Class - private lateinit var targetClass: Class - - private fun transform(type: Class, asType: Class): Class { - val bytecode = type.bytecode.execute({ writer -> - FilterTransformer( - visitor = writer, - logger = logger, - removeAnnotations = emptySet(), - deleteAnnotations = setOf(Deletable::class.jvmName.descriptor), - stubAnnotations = emptySet(), - unwantedElements = UnwantedCache() - ) - }, COMPUTE_MAXS) - return bytecode.toClass(type, asType) - } - - @JvmStatic - @BeforeClass - fun setup() { - sourceClass = Class.forName(FIELD_CLASS) - targetClass = transform(sourceClass, Any::class.java) - } - } - - @Test - fun deleteStaticString() { - assertEquals("1", sourceClass.getDeclaredMethod("getStaticString").invoke(null)) - assertFailsWith { targetClass.getDeclaredMethod("getStaticString") } - } - - @Test - fun deleteStaticLong() { - assertEquals(2L, sourceClass.getDeclaredMethod("getStaticLong").invoke(null)) - assertFailsWith { targetClass.getDeclaredMethod("getStaticLong") } - } - - @Test - fun deleteStaticInt() { - assertEquals(3, sourceClass.getDeclaredMethod("getStaticInt").invoke(null)) - assertFailsWith { targetClass.getDeclaredMethod("getStaticInt") } - } - - @Test - fun deleteStaticShort() { - assertEquals(4.toShort(), sourceClass.getDeclaredMethod("getStaticShort").invoke(null)) - assertFailsWith { targetClass.getDeclaredMethod("getStaticShort") } - } - - @Test - fun deleteStaticByte() { - assertEquals(5.toByte(), sourceClass.getDeclaredMethod("getStaticByte").invoke(null)) - assertFailsWith { targetClass.getDeclaredMethod("getStaticByte") } - } - - @Test - fun deleteStaticChar() { - assertEquals(6.toChar(), sourceClass.getDeclaredMethod("getStaticChar").invoke(null)) - assertFailsWith { targetClass.getDeclaredMethod("getStaticChar") } - } - - @Test - fun checkSeedHasBeenIncremented() { - assertEquals(6, sourceClass.getDeclaredMethod("getStaticSeed").invoke(null)) - assertEquals(6, targetClass.getDeclaredMethod("getStaticSeed").invoke(null)) - } -} - -private var seed: Int = 0 -val staticSeed get() = seed - -@Deletable val staticString: String = (++seed).toString() -@Deletable val staticLong: Long = (++seed).toLong() -@Deletable val staticInt: Int = ++seed -@Deletable val staticShort: Short = (++seed).toShort() -@Deletable val staticByte: Byte = (++seed).toByte() -@Deletable val staticChar: Char = (++seed).toChar() diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/StdOutLogging.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/StdOutLogging.kt deleted file mode 100644 index 7cd785cf8f..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/StdOutLogging.kt +++ /dev/null @@ -1,262 +0,0 @@ -package net.corda.gradle.jarfilter - -import org.gradle.api.logging.LogLevel.* -import org.gradle.api.logging.LogLevel -import org.gradle.api.logging.Logger -import org.slf4j.Marker -import org.slf4j.helpers.MessageFormatter -import kotlin.reflect.KClass - -class StdOutLogging(private val name: String, private val threshold: LogLevel = INFO) : Logger { - constructor(clazz: KClass<*>) : this(clazz.java.simpleName) - - override fun getName(): String = name - - override fun isErrorEnabled(): Boolean = isEnabled(ERROR) - override fun isErrorEnabled(marker: Marker): Boolean = isEnabled(ERROR) - - override fun isWarnEnabled(): Boolean = isEnabled(WARN) - override fun isWarnEnabled(marker: Marker): Boolean = isEnabled(WARN) - - override fun isInfoEnabled(): Boolean = isEnabled(INFO) - override fun isInfoEnabled(marker: Marker): Boolean = isEnabled(INFO) - - override fun isDebugEnabled(): Boolean = isEnabled(DEBUG) - override fun isDebugEnabled(marker: Marker): Boolean = isEnabled(DEBUG) - - override fun isTraceEnabled(): Boolean = isEnabled(DEBUG) - override fun isTraceEnabled(marker: Marker): Boolean = isEnabled(DEBUG) - - override fun isQuietEnabled(): Boolean = isEnabled(QUIET) - - override fun isLifecycleEnabled(): Boolean = isEnabled(LIFECYCLE) - - override fun isEnabled(level: LogLevel): Boolean = threshold <= level - - override fun warn(msg: String) = log(WARN, msg) - override fun warn(msg: String, obj: Any?) = log(WARN, msg, obj) - override fun warn(msg: String, vararg objects: Any?) = log(WARN, msg, *objects) - override fun warn(msg: String, obj1: Any?, obj2: Any?) = log(WARN, msg, obj1, obj2) - override fun warn(msg: String, ex: Throwable) = log(WARN, msg, ex) - - override fun warn(marker: Marker, msg: String) { - if (isWarnEnabled(marker)) { - print(WARN, msg) - } - } - - override fun warn(marker: Marker, msg: String, obj: Any?) { - if (isWarnEnabled(marker)) { - print(WARN, msg, obj) - } - } - - override fun warn(marker: Marker, msg: String, obj1: Any?, obj2: Any?) { - if (isWarnEnabled(marker)) { - print(WARN, msg, obj1, obj2) - } - } - - override fun warn(marker: Marker, msg: String, vararg objects: Any?) { - if (isWarnEnabled(marker)) { - printAny(WARN, msg, *objects) - } - } - - override fun warn(marker: Marker, msg: String, ex: Throwable) { - if (isWarnEnabled(marker)) { - print(WARN, msg, ex) - } - } - - override fun info(message: String, vararg objects: Any?) = log(INFO, message, *objects) - override fun info(message: String) = log(INFO, message) - override fun info(message: String, obj: Any?) = log(INFO, message, obj) - override fun info(message: String, obj1: Any?, obj2: Any?) = log(INFO, message, obj1, obj2) - override fun info(message: String, ex: Throwable) = log(INFO, message, ex) - - override fun info(marker: Marker, msg: String) { - if (isInfoEnabled(marker)) { - print(INFO, msg) - } - } - - override fun info(marker: Marker, msg: String, obj: Any?) { - if (isInfoEnabled(marker)) { - print(INFO, msg, obj) - } - } - - override fun info(marker: Marker, msg: String, obj1: Any?, obj2: Any?) { - if (isInfoEnabled(marker)) { - print(INFO, msg, obj1, obj2) - } - } - - override fun info(marker: Marker, msg: String, vararg objects: Any?) { - if (isInfoEnabled(marker)) { - printAny(INFO, msg, *objects) - } - } - - override fun info(marker: Marker, msg: String, ex: Throwable) { - if (isInfoEnabled(marker)) { - print(INFO, msg, ex) - } - } - - override fun error(message: String) = log(ERROR, message) - override fun error(message: String, obj: Any?) = log(ERROR, message, obj) - override fun error(message: String, obj1: Any?, obj2: Any?) = log(ERROR, message, obj1, obj2) - override fun error(message: String, vararg objects: Any?) = log(ERROR, message, *objects) - override fun error(message: String, ex: Throwable) = log(ERROR, message, ex) - - override fun error(marker: Marker, msg: String) { - if (isErrorEnabled(marker)) { - print(ERROR, msg) - } - } - - override fun error(marker: Marker, msg: String, obj: Any?) { - if (isErrorEnabled(marker)) { - print(ERROR, msg, obj) - } - } - - override fun error(marker: Marker, msg: String, obj1: Any?, obj2: Any?) { - if (isErrorEnabled(marker)) { - print(ERROR, msg, obj1, obj2) - } - } - - override fun error(marker: Marker, msg: String, vararg objects: Any?) { - if (isErrorEnabled(marker)) { - printAny(ERROR, msg, *objects) - } - } - - override fun error(marker: Marker, msg: String, ex: Throwable) { - if (isErrorEnabled(marker)) { - print(ERROR, msg, ex) - } - } - - override fun log(level: LogLevel, message: String) { - if (isEnabled(level)) { - print(level, message) - } - } - - override fun log(level: LogLevel, message: String, vararg objects: Any?) { - if (isEnabled(level)) { - printAny(level, message, *objects) - } - } - - override fun log(level: LogLevel, message: String, ex: Throwable) { - if (isEnabled(level)) { - print(level, message, ex) - } - } - - override fun debug(message: String, vararg objects: Any?) = log(DEBUG, message, *objects) - override fun debug(message: String) = log(DEBUG, message) - override fun debug(message: String, obj: Any?) = log(DEBUG, message, obj) - override fun debug(message: String, obj1: Any?, obj2: Any?) = log(DEBUG, message, obj1, obj2) - override fun debug(message: String, ex: Throwable) = log(DEBUG, message, ex) - - override fun debug(marker: Marker, msg: String) { - if (isDebugEnabled(marker)) { - print(DEBUG, msg) - } - } - - override fun debug(marker: Marker, msg: String, obj: Any?) { - if (isDebugEnabled(marker)) { - print(DEBUG, msg, obj) - } - } - - override fun debug(marker: Marker, msg: String, obj1: Any?, obj2: Any?) { - if (isDebugEnabled(marker)) { - print(DEBUG, msg, obj1, obj2) - } - } - - override fun debug(marker: Marker, msg: String, vararg objects: Any?) { - if (isDebugEnabled(marker)) { - printAny(DEBUG, msg, *objects) - } - } - - override fun debug(marker: Marker, msg: String, ex: Throwable) { - if (isDebugEnabled(marker)) { - print(DEBUG, msg, ex) - } - } - - override fun lifecycle(message: String) = log(LIFECYCLE, message) - override fun lifecycle(message: String, vararg objects: Any?) = log(LIFECYCLE, message, *objects) - override fun lifecycle(message: String, ex: Throwable) = log(LIFECYCLE, message, ex) - - override fun quiet(message: String) = log(QUIET, message) - override fun quiet(message: String, vararg objects: Any?) = log(QUIET, message, *objects) - override fun quiet(message: String, ex: Throwable) = log(QUIET, message, ex) - - override fun trace(message: String) = debug(message) - override fun trace(message: String, obj: Any?) = debug(message, obj) - override fun trace(message: String, obj1: Any?, obj2: Any?) = debug(message, obj1, obj2) - override fun trace(message: String, vararg objects: Any?) = debug(message, *objects) - override fun trace(message: String, ex: Throwable) = debug(message, ex) - - override fun trace(marker: Marker, msg: String) { - if (isTraceEnabled(marker)) { - print(DEBUG, msg) - } - } - - override fun trace(marker: Marker, msg: String, obj: Any?) { - if (isTraceEnabled(marker)) { - print(DEBUG, msg, obj) - } - } - - override fun trace(marker: Marker, msg: String, obj1: Any?, obj2: Any?) { - if (isTraceEnabled(marker)) { - print(DEBUG, msg, obj1, obj2) - } - } - - override fun trace(marker: Marker, msg: String, vararg objects: Any?) { - if (isTraceEnabled(marker)) { - printAny(DEBUG, msg, *objects) - } - } - - override fun trace(marker: Marker, msg: String, ex: Throwable) { - if (isTraceEnabled) { - print(DEBUG, msg, ex) - } - } - - private fun print(level: LogLevel, message: String) { - println("$name - $level: $message") - } - - private fun print(level: LogLevel, message: String, ex: Throwable) { - print(level, message) - ex.printStackTrace(System.out) - } - - private fun print(level: LogLevel, message: String, obj: Any?) { - print(level, MessageFormatter.format(message, obj).message) - } - - private fun print(level: LogLevel, message: String, obj1: Any?, obj2: Any?) { - print(level, MessageFormatter.format(message, obj1, obj2).message) - } - - private fun printAny(level: LogLevel, message: String, vararg objects: Any?) { - print(level, MessageFormatter.arrayFormat(message, objects).message) - } -} \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/StubConstructorTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/StubConstructorTest.kt deleted file mode 100644 index 56352be355..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/StubConstructorTest.kt +++ /dev/null @@ -1,160 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.unwanted.HasAll -import net.corda.gradle.unwanted.HasInt -import net.corda.gradle.unwanted.HasLong -import net.corda.gradle.unwanted.HasString -import org.assertj.core.api.Assertions.* -import org.junit.Assert.* -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import java.lang.reflect.InvocationTargetException -import kotlin.test.assertFailsWith - -class StubConstructorTest { - companion object { - private const val STRING_PRIMARY_CONSTRUCTOR_CLASS = "net.corda.gradle.PrimaryStringConstructorToStub" - private const val LONG_PRIMARY_CONSTRUCTOR_CLASS = "net.corda.gradle.PrimaryLongConstructorToStub" - private const val INT_PRIMARY_CONSTRUCTOR_CLASS = "net.corda.gradle.PrimaryIntConstructorToStub" - private const val SECONDARY_CONSTRUCTOR_CLASS = "net.corda.gradle.HasConstructorToStub" - - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "stub-constructor") - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - } - - @Test - fun stubConstructorWithLongParameter() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(SECONDARY_CONSTRUCTOR_CLASS).apply { - getDeclaredConstructor(Long::class.java).newInstance(BIG_NUMBER).also { obj -> - assertEquals(BIG_NUMBER, obj.longData()) - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(SECONDARY_CONSTRUCTOR_CLASS).apply { - getDeclaredConstructor(Long::class.java).also { - assertFailsWith { it.newInstance(BIG_NUMBER) }.targetException.also { ex -> - assertThat(ex) - .isInstanceOf(UnsupportedOperationException::class.java) - .hasMessage("Method has been deleted") - } - } - } - } - } - - @Test - fun stubConstructorWithStringParameter() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(SECONDARY_CONSTRUCTOR_CLASS).apply { - getDeclaredConstructor(String::class.java).newInstance(MESSAGE).also { obj -> - assertEquals(MESSAGE, obj.stringData()) - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(SECONDARY_CONSTRUCTOR_CLASS).apply { - getDeclaredConstructor(String::class.java).also { - assertFailsWith { it.newInstance(MESSAGE) }.targetException.also { ex -> - assertThat(ex) - .isInstanceOf(UnsupportedOperationException::class.java) - .hasMessage("Method has been deleted") - } - } - } - } - } - - @Test - fun showUnannotatedConstructorIsUnaffected() { - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(SECONDARY_CONSTRUCTOR_CLASS).apply { - getDeclaredConstructor(Int::class.java).newInstance(NUMBER).also { obj -> - assertEquals(NUMBER, obj.intData()) - assertEquals(NUMBER.toLong(), obj.longData()) - assertEquals("", obj.stringData()) - } - } - } - } - - @Test - fun stubPrimaryConstructorWithStringParameter() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(STRING_PRIMARY_CONSTRUCTOR_CLASS).apply { - getDeclaredConstructor(String::class.java).newInstance(MESSAGE).also { obj -> - assertEquals(MESSAGE, obj.stringData()) - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(STRING_PRIMARY_CONSTRUCTOR_CLASS).apply { - getDeclaredConstructor(String::class.java).also { - assertFailsWith { it.newInstance(MESSAGE) }.targetException.also { ex -> - assertThat(ex) - .isInstanceOf(UnsupportedOperationException::class.java) - .hasMessage("Method has been deleted") - } - } - } - } - } - - @Test - fun stubPrimaryConstructorWithLongParameter() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(LONG_PRIMARY_CONSTRUCTOR_CLASS).apply { - getDeclaredConstructor(Long::class.java).newInstance(BIG_NUMBER).also { obj -> - assertEquals(BIG_NUMBER, obj.longData()) - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(LONG_PRIMARY_CONSTRUCTOR_CLASS).apply { - getDeclaredConstructor(Long::class.java).also { - assertFailsWith { it.newInstance(BIG_NUMBER) }.targetException.also { ex -> - assertThat(ex) - .isInstanceOf(UnsupportedOperationException::class.java) - .hasMessage("Method has been deleted") - } - } - } - } - } - - @Test - fun stubPrimaryConstructorWithIntParameter() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(INT_PRIMARY_CONSTRUCTOR_CLASS).apply { - getDeclaredConstructor(Int::class.java).newInstance(NUMBER).also { obj -> - assertEquals(NUMBER, obj.intData()) - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(INT_PRIMARY_CONSTRUCTOR_CLASS).apply { - getDeclaredConstructor(Int::class.java).apply { - val error = assertFailsWith { newInstance(NUMBER) }.targetException - assertThat(error) - .isInstanceOf(UnsupportedOperationException::class.java) - .hasMessage("Method has been deleted") - } - } - } - } -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/StubFunctionOutTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/StubFunctionOutTest.kt deleted file mode 100644 index 333fa2ce56..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/StubFunctionOutTest.kt +++ /dev/null @@ -1,74 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.unwanted.HasUnwantedFun -import org.assertj.core.api.Assertions.* -import org.junit.Assert.* -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import javax.annotation.Resource -import kotlin.test.assertFailsWith - -class StubFunctionOutTest { - companion object { - private const val FUNCTION_CLASS = "net.corda.gradle.HasFunctionToStub" - private const val STUB_ME_OUT_ANNOTATION = "net.corda.gradle.jarfilter.StubMeOut" - private const val PARAMETER_ANNOTATION = "net.corda.gradle.Parameter" - - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "stub-function") - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - } - - @Test - fun stubFunction() { - classLoaderFor(testProject.sourceJar).use { cl -> - val stubMeOut = cl.load(STUB_ME_OUT_ANNOTATION) - val parameter = cl.load(PARAMETER_ANNOTATION) - - cl.load(FUNCTION_CLASS).apply { - newInstance().also { obj -> - assertEquals(MESSAGE, obj.unwantedFun(MESSAGE)) - } - getMethod("unwantedFun", String::class.java).also { method -> - assertTrue("StubMeOut annotation missing", method.isAnnotationPresent (stubMeOut)) - assertTrue("Resource annotation missing", method.isAnnotationPresent(Resource::class.java)) - method.parameterAnnotations.also { paramAnns -> - assertEquals(1, paramAnns.size) - assertThat(paramAnns[0]) - .hasOnlyOneElementSatisfying { a -> a.javaClass.isInstance(parameter) } - } - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - val stubMeOut = cl.load(STUB_ME_OUT_ANNOTATION) - val parameter = cl.load(PARAMETER_ANNOTATION) - - cl.load(FUNCTION_CLASS).apply { - newInstance().also { obj -> - assertFailsWith { obj.unwantedFun(MESSAGE) }.also { ex -> - assertEquals("Method has been deleted", ex.message) - } - } - getMethod("unwantedFun", String::class.java).also { method -> - assertFalse("StubMeOut annotation present", method.isAnnotationPresent(stubMeOut)) - assertTrue("Resource annotation missing", method.isAnnotationPresent(Resource::class.java)) - method.parameterAnnotations.also { paramAnns -> - assertEquals(1, paramAnns.size) - assertThat(paramAnns[0]) - .hasOnlyOneElementSatisfying { a -> a.javaClass.isInstance(parameter) } - } - } - } - } - } -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/StubStaticFunctionTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/StubStaticFunctionTest.kt deleted file mode 100644 index 79a7ed3b7c..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/StubStaticFunctionTest.kt +++ /dev/null @@ -1,127 +0,0 @@ -package net.corda.gradle.jarfilter - -import org.assertj.core.api.Assertions.* -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import java.lang.reflect.InvocationTargetException -import kotlin.test.* - -class StubStaticFunctionTest { - companion object { - private const val FUNCTION_CLASS = "net.corda.gradle.StaticFunctionsToStub" - - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "stub-static-function") - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - } - - @Test - fun stubStringFunction() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(FUNCTION_CLASS).apply { - getDeclaredMethod("unwantedStringToStub", String::class.java).also { method -> - method.invoke(null, MESSAGE).also { result -> - assertThat(result) - .isInstanceOf(String::class.java) - .isEqualTo(MESSAGE) - } - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(FUNCTION_CLASS).apply { - getDeclaredMethod("unwantedStringToStub", String::class.java).also { method -> - assertFailsWith { method.invoke(null, MESSAGE) }.targetException.also { ex -> - assertThat(ex) - .isInstanceOf(UnsupportedOperationException::class.java) - .hasMessage("Method has been deleted") - } - } - } - } - } - - @Test - fun stubLongFunction() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(FUNCTION_CLASS).apply { - getDeclaredMethod("unwantedLongToStub", Long::class.java).also { method -> - method.invoke(null, BIG_NUMBER).also { result -> - assertThat(result) - .isInstanceOf(Long::class.javaObjectType) - .isEqualTo(BIG_NUMBER) - } - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(FUNCTION_CLASS).apply { - getDeclaredMethod("unwantedLongToStub", Long::class.java).also { method -> - assertFailsWith { method.invoke(null, BIG_NUMBER) }.targetException.also { ex -> - assertThat(ex) - .isInstanceOf(UnsupportedOperationException::class.java) - .hasMessage("Method has been deleted") - } - } - } - } - } - - @Test - fun stubIntFunction() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(FUNCTION_CLASS).apply { - getDeclaredMethod("unwantedIntToStub", Int::class.java).also { method -> - method.invoke(null, NUMBER).also { result -> - assertThat(result) - .isInstanceOf(Int::class.javaObjectType) - .isEqualTo(NUMBER) - } - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(FUNCTION_CLASS).apply { - getDeclaredMethod("unwantedIntToStub", Int::class.java).also { method -> - assertFailsWith { method.invoke(null, NUMBER) }.targetException.also { ex -> - assertThat(ex) - .isInstanceOf(UnsupportedOperationException::class.java) - .hasMessage("Method has been deleted") - } - } - } - } - } - - @Test - fun stubVoidFunction() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(FUNCTION_CLASS).apply { - val staticSeed = getDeclaredMethod("getStaticSeed") - assertEquals(0, staticSeed.invoke(null)) - getDeclaredMethod("unwantedVoidToStub").invoke(null) - assertEquals(1, staticSeed.invoke(null)) - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(FUNCTION_CLASS).apply { - val staticSeed = getDeclaredMethod("getStaticSeed") - assertEquals(0, staticSeed.invoke(null)) - getDeclaredMethod("unwantedVoidToStub").invoke(null) - assertEquals(0, staticSeed.invoke(null)) - } - } - } -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/StubValPropertyTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/StubValPropertyTest.kt deleted file mode 100644 index fbc26f2211..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/StubValPropertyTest.kt +++ /dev/null @@ -1,46 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.unwanted.HasUnwantedVal -import org.junit.Assert.* -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import kotlin.test.assertFailsWith - -class StubValPropertyTest { - companion object { - private const val PROPERTY_CLASS = "net.corda.gradle.HasValPropertyForStub" - - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "stub-val-property") - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - } - - @Test - fun deleteGetter() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - getDeclaredConstructor(String::class.java).newInstance(MESSAGE).also { obj -> - assertEquals(MESSAGE, obj.unwantedVal) - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(PROPERTY_CLASS).apply { - getDeclaredConstructor(String::class.java).newInstance(MESSAGE).also { obj -> - assertFailsWith { obj.unwantedVal }.also { ex -> - assertEquals("Method has been deleted", ex.message) - } - } - } - } - } -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/StubVarPropertyTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/StubVarPropertyTest.kt deleted file mode 100644 index 4910e83d62..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/StubVarPropertyTest.kt +++ /dev/null @@ -1,70 +0,0 @@ -package net.corda.gradle.jarfilter - -import net.corda.gradle.unwanted.HasUnwantedVar -import org.junit.Assert.* -import org.junit.ClassRule -import org.junit.Test -import org.junit.rules.RuleChain -import org.junit.rules.TemporaryFolder -import org.junit.rules.TestRule -import kotlin.test.assertFailsWith - -class StubVarPropertyTest { - companion object { - private const val GETTER_CLASS = "net.corda.gradle.HasUnwantedGetForStub" - private const val SETTER_CLASS = "net.corda.gradle.HasUnwantedSetForStub" - - private val testProjectDir = TemporaryFolder() - private val testProject = JarFilterProject(testProjectDir, "stub-var-property") - - @ClassRule - @JvmField - val rules: TestRule = RuleChain - .outerRule(testProjectDir) - .around(testProject) - } - - @Test - fun deleteGetter() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(GETTER_CLASS).apply { - getDeclaredConstructor(String::class.java).newInstance(MESSAGE).also { obj -> - assertEquals(MESSAGE, obj.unwantedVar) - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(GETTER_CLASS).apply { - getDeclaredConstructor(String::class.java).newInstance(MESSAGE).also { obj -> - assertFailsWith { obj.unwantedVar }.also { ex -> - assertEquals("Method has been deleted", ex.message) - } - } - } - } - } - - @Test - fun deleteSetter() { - classLoaderFor(testProject.sourceJar).use { cl -> - cl.load(SETTER_CLASS).apply { - getConstructor(String::class.java).newInstance(DEFAULT_MESSAGE).also { obj -> - assertEquals(DEFAULT_MESSAGE, obj.unwantedVar) - obj.unwantedVar = MESSAGE - assertEquals(MESSAGE, obj.unwantedVar) - } - } - } - - classLoaderFor(testProject.filteredJar).use { cl -> - cl.load(SETTER_CLASS).apply { - getConstructor(String::class.java).newInstance(DEFAULT_MESSAGE).also { obj -> - assertEquals(DEFAULT_MESSAGE, obj.unwantedVar) - obj.unwantedVar = MESSAGE - assertEquals(DEFAULT_MESSAGE, obj.unwantedVar) - } - } - } - } -} \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/UnwantedCacheTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/UnwantedCacheTest.kt deleted file mode 100644 index 53abf1de1b..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/UnwantedCacheTest.kt +++ /dev/null @@ -1,54 +0,0 @@ -package net.corda.gradle.jarfilter - -import org.junit.Assert.* -import org.junit.Before -import org.junit.Test - -class UnwantedCacheTest { - private companion object { - private const val CLASS_NAME = "org.testing.MyClass" - private const val LONG_ARG = "(J)V" - private const val NO_ARG = "()V" - } - - private lateinit var cache: UnwantedCache - - @Before - fun setup() { - cache = UnwantedCache() - } - - @Test - fun testEmptyCache() { - assertFalse(cache.containsClass(CLASS_NAME)) - assertFalse(cache.containsMethod(CLASS_NAME, null, null)) - assertFalse(cache.containsMethod(CLASS_NAME, "", NO_ARG)) - } - - @Test - fun testAddingClass() { - cache.addClass(CLASS_NAME) - assertTrue(cache.containsClass(CLASS_NAME)) - assertTrue(cache.containsMethod(CLASS_NAME, null, null)) - assertTrue(cache.containsMethod(CLASS_NAME, "", NO_ARG)) - } - - @Test - fun testAddingMethod() { - cache.addMethod(CLASS_NAME, MethodElement("", LONG_ARG)) - assertTrue(cache.containsMethod(CLASS_NAME, "", LONG_ARG)) - assertFalse(cache.containsMethod(CLASS_NAME, "", NO_ARG)) - assertFalse(cache.containsMethod(CLASS_NAME, "destroy", LONG_ARG)) - assertFalse(cache.containsMethod(CLASS_NAME, null, null)) - assertFalse(cache.containsMethod(CLASS_NAME, "nonsense", null)) - assertFalse(cache.containsClass(CLASS_NAME)) - } - - @Test - fun testAddingMethodFollowedByClass() { - cache.addMethod(CLASS_NAME, MethodElement("", LONG_ARG)) - cache.addClass(CLASS_NAME) - assertTrue(cache.containsMethod(CLASS_NAME, "", LONG_ARG)) - assertEquals(0, cache.classMethods.size) - } -} \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/Utilities.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/Utilities.kt deleted file mode 100644 index 443d2a3ef0..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/Utilities.kt +++ /dev/null @@ -1,97 +0,0 @@ -@file:JvmName("Utilities") -package net.corda.gradle.jarfilter - -import org.junit.AssumptionViolatedException -import org.junit.rules.TemporaryFolder -import java.io.File -import java.io.IOException -import java.net.MalformedURLException -import java.net.URLClassLoader -import java.nio.file.StandardCopyOption.* -import java.nio.file.Files -import java.nio.file.Path -import java.nio.file.Paths -import java.util.stream.Collectors.* -import java.util.zip.ZipFile -import kotlin.reflect.KClass -import kotlin.reflect.KFunction -import kotlin.reflect.KParameter -import kotlin.reflect.full.valueParameters - -const val DEFAULT_MESSAGE = "" -const val MESSAGE = "Goodbye, Cruel World!" -const val NUMBER = 111 -const val BIG_NUMBER = 9999L - -private val classLoader: ClassLoader = object {}.javaClass.classLoader - -// The AssumptionViolatedException must be caught by the JUnit test runner, -// which means that it must not be thrown when this class loads. -private val testGradleUserHomeValue: String? = System.getProperty("test.gradle.user.home") -private val testGradleUserHome: String get() = testGradleUserHomeValue - ?: throw AssumptionViolatedException("System property 'test.gradle.user.home' not set.") - -fun getGradleArgsForTasks(vararg taskNames: String): MutableList = getBasicArgsForTasks(*taskNames).apply { add("--info") } -fun getBasicArgsForTasks(vararg taskNames: String): MutableList = mutableListOf(*taskNames, "--stacktrace", "-g", testGradleUserHome) - -@Throws(IOException::class) -fun copyResourceTo(resourceName: String, target: Path) { - classLoader.getResourceAsStream(resourceName).use { source -> - Files.copy(source, target, REPLACE_EXISTING) - } -} - -@Throws(IOException::class) -fun copyResourceTo(resourceName: String, target: File) = copyResourceTo(resourceName, target.toPath()) - -@Throws(IOException::class) -fun TemporaryFolder.installResources(vararg resourceNames: String) { - resourceNames.forEach { installResource(it) } -} - -@Throws(IOException::class) -fun TemporaryFolder.installResource(resourceName: String): File = newFile(resourceName.fileName).let { file -> - copyResourceTo(resourceName, file) - file -} - -private val String.fileName: String get() = substring(1 + lastIndexOf('/')) - -val String.toPackageFormat: String get() = replace('/', '.') -fun pathsOf(vararg types: KClass<*>): Set = types.map { it.java.name.toPathFormat }.toSet() - -fun TemporaryFolder.pathOf(vararg elements: String): Path = Paths.get(root.absolutePath, *elements) - -fun arrayOfJunk(size: Int) = ByteArray(size).apply { - for (i in 0 until size) { - this[i] = (i and 0xFF).toByte() - } -} - -val KFunction<*>.hasAnyOptionalParameters: Boolean - get() = valueParameters.any(KParameter::isOptional) - -val KFunction<*>.hasAllOptionalParameters: Boolean - get() = valueParameters.all(KParameter::isOptional) - -val KFunction<*>.hasAllMandatoryParameters: Boolean - get() = valueParameters.none(KParameter::isOptional) - -val KClass.noArgConstructor: KFunction? - get() = constructors.firstOrNull(KFunction<*>::hasAllOptionalParameters) - -@Throws(MalformedURLException::class) -fun classLoaderFor(jar: Path) = URLClassLoader(arrayOf(jar.toUri().toURL()), classLoader) - -@Suppress("UNCHECKED_CAST") -@Throws(ClassNotFoundException::class) -fun ClassLoader.load(className: String) - = Class.forName(className, true, this) as Class - -fun Path.getClassNames(prefix: String): List { - val resourcePrefix = prefix.toPathFormat - return ZipFile(toFile()).stream() - .filter { it.name.startsWith(resourcePrefix) && it.name.endsWith(".class") } - .map { it.name.removeSuffix(".class").toPackageFormat } - .collect(toList()) -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/UtilsTest.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/UtilsTest.kt deleted file mode 100644 index b65a31130a..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/UtilsTest.kt +++ /dev/null @@ -1,42 +0,0 @@ -package net.corda.gradle.jarfilter - -import org.assertj.core.api.Assertions.assertThat -import org.gradle.api.GradleException -import org.gradle.api.InvalidUserDataException -import org.junit.Test -import java.io.IOException -import kotlin.test.assertFailsWith - -class UtilsTest { - @Test - fun testRethrowingCheckedException() { - val ex = assertFailsWith { rethrowAsUncheckedException(IOException(MESSAGE)) } - assertThat(ex) - .hasMessage(MESSAGE) - .hasCauseExactlyInstanceOf(IOException::class.java) - } - - @Test - fun testRethrowingCheckExceptionWithoutMessage() { - val ex = assertFailsWith { rethrowAsUncheckedException(IOException()) } - assertThat(ex) - .hasMessage("") - .hasCauseExactlyInstanceOf(IOException::class.java) - } - - @Test - fun testRethrowingUncheckedException() { - val ex = assertFailsWith { rethrowAsUncheckedException(IllegalArgumentException(MESSAGE)) } - assertThat(ex) - .hasMessage(MESSAGE) - .hasNoCause() - } - - @Test - fun testRethrowingGradleException() { - val ex = assertFailsWith { rethrowAsUncheckedException(InvalidUserDataException(MESSAGE)) } - assertThat(ex) - .hasMessage(MESSAGE) - .hasNoCause() - } -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/annotations/Deletable.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/annotations/Deletable.kt deleted file mode 100644 index 3c9597c75c..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/annotations/Deletable.kt +++ /dev/null @@ -1,8 +0,0 @@ -package net.corda.gradle.jarfilter.annotations - -import kotlin.annotation.AnnotationRetention.BINARY -import kotlin.annotation.AnnotationTarget.PROPERTY - -@Retention(BINARY) -@Target(PROPERTY) -annotation class Deletable diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/asm/AsmTools.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/asm/AsmTools.kt deleted file mode 100644 index 4c488d9dec..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/asm/AsmTools.kt +++ /dev/null @@ -1,47 +0,0 @@ -@file:JvmName("AsmTools") -package net.corda.gradle.jarfilter.asm - -import net.corda.gradle.jarfilter.descriptor -import net.corda.gradle.jarfilter.toPathFormat -import org.objectweb.asm.ClassReader -import org.objectweb.asm.ClassVisitor -import org.objectweb.asm.ClassWriter -import org.objectweb.asm.ClassWriter.COMPUTE_MAXS -import java.io.ByteArrayInputStream -import java.io.InputStream - - -fun ByteArray.accept(visitor: (ClassVisitor) -> ClassVisitor): ByteArray { - return ClassWriter(COMPUTE_MAXS).let { writer -> - ClassReader(this).accept(visitor(writer), 0) - writer.toByteArray() - } -} - -private val String.resourceName: String get() = "$toPathFormat.class" -val Class<*>.resourceName get() = name.resourceName -val Class<*>.bytecode: ByteArray get() = classLoader.getResourceAsStream(resourceName).use { it.readBytes() } -val Class<*>.descriptor: String get() = name.descriptor - -/** - * Functions for converting bytecode into a "live" Java class. - */ -inline fun ByteArray.toClass(): Class = toClass(T::class.java, R::class.java) - -fun ByteArray.toClass(type: Class, asType: Class): Class - = BytecodeClassLoader(this, type.name, type.classLoader).createClass().asSubclass(asType) - -private class BytecodeClassLoader( - private val bytecode: ByteArray, - private val className: String, - parent: ClassLoader -) : ClassLoader(parent) { - internal fun createClass(): Class<*> { - return defineClass(className, bytecode, 0, bytecode.size).apply { resolveClass(this) } - } - - // Ensure that the class we create also honours Class<*>.bytecode (above). - override fun getResourceAsStream(name: String): InputStream? { - return if (name == className.resourceName) ByteArrayInputStream(bytecode) else super.getResourceAsStream(name) - } -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/asm/ClassMetadata.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/asm/ClassMetadata.kt deleted file mode 100644 index 313a562f05..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/asm/ClassMetadata.kt +++ /dev/null @@ -1,48 +0,0 @@ -package net.corda.gradle.jarfilter.asm - -import net.corda.gradle.jarfilter.MetadataTransformer -import net.corda.gradle.jarfilter.getClassInternalName -import net.corda.gradle.jarfilter.toPackageFormat -import net.corda.gradle.jarfilter.mutableList -import org.gradle.api.logging.Logger -import org.jetbrains.kotlin.metadata.ProtoBuf -import org.jetbrains.kotlin.metadata.deserialization.TypeTable - -internal class ClassMetadata( - logger: Logger, - d1: List, - d2: List -) : MetadataTransformer( - logger, - emptyList(), - emptyList(), - emptyList(), - emptyList(), - emptyList(), - {}, - d1, - d2, - ProtoBuf.Class::parseFrom -) { - override val typeTable = TypeTable(message.typeTable) - override val className = nameResolver.getClassInternalName(message.fqName) - override val nestedClassNames = mutableList(message.nestedClassNameList) - override val properties = mutableList(message.propertyList) - override val functions = mutableList(message.functionList) - override val constructors = mutableList(message.constructorList) - override val typeAliases = mutableList(message.typeAliasList) - override val sealedSubclassNames = mutableList(message.sealedSubclassFqNameList) - - override fun rebuild(): ProtoBuf.Class = message - - val sealedSubclasses: List = sealedSubclassNames.map { - // Transform "a/b/c/BaseName$SubclassName" -> "a.b.c.BaseName$SubclassName" - nameResolver.getClassInternalName(it).toPackageFormat }.toList() - - val nestedClasses: List - - init { - val internalClassName = className.toPackageFormat - nestedClasses = nestedClassNames.map { "$internalClassName\$${nameResolver.getClassInternalName(it)}" }.toList() - } -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/asm/FileMetadata.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/asm/FileMetadata.kt deleted file mode 100644 index f7636c810c..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/asm/FileMetadata.kt +++ /dev/null @@ -1,33 +0,0 @@ -package net.corda.gradle.jarfilter.asm - -import net.corda.gradle.jarfilter.MetadataTransformer -import net.corda.gradle.jarfilter.mutableList -import org.gradle.api.logging.Logger -import org.jetbrains.kotlin.metadata.ProtoBuf -import org.jetbrains.kotlin.metadata.deserialization.TypeTable - -internal class FileMetadata( - logger: Logger, - d1: List, - d2: List -) : MetadataTransformer( - logger, - emptyList(), - emptyList(), - emptyList(), - emptyList(), - emptyList(), - {}, - d1, - d2, - ProtoBuf.Package::parseFrom -) { - override val typeTable = TypeTable(message.typeTable) - override val properties = mutableList(message.propertyList) - override val functions = mutableList(message.functionList) - override val typeAliases = mutableList(message.typeAliasList) - - override fun rebuild(): ProtoBuf.Package = message - - val typeAliasNames: List = typeAliases.map { nameResolver.getString(it.name) }.toList() -} \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/asm/MetadataTools.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/asm/MetadataTools.kt deleted file mode 100644 index 5526c5056d..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/asm/MetadataTools.kt +++ /dev/null @@ -1,86 +0,0 @@ -@file:JvmName("MetadataTools") -package net.corda.gradle.jarfilter.asm - -import net.corda.gradle.jarfilter.StdOutLogging -import org.jetbrains.kotlin.load.java.JvmAnnotationNames.* -import org.objectweb.asm.* -import org.objectweb.asm.Opcodes.ASM6 - -@Suppress("UNCHECKED_CAST") -private val metadataClass: Class - = object {}.javaClass.classLoader.loadClass("kotlin.Metadata") as Class - -/** - * Rewrite the bytecode for this class with the Kotlin @Metadata of another class. - */ -inline fun recodeMetadataFor(): ByteArray = T::class.java.metadataAs(X::class.java) - -fun Class.metadataAs(template: Class): ByteArray { - val metadata = template.readMetadata().let { m -> - val templateDescriptor = template.descriptor - val templatePrefix = templateDescriptor.dropLast(1) + '$' - val targetDescriptor = descriptor - val targetPrefix = targetDescriptor.dropLast(1) + '$' - Pair(m.first, m.second.map { s -> - when { - // Replace any references to the template class with the target class. - s == templateDescriptor -> targetDescriptor - s.startsWith(templatePrefix) -> targetPrefix + s.substring(templatePrefix.length) - else -> s - } - }.toList()) - } - return bytecode.accept { w -> MetadataWriter(metadata, w) } -} - -/** - * Kotlin reflection only supports classes atm, so use this to examine file metadata. - */ -internal val Class<*>.fileMetadata: FileMetadata get() { - val (d1, d2) = readMetadata() - return FileMetadata(StdOutLogging(kotlin), d1, d2) -} - -/** - * For accessing the parts of class metadata that Kotlin reflection cannot reach. - */ -internal val Class<*>.classMetadata: ClassMetadata get() { - val (d1, d2) = readMetadata() - return ClassMetadata(StdOutLogging(kotlin), d1, d2) -} - -private fun Class<*>.readMetadata(): Pair, List> { - val metadata = getAnnotation(metadataClass) - val d1 = metadataClass.getMethod(METADATA_DATA_FIELD_NAME) - val d2 = metadataClass.getMethod(METADATA_STRINGS_FIELD_NAME) - return Pair(d1.invoke(metadata).asList(), d2.invoke(metadata).asList()) -} - -@Suppress("UNCHECKED_CAST") -fun Any.asList(): List { - return (this as? Array)?.toList() ?: emptyList() -} - -private class MetadataWriter(metadata: Pair, List>, visitor: ClassVisitor) : ClassVisitor(ASM6, visitor) { - private val kotlinMetadata: MutableMap> = mutableMapOf( - METADATA_DATA_FIELD_NAME to metadata.first, - METADATA_STRINGS_FIELD_NAME to metadata.second - ) - - override fun visitAnnotation(descriptor: String, visible: Boolean): AnnotationVisitor? { - val av = super.visitAnnotation(descriptor, visible) ?: return null - return if (descriptor == METADATA_DESC) KotlinMetadataWriter(av) else av - } - - private inner class KotlinMetadataWriter(av: AnnotationVisitor) : AnnotationVisitor(api, av) { - override fun visitArray(name: String): AnnotationVisitor? { - val av = super.visitArray(name) - if (av != null) { - val data = kotlinMetadata.remove(name) ?: return av - data.forEach { av.visit(null, it) } - av.visitEnd() - } - return null - } - } -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/matcher/JavaMatchers.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/matcher/JavaMatchers.kt deleted file mode 100644 index 19dc03a3bf..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/matcher/JavaMatchers.kt +++ /dev/null @@ -1,81 +0,0 @@ -@file:JvmName("JavaMatchers") -package net.corda.gradle.jarfilter.matcher - -import org.hamcrest.Description -import org.hamcrest.DiagnosingMatcher -import org.hamcrest.Matcher -import org.hamcrest.core.IsEqual.* -import java.lang.reflect.Method -import kotlin.reflect.KClass - -fun isMethod(name: Matcher, returnType: Matcher>, vararg parameters: Matcher>): Matcher { - return MethodMatcher(name, returnType, *parameters) -} - -fun isMethod(name: String, returnType: Class<*>, vararg parameters: Class<*>): Matcher { - return isMethod(equalTo(name), equalTo(returnType), *parameters.toMatchers()) -} - -private fun Array>.toMatchers() = map(::equalTo).toTypedArray() - -val KClass<*>.javaDeclaredMethods: List get() = java.declaredMethods.toList() - -/** - * Matcher logic for a Java [Method] object. Also applicable to constructors. - */ -private class MethodMatcher( - private val name: Matcher, - private val returnType: Matcher>, - vararg parameters: Matcher> -) : DiagnosingMatcher() { - private val parameters = listOf(*parameters) - - override fun describeTo(description: Description) { - description.appendText("Method[name as ").appendDescriptionOf(name) - .appendText(", returnType as ").appendDescriptionOf(returnType) - .appendText(", parameters as '") - if (parameters.isNotEmpty()) { - val param = parameters.iterator() - description.appendValue(param.next()) - while (param.hasNext()) { - description.appendText(",").appendValue(param.next()) - } - } - description.appendText("']") - } - - override fun matches(obj: Any?, mismatch: Description): Boolean { - if (obj == null) { - mismatch.appendText("is null") - return false - } - - val method: Method = obj as? Method ?: return false - if (!name.matches(method.name)) { - mismatch.appendText("name is ").appendValue(method.name) - return false - } - method.returnType.apply { - if (!returnType.matches(this)) { - mismatch.appendText("returnType is ").appendValue(this.name) - return false - } - } - - if (method.parameterTypes.size != parameters.size) { - mismatch.appendText("number of parameters is ").appendValue(method.parameterTypes.size) - .appendText(", parameters=").appendValueList("[", ",", "]", method.parameterTypes) - return false - } - - var i = 0 - method.parameterTypes.forEach { param -> - if (!parameters[i].matches(param)) { - mismatch.appendText("parameter[").appendValue(i).appendText("] is ").appendValue(param) - return false - } - ++i - } - return true - } -} diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/matcher/KotlinMatchers.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/matcher/KotlinMatchers.kt deleted file mode 100644 index f5e0528927..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/matcher/KotlinMatchers.kt +++ /dev/null @@ -1,195 +0,0 @@ -@file:JvmName("KotlinMatchers") -package net.corda.gradle.jarfilter.matcher - -import org.hamcrest.Description -import org.hamcrest.DiagnosingMatcher -import org.hamcrest.Matcher -import org.hamcrest.core.IsEqual.equalTo -import kotlin.reflect.KClass -import kotlin.reflect.KFunction -import kotlin.reflect.KParameter -import kotlin.reflect.KProperty -import kotlin.reflect.full.valueParameters -import kotlin.reflect.jvm.jvmName - -fun isFunction(name: Matcher, returnType: Matcher, vararg parameters: Matcher): Matcher> { - return KFunctionMatcher(name, returnType, *parameters) -} - -fun isFunction(name: String, returnType: KClass<*>, vararg parameters: KClass<*>): Matcher> { - return isFunction(equalTo(name), matches(returnType), *parameters.toMatchers()) -} - -fun isConstructor(returnType: Matcher, vararg parameters: Matcher): Matcher> { - return KFunctionMatcher(equalTo(""), returnType, *parameters) -} - -fun isConstructor(returnType: KClass<*>, vararg parameters: KClass<*>): Matcher> { - return isConstructor(matches(returnType), *parameters.toMatchers()) -} - -fun isConstructor(returnType: String, vararg parameters: KClass<*>): Matcher> { - return isConstructor(equalTo(returnType), *parameters.toMatchers()) -} - -fun hasParam(type: Matcher): Matcher = KParameterMatcher(type) - -fun hasParam(type: KClass<*>): Matcher = hasParam(matches(type)) - -fun isProperty(name: String, type: KClass<*>): Matcher> = isProperty(equalTo(name), matches(type)) - -fun isProperty(name: Matcher, type: Matcher): Matcher> = KPropertyMatcher(name, type) - -fun isClass(name: String): Matcher> = KClassMatcher(equalTo(name)) - -fun matches(type: KClass<*>): Matcher = equalTo(type.qualifiedName) - -private fun Array>.toMatchers() = map(::hasParam).toTypedArray() - -/** - * Matcher logic for a Kotlin [KFunction] object. Also applicable to constructors. - */ -private class KFunctionMatcher( - private val name: Matcher, - private val returnType: Matcher, - vararg parameters: Matcher -) : DiagnosingMatcher>() { - private val parameters = listOf(*parameters) - - override fun describeTo(description: Description) { - description.appendText("KFunction[name as ").appendDescriptionOf(name) - .appendText(", returnType as ").appendDescriptionOf(returnType) - .appendText(", parameters as '") - if (parameters.isNotEmpty()) { - val param = parameters.iterator() - description.appendValue(param.next()) - while (param.hasNext()) { - description.appendText(",").appendValue(param.next()) - } - } - description.appendText("']") - } - - override fun matches(obj: Any?, mismatch: Description): Boolean { - if (obj == null) { - mismatch.appendText("is null") - return false - } - - val function: KFunction<*> = obj as? KFunction<*> ?: return false - if (!name.matches(function.name)) { - mismatch.appendText("name is ").appendValue(function.name) - return false - } - function.returnType.toString().apply { - if (!returnType.matches(this)) { - mismatch.appendText("returnType is ").appendValue(this) - return false - } - } - - if (function.valueParameters.size != parameters.size) { - mismatch.appendText("number of parameters is ").appendValue(function.valueParameters.size) - .appendText(", parameters=").appendValueList("[", ",", "]", function.valueParameters) - return false - } - - var i = 0 - function.valueParameters.forEach { param -> - if (!parameters[i].matches(param)) { - mismatch.appendText("parameter[").appendValue(i).appendText("] is ").appendValue(param) - return false - } - ++i - } - return true - } -} - -/** - * Matcher logic for a Kotlin [KParameter] object. - */ -private class KParameterMatcher( - private val type: Matcher -) : DiagnosingMatcher() { - override fun describeTo(description: Description) { - description.appendText("KParameter[type as ").appendDescriptionOf(type) - .appendText("]") - } - - override fun matches(obj: Any?, mismatch: Description): Boolean { - if (obj == null) { - mismatch.appendText("is null") - return false - } - - val parameter: KParameter = obj as? KParameter ?: return false - parameter.type.toString().apply { - if (!type.matches(this)) { - mismatch.appendText("type is ").appendValue(this) - return false - } - } - return true - } -} - -/** - * Matcher logic for a Kotlin [KProperty] object. - */ -private class KPropertyMatcher( - private val name: Matcher, - private val type: Matcher -) : DiagnosingMatcher>() { - override fun describeTo(description: Description) { - description.appendText("KProperty[name as ").appendDescriptionOf(name) - .appendText(", type as ").appendDescriptionOf(type) - .appendText("]") - } - - override fun matches(obj: Any?, mismatch: Description): Boolean { - if (obj == null) { - mismatch.appendText("is null") - return false - } - - val property: KProperty<*> = obj as? KProperty<*> ?: return false - if (!name.matches(property.name)) { - mismatch.appendText("name is ").appendValue(property.name) - return false - } - property.returnType.toString().apply { - if (!type.matches(this)) { - mismatch.appendText("type is ").appendValue(this) - return false - } - } - return true - } -} - -/** - * Matcher logic for a Kotlin [KClass] object. - */ -private class KClassMatcher(private val className: Matcher) : DiagnosingMatcher>() { - override fun describeTo(description: Description) { - description.appendText("KClass[name as ").appendDescriptionOf(className) - .appendText("]") - } - - override fun matches(obj: Any?, mismatch: Description): Boolean { - if (obj == null) { - mismatch.appendText("is null") - return false - } - - val type: KClass<*> = obj as? KClass<*> ?: return false - type.jvmName.apply { - if (!className.matches(this)) { - mismatch.appendText("name is ").appendValue(this) - return false - } - } - return true - } -} \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/template/PackageWithDefaultParameters.kt b/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/template/PackageWithDefaultParameters.kt deleted file mode 100644 index 186c1eb634..0000000000 --- a/buildSrc/jarfilter/src/test/kotlin/net/corda/gradle/jarfilter/template/PackageWithDefaultParameters.kt +++ /dev/null @@ -1,9 +0,0 @@ -@file:JvmName("PackageWithDefaultParameters") -@file:Suppress("UNUSED") -package net.corda.gradle.jarfilter.template - -import net.corda.gradle.jarfilter.DEFAULT_MESSAGE - -fun hasDefaultParameters(intData: Int=0, message: String=DEFAULT_MESSAGE): String = "$message: intData=$intData" - -fun hasMandatoryParameters(longData: Long=0, message: String=DEFAULT_MESSAGE): String = "$message: longData=$longData" diff --git a/buildSrc/jarfilter/src/test/resources/abstract-function/build.gradle b/buildSrc/jarfilter/src/test/resources/abstract-function/build.gradle deleted file mode 100644 index c67c80b303..0000000000 --- a/buildSrc/jarfilter/src/test/resources/abstract-function/build.gradle +++ /dev/null @@ -1,34 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/abstract-function/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' - compileOnly files('../../unwanteds/build/libs/unwanteds.jar') -} - -jar { - baseName = 'abstract-function' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forDelete = ["net.corda.gradle.jarfilter.DeleteMe"] - forStub = ["net.corda.gradle.jarfilter.StubMeOut"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/abstract-function/kotlin/net/corda/gradle/AbstractFunctions.kt b/buildSrc/jarfilter/src/test/resources/abstract-function/kotlin/net/corda/gradle/AbstractFunctions.kt deleted file mode 100644 index 8d22e90854..0000000000 --- a/buildSrc/jarfilter/src/test/resources/abstract-function/kotlin/net/corda/gradle/AbstractFunctions.kt +++ /dev/null @@ -1,13 +0,0 @@ -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe -import net.corda.gradle.jarfilter.StubMeOut - -abstract class AbstractFunctions { - @DeleteMe - abstract fun toDelete(value: Long): Long - - @StubMeOut - abstract fun toStubOut(value: Long): Long -} diff --git a/buildSrc/jarfilter/src/test/resources/annotations/kotlin/net/corda/gradle/jarfilter/DeleteMe.kt b/buildSrc/jarfilter/src/test/resources/annotations/kotlin/net/corda/gradle/jarfilter/DeleteMe.kt deleted file mode 100644 index 60ea95420b..0000000000 --- a/buildSrc/jarfilter/src/test/resources/annotations/kotlin/net/corda/gradle/jarfilter/DeleteMe.kt +++ /dev/null @@ -1,20 +0,0 @@ -package net.corda.gradle.jarfilter - -import kotlin.annotation.AnnotationRetention.* -import kotlin.annotation.AnnotationTarget.* -import kotlin.annotation.Retention -import kotlin.annotation.Target - -@Target( - FILE, - CLASS, - CONSTRUCTOR, - FUNCTION, - PROPERTY, - PROPERTY_GETTER, - PROPERTY_SETTER, - FIELD, - TYPEALIAS -) -@Retention(BINARY) -annotation class DeleteMe \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/resources/annotations/kotlin/net/corda/gradle/jarfilter/RemoveMe.kt b/buildSrc/jarfilter/src/test/resources/annotations/kotlin/net/corda/gradle/jarfilter/RemoveMe.kt deleted file mode 100644 index 5023cff43a..0000000000 --- a/buildSrc/jarfilter/src/test/resources/annotations/kotlin/net/corda/gradle/jarfilter/RemoveMe.kt +++ /dev/null @@ -1,19 +0,0 @@ -package net.corda.gradle.jarfilter - -import kotlin.annotation.AnnotationRetention.* -import kotlin.annotation.AnnotationTarget.* -import kotlin.annotation.Retention -import kotlin.annotation.Target - -@Target( - FILE, - CLASS, - CONSTRUCTOR, - FUNCTION, - PROPERTY, - PROPERTY_GETTER, - PROPERTY_SETTER, - FIELD -) -@Retention(RUNTIME) -annotation class RemoveMe diff --git a/buildSrc/jarfilter/src/test/resources/annotations/kotlin/net/corda/gradle/jarfilter/StubMeOut.kt b/buildSrc/jarfilter/src/test/resources/annotations/kotlin/net/corda/gradle/jarfilter/StubMeOut.kt deleted file mode 100644 index 5d148dcb58..0000000000 --- a/buildSrc/jarfilter/src/test/resources/annotations/kotlin/net/corda/gradle/jarfilter/StubMeOut.kt +++ /dev/null @@ -1,15 +0,0 @@ -package net.corda.gradle.jarfilter - -import kotlin.annotation.AnnotationRetention.* -import kotlin.annotation.AnnotationTarget.* -import kotlin.annotation.Retention -import kotlin.annotation.Target - -@Target( - CONSTRUCTOR, - FUNCTION, - PROPERTY_GETTER, - PROPERTY_SETTER -) -@Retention(RUNTIME) -annotation class StubMeOut \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/resources/delete-and-stub/build.gradle b/buildSrc/jarfilter/src/test/resources/delete-and-stub/build.gradle deleted file mode 100644 index 8e356b4936..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-and-stub/build.gradle +++ /dev/null @@ -1,34 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/delete-and-stub/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' - compileOnly files('../../unwanteds/build/libs/unwanteds.jar') -} - -jar { - baseName = 'delete-and-stub' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forDelete = ["net.corda.gradle.jarfilter.DeleteMe"] - forStub = ["net.corda.gradle.jarfilter.StubMeOut"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-and-stub/kotlin/net/corda/gradle/DeletePackageWithStubbed.kt b/buildSrc/jarfilter/src/test/resources/delete-and-stub/kotlin/net/corda/gradle/DeletePackageWithStubbed.kt deleted file mode 100644 index b7d4baece2..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-and-stub/kotlin/net/corda/gradle/DeletePackageWithStubbed.kt +++ /dev/null @@ -1,12 +0,0 @@ -@file:JvmName("DeletePackageWithStubbed") -@file:Suppress("UNUSED") -@file:DeleteMe -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe -import net.corda.gradle.jarfilter.StubMeOut - -fun bracket(str: String): String = "[$str]" - -@StubMeOut -fun stubbed(str: String): String = bracket(str) diff --git a/buildSrc/jarfilter/src/test/resources/delete-and-stub/kotlin/net/corda/gradle/HasDeletedInsideStubbed.kt b/buildSrc/jarfilter/src/test/resources/delete-and-stub/kotlin/net/corda/gradle/HasDeletedInsideStubbed.kt deleted file mode 100644 index 3083c2b4d8..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-and-stub/kotlin/net/corda/gradle/HasDeletedInsideStubbed.kt +++ /dev/null @@ -1,28 +0,0 @@ -@file:JvmName("HasDeletedInsideStubbed") -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe -import net.corda.gradle.jarfilter.StubMeOut -import net.corda.gradle.unwanted.HasString -import net.corda.gradle.unwanted.HasUnwantedFun -import net.corda.gradle.unwanted.HasUnwantedVal -import net.corda.gradle.unwanted.HasUnwantedVar - -class DeletedFunctionInsideStubbed(private val data: String): HasString, HasUnwantedFun { - @DeleteMe - override fun unwantedFun(str: String): String = str - - @StubMeOut - override fun stringData(): String = unwantedFun(data) -} - -class DeletedValInsideStubbed(@DeleteMe override val unwantedVal: String): HasString, HasUnwantedVal { - @StubMeOut - override fun stringData(): String = unwantedVal -} - -class DeletedVarInsideStubbed(@DeleteMe override var unwantedVar: String) : HasString, HasUnwantedVar { - @StubMeOut - override fun stringData(): String = unwantedVar -} \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/resources/delete-and-stub/kotlin/net/corda/gradle/HasPropertyForDeleteAndStub.kt b/buildSrc/jarfilter/src/test/resources/delete-and-stub/kotlin/net/corda/gradle/HasPropertyForDeleteAndStub.kt deleted file mode 100644 index c40d183929..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-and-stub/kotlin/net/corda/gradle/HasPropertyForDeleteAndStub.kt +++ /dev/null @@ -1,21 +0,0 @@ -@file:JvmName("HasPropertyForDeleteAndStub") -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe -import net.corda.gradle.jarfilter.StubMeOut -import net.corda.gradle.unwanted.* - -class HasVarPropertyForDeleteAndStub(value: Long) : HasLongVar { - @DeleteMe - @get:StubMeOut - @set:StubMeOut - override var longVar: Long = value -} - -class HasValPropertyForDeleteAndStub(str: String) : HasStringVal { - @DeleteMe - @get:StubMeOut - override val stringVal: String = str -} - diff --git a/buildSrc/jarfilter/src/test/resources/delete-constructor/build.gradle b/buildSrc/jarfilter/src/test/resources/delete-constructor/build.gradle deleted file mode 100644 index 8503573c6c..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-constructor/build.gradle +++ /dev/null @@ -1,33 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/delete-constructor/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' - compileOnly files('../../unwanteds/build/libs/unwanteds.jar') -} - -jar { - baseName = 'delete-constructor' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forDelete = ["net.corda.gradle.jarfilter.DeleteMe"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-constructor/kotlin/net/corda/gradle/HasConstructorToDelete.kt b/buildSrc/jarfilter/src/test/resources/delete-constructor/kotlin/net/corda/gradle/HasConstructorToDelete.kt deleted file mode 100644 index 6e142646d1..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-constructor/kotlin/net/corda/gradle/HasConstructorToDelete.kt +++ /dev/null @@ -1,15 +0,0 @@ -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe -import net.corda.gradle.unwanted.HasAll - -class HasConstructorToDelete(private val message: String, private val data: Long) : HasAll { - @DeleteMe constructor(message: String) : this(message, 0) - @DeleteMe constructor(data: Long) : this("", data) - constructor(data: Int) : this("", data.toLong()) - - override fun stringData(): String = message - override fun longData(): Long = data - override fun intData(): Int = data.toInt() -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-constructor/kotlin/net/corda/gradle/PrimaryConstructorsToDelete.kt b/buildSrc/jarfilter/src/test/resources/delete-constructor/kotlin/net/corda/gradle/PrimaryConstructorsToDelete.kt deleted file mode 100644 index 4be16cd208..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-constructor/kotlin/net/corda/gradle/PrimaryConstructorsToDelete.kt +++ /dev/null @@ -1,21 +0,0 @@ -@file:JvmName("PrimaryConstructorsToDelete") -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe -import net.corda.gradle.unwanted.HasInt -import net.corda.gradle.unwanted.HasLong -import net.corda.gradle.unwanted.HasString - -class PrimaryIntConstructorToDelete @DeleteMe constructor(private val value: Int) : HasInt { - override fun intData() = value -} - -class PrimaryLongConstructorToDelete @DeleteMe constructor(private val value: Long) : HasLong { - override fun longData() = value -} - -class PrimaryStringConstructorToDelete @DeleteMe constructor(private val value: String) : HasString { - override fun stringData() = value -} - diff --git a/buildSrc/jarfilter/src/test/resources/delete-extension-val/build.gradle b/buildSrc/jarfilter/src/test/resources/delete-extension-val/build.gradle deleted file mode 100644 index 2bc54db421..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-extension-val/build.gradle +++ /dev/null @@ -1,33 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/delete-extension-val/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' - compileOnly files('../../unwanteds/build/libs/unwanteds.jar') -} - -jar { - baseName = 'delete-extension-val' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forDelete = ["net.corda.gradle.jarfilter.DeleteMe"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-extension-val/kotlin/net/corda/gradle/HasValExtension.kt b/buildSrc/jarfilter/src/test/resources/delete-extension-val/kotlin/net/corda/gradle/HasValExtension.kt deleted file mode 100644 index f1219ab1ff..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-extension-val/kotlin/net/corda/gradle/HasValExtension.kt +++ /dev/null @@ -1,10 +0,0 @@ -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe -import net.corda.gradle.unwanted.HasUnwantedVal - -class HasValExtension(override val unwantedVal: String) : HasUnwantedVal { - @DeleteMe - val List.unwantedVal: String get() = this[0] -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-field/build.gradle b/buildSrc/jarfilter/src/test/resources/delete-field/build.gradle deleted file mode 100644 index 92dd13a5f2..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-field/build.gradle +++ /dev/null @@ -1,32 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/delete-field/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' -} - -jar { - baseName = 'delete-field' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forDelete = ["net.corda.gradle.jarfilter.DeleteMe"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-field/kotlin/net/corda/gradle/HasFieldToDelete.kt b/buildSrc/jarfilter/src/test/resources/delete-field/kotlin/net/corda/gradle/HasFieldToDelete.kt deleted file mode 100644 index d3127ce7d7..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-field/kotlin/net/corda/gradle/HasFieldToDelete.kt +++ /dev/null @@ -1,23 +0,0 @@ -@file:JvmName("HasFieldToDelete") -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe - -class HasStringFieldToDelete(value: String) { - @JvmField - @field:DeleteMe - val stringField: String = value -} - -class HasLongFieldToDelete(value: Long) { - @JvmField - @field:DeleteMe - val longField: Long = value -} - -class HasIntFieldToDelete(value: Int) { - @JvmField - @field:DeleteMe - val intField: Int = value -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-file-typealias/build.gradle b/buildSrc/jarfilter/src/test/resources/delete-file-typealias/build.gradle deleted file mode 100644 index f4de2588c8..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-file-typealias/build.gradle +++ /dev/null @@ -1,32 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/delete-file-typealias/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' -} - -jar { - baseName = 'delete-file-typealias' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forDelete = ["net.corda.gradle.jarfilter.DeleteMe"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-file-typealias/kotlin/net/corda/gradle/FileWithTypeAlias.kt b/buildSrc/jarfilter/src/test/resources/delete-file-typealias/kotlin/net/corda/gradle/FileWithTypeAlias.kt deleted file mode 100644 index 500e6b9be8..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-file-typealias/kotlin/net/corda/gradle/FileWithTypeAlias.kt +++ /dev/null @@ -1,12 +0,0 @@ -@file:JvmName("FileWithTypeAlias") -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe - -typealias FileWantedType = Long - -@DeleteMe -typealias FileUnwantedType = (String) -> Boolean - -val Any.FileUnwantedType: String get() = "" diff --git a/buildSrc/jarfilter/src/test/resources/delete-function/build.gradle b/buildSrc/jarfilter/src/test/resources/delete-function/build.gradle deleted file mode 100644 index 5a5de263ad..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-function/build.gradle +++ /dev/null @@ -1,33 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/delete-function/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' - compileOnly files('../../unwanteds/build/libs/unwanteds.jar') -} - -jar { - baseName = 'delete-function' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forDelete = ["net.corda.gradle.jarfilter.DeleteMe"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-function/kotlin/net/corda/gradle/HasFunctionToDelete.kt b/buildSrc/jarfilter/src/test/resources/delete-function/kotlin/net/corda/gradle/HasFunctionToDelete.kt deleted file mode 100644 index 81997e0857..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-function/kotlin/net/corda/gradle/HasFunctionToDelete.kt +++ /dev/null @@ -1,12 +0,0 @@ -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe -import net.corda.gradle.unwanted.HasUnwantedFun - -class HasFunctionToDelete : HasUnwantedFun { - @DeleteMe - override fun unwantedFun(str: String): String { - return str - } -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-function/kotlin/net/corda/gradle/HasIndirectFunctionToDelete.kt b/buildSrc/jarfilter/src/test/resources/delete-function/kotlin/net/corda/gradle/HasIndirectFunctionToDelete.kt deleted file mode 100644 index 5a85f74d8e..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-function/kotlin/net/corda/gradle/HasIndirectFunctionToDelete.kt +++ /dev/null @@ -1,13 +0,0 @@ -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe -import net.corda.gradle.unwanted.HasString -import net.corda.gradle.unwanted.HasUnwantedFun - -class HasIndirectFunctionToDelete(private val data: String) : HasUnwantedFun, HasString { - @DeleteMe - override fun unwantedFun(str: String): String = str - - override fun stringData() = unwantedFun(data) -} \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/resources/delete-inner-lambda/build.gradle b/buildSrc/jarfilter/src/test/resources/delete-inner-lambda/build.gradle deleted file mode 100644 index f5725b6e52..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-inner-lambda/build.gradle +++ /dev/null @@ -1,33 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/delete-inner-lambda/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' - compileOnly files('../../unwanteds/build/libs/unwanteds.jar') -} - -jar { - baseName = 'delete-inner-lambda' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forDelete = ["net.corda.gradle.jarfilter.DeleteMe"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-inner-lambda/kotlin/net/corda/gradle/HasInnerLambda.kt b/buildSrc/jarfilter/src/test/resources/delete-inner-lambda/kotlin/net/corda/gradle/HasInnerLambda.kt deleted file mode 100644 index 774ebb80d6..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-inner-lambda/kotlin/net/corda/gradle/HasInnerLambda.kt +++ /dev/null @@ -1,19 +0,0 @@ -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe -import net.corda.gradle.unwanted.HasInt - -class HasInnerLambda(private val bytes: ByteArray) : HasInt { - @DeleteMe - constructor(size: Int) : this(ZeroArray { size }.bytes) - - override fun intData() = bytes.size -} - -/** - * Do NOT inline this lambda! - */ -class ZeroArray(initialSize: () -> Int) { - val bytes: ByteArray = ByteArray(initialSize()) { 0 } -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-lazy/build.gradle b/buildSrc/jarfilter/src/test/resources/delete-lazy/build.gradle deleted file mode 100644 index 74de278f40..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-lazy/build.gradle +++ /dev/null @@ -1,33 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/delete-lazy/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' - compileOnly files('../../unwanteds/build/libs/unwanteds.jar') -} - -jar { - baseName = 'delete-lazy' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forDelete = ["net.corda.gradle.jarfilter.DeleteMe"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-lazy/kotlin/net/corda/gradle/HasLazy.kt b/buildSrc/jarfilter/src/test/resources/delete-lazy/kotlin/net/corda/gradle/HasLazy.kt deleted file mode 100644 index ad824cab4d..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-lazy/kotlin/net/corda/gradle/HasLazy.kt +++ /dev/null @@ -1,13 +0,0 @@ -@file:JvmName("HasLazy") -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe -import net.corda.gradle.unwanted.HasUnwantedVal - -class HasLazyVal(private val message: String) : HasUnwantedVal { - @DeleteMe - override val unwantedVal: String by lazy { - message - } -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-multifile/build.gradle b/buildSrc/jarfilter/src/test/resources/delete-multifile/build.gradle deleted file mode 100644 index 417c8d97fe..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-multifile/build.gradle +++ /dev/null @@ -1,32 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/delete-multifile/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' -} - -jar { - baseName = 'delete-multifile' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forDelete = ["net.corda.gradle.jarfilter.DeleteMe"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-multifile/kotlin/net/corda/gradle/HasInt.kt b/buildSrc/jarfilter/src/test/resources/delete-multifile/kotlin/net/corda/gradle/HasInt.kt deleted file mode 100644 index 0c4507d568..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-multifile/kotlin/net/corda/gradle/HasInt.kt +++ /dev/null @@ -1,9 +0,0 @@ -@file:JvmName("HasMultiData") -@file:JvmMultifileClass -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe - -@DeleteMe -fun intToDelete(data: Int): Int = data diff --git a/buildSrc/jarfilter/src/test/resources/delete-multifile/kotlin/net/corda/gradle/HasLong.kt b/buildSrc/jarfilter/src/test/resources/delete-multifile/kotlin/net/corda/gradle/HasLong.kt deleted file mode 100644 index c4c6617e33..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-multifile/kotlin/net/corda/gradle/HasLong.kt +++ /dev/null @@ -1,9 +0,0 @@ -@file:JvmName("HasMultiData") -@file:JvmMultifileClass -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe - -@DeleteMe -fun longToDelete(data: Long): Long = data diff --git a/buildSrc/jarfilter/src/test/resources/delete-multifile/kotlin/net/corda/gradle/HasString.kt b/buildSrc/jarfilter/src/test/resources/delete-multifile/kotlin/net/corda/gradle/HasString.kt deleted file mode 100644 index 3fe9965c2f..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-multifile/kotlin/net/corda/gradle/HasString.kt +++ /dev/null @@ -1,9 +0,0 @@ -@file:JvmName("HasMultiData") -@file:JvmMultifileClass -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe - -@DeleteMe -fun stringToDelete(str: String): String = str diff --git a/buildSrc/jarfilter/src/test/resources/delete-nested-class/build.gradle b/buildSrc/jarfilter/src/test/resources/delete-nested-class/build.gradle deleted file mode 100644 index 9a74a8e3c3..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-nested-class/build.gradle +++ /dev/null @@ -1,32 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/delete-nested-class/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' -} - -jar { - baseName = 'delete-nested-class' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forDelete = ["net.corda.gradle.jarfilter.DeleteMe"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-nested-class/kotlin/net/corda/gradle/HasNestedClasses.kt b/buildSrc/jarfilter/src/test/resources/delete-nested-class/kotlin/net/corda/gradle/HasNestedClasses.kt deleted file mode 100644 index a8f8a2f2f4..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-nested-class/kotlin/net/corda/gradle/HasNestedClasses.kt +++ /dev/null @@ -1,10 +0,0 @@ -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe - -class HasNestedClasses { - class OneToKeep - - @DeleteMe class OneToThrowAway -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-nested-class/kotlin/net/corda/gradle/SealedClass.kt b/buildSrc/jarfilter/src/test/resources/delete-nested-class/kotlin/net/corda/gradle/SealedClass.kt deleted file mode 100644 index 1e85d6564c..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-nested-class/kotlin/net/corda/gradle/SealedClass.kt +++ /dev/null @@ -1,10 +0,0 @@ -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe - -sealed class SealedClass { - class Wanted : SealedClass() - - @DeleteMe class Unwanted : SealedClass() -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-object/build.gradle b/buildSrc/jarfilter/src/test/resources/delete-object/build.gradle deleted file mode 100644 index 9958740aad..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-object/build.gradle +++ /dev/null @@ -1,33 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/delete-object/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' - compileOnly files('../../unwanteds/build/libs/unwanteds.jar') -} - -jar { - baseName = 'delete-object' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forDelete = ["net.corda.gradle.jarfilter.DeleteMe"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-object/kotlin/net/corda/gradle/HasObjects.kt b/buildSrc/jarfilter/src/test/resources/delete-object/kotlin/net/corda/gradle/HasObjects.kt deleted file mode 100644 index 03ec14bcb4..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-object/kotlin/net/corda/gradle/HasObjects.kt +++ /dev/null @@ -1,20 +0,0 @@ -@file:JvmName("HasObjects") -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe -import net.corda.gradle.unwanted.HasUnwantedFun -import net.corda.gradle.unwanted.HasUnwantedVal - -@DeleteMe -val unwantedObj = object : HasUnwantedFun { - override fun unwantedFun(str: String): String = str -} - -@DeleteMe -fun unwantedFun(): String { - val obj = object : HasUnwantedVal { - override val unwantedVal: String = "" - } - return obj.unwantedVal -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-sealed-subclass/build.gradle b/buildSrc/jarfilter/src/test/resources/delete-sealed-subclass/build.gradle deleted file mode 100644 index 38c76d6f7c..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-sealed-subclass/build.gradle +++ /dev/null @@ -1,33 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/delete-sealed-subclass/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' - compileOnly files('../../unwanteds/build/libs/unwanteds.jar') -} - -jar { - baseName = 'delete-sealed-subclass' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forDelete = ["net.corda.gradle.jarfilter.DeleteMe"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-sealed-subclass/kotlin/net/corda/gradle/SealedWithSubclasses.kt b/buildSrc/jarfilter/src/test/resources/delete-sealed-subclass/kotlin/net/corda/gradle/SealedWithSubclasses.kt deleted file mode 100644 index 52e28a4475..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-sealed-subclass/kotlin/net/corda/gradle/SealedWithSubclasses.kt +++ /dev/null @@ -1,12 +0,0 @@ -@file:JvmName("SealedWithSubclasses") -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe - -sealed class SealedBaseClass - -@DeleteMe -class UnwantedSubclass : SealedBaseClass() - -class WantedSubclass : SealedBaseClass() diff --git a/buildSrc/jarfilter/src/test/resources/delete-static-field/build.gradle b/buildSrc/jarfilter/src/test/resources/delete-static-field/build.gradle deleted file mode 100644 index 18040b9954..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-static-field/build.gradle +++ /dev/null @@ -1,32 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/delete-static-field/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' -} - -jar { - baseName = 'delete-static-field' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forDelete = ["net.corda.gradle.jarfilter.DeleteMe"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-static-field/kotlin/net/corda/gradle/StaticFieldsToDelete.kt b/buildSrc/jarfilter/src/test/resources/delete-static-field/kotlin/net/corda/gradle/StaticFieldsToDelete.kt deleted file mode 100644 index a16350d5d4..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-static-field/kotlin/net/corda/gradle/StaticFieldsToDelete.kt +++ /dev/null @@ -1,17 +0,0 @@ -@file:JvmName("StaticFieldsToDelete") -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe - -@DeleteMe -@JvmField -val stringField: String = "" - -@DeleteMe -@JvmField -val longField: Long = 123456789L - -@DeleteMe -@JvmField -val intField: Int = 123456 diff --git a/buildSrc/jarfilter/src/test/resources/delete-static-function/build.gradle b/buildSrc/jarfilter/src/test/resources/delete-static-function/build.gradle deleted file mode 100644 index b2308fad37..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-static-function/build.gradle +++ /dev/null @@ -1,33 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/delete-static-function/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' - compileOnly files('../../unwanteds/build/libs/unwanteds.jar') -} - -jar { - baseName = 'delete-static-function' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forDelete = ["net.corda.gradle.jarfilter.DeleteMe"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-static-function/kotlin/net/corda/gradle/StaticFunctionsToDelete.kt b/buildSrc/jarfilter/src/test/resources/delete-static-function/kotlin/net/corda/gradle/StaticFunctionsToDelete.kt deleted file mode 100644 index a9144140c0..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-static-function/kotlin/net/corda/gradle/StaticFunctionsToDelete.kt +++ /dev/null @@ -1,14 +0,0 @@ -@file:JvmName("StaticFunctionsToDelete") -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe - -@DeleteMe -fun unwantedStringToDelete(value: String): String = value - -@DeleteMe -fun unwantedIntToDelete(value: Int): Int = value - -@DeleteMe -fun unwantedLongToDelete(value: Long): Long = value diff --git a/buildSrc/jarfilter/src/test/resources/delete-static-val/build.gradle b/buildSrc/jarfilter/src/test/resources/delete-static-val/build.gradle deleted file mode 100644 index a67c4f7760..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-static-val/build.gradle +++ /dev/null @@ -1,32 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/delete-static-val/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' -} - -jar { - baseName = 'delete-static-val' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forDelete = ["net.corda.gradle.jarfilter.DeleteMe"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-static-val/kotlin/net/corda/gradle/StaticValToDelete.kt b/buildSrc/jarfilter/src/test/resources/delete-static-val/kotlin/net/corda/gradle/StaticValToDelete.kt deleted file mode 100644 index 51de79e5c5..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-static-val/kotlin/net/corda/gradle/StaticValToDelete.kt +++ /dev/null @@ -1,17 +0,0 @@ -@file:JvmName("StaticValToDelete") -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe - -@DeleteMe -val stringVal: String = "" - -@DeleteMe -val longVal: Long = 123456789L - -@DeleteMe -val intVal: Int = 123456 - -@DeleteMe -val T.memberVal: T get() = this diff --git a/buildSrc/jarfilter/src/test/resources/delete-static-var/build.gradle b/buildSrc/jarfilter/src/test/resources/delete-static-var/build.gradle deleted file mode 100644 index 2d601a37c4..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-static-var/build.gradle +++ /dev/null @@ -1,32 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/delete-static-var/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' -} - -jar { - baseName = 'delete-static-var' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forDelete = ["net.corda.gradle.jarfilter.DeleteMe"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-static-var/kotlin/net/corda/gradle/StaticVarToDelete.kt b/buildSrc/jarfilter/src/test/resources/delete-static-var/kotlin/net/corda/gradle/StaticVarToDelete.kt deleted file mode 100644 index 1b941b8fff..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-static-var/kotlin/net/corda/gradle/StaticVarToDelete.kt +++ /dev/null @@ -1,19 +0,0 @@ -@file:JvmName("StaticVarToDelete") -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe - -@DeleteMe -var stringVar: String = "" - -@DeleteMe -var longVar: Long = 123456789L - -@DeleteMe -var intVar: Int = 123456 - -@DeleteMe -var T.memberVar: T - get() = this - set(value) { } diff --git a/buildSrc/jarfilter/src/test/resources/delete-val-property/build.gradle b/buildSrc/jarfilter/src/test/resources/delete-val-property/build.gradle deleted file mode 100644 index 3d6f3d4224..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-val-property/build.gradle +++ /dev/null @@ -1,33 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/delete-val-property/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' - compileOnly files('../../unwanteds/build/libs/unwanteds.jar') -} - -jar { - baseName = 'delete-val-property' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forDelete = ["net.corda.gradle.jarfilter.DeleteMe"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-val-property/kotlin/net/corda/gradle/HasValPropertyForDelete.kt b/buildSrc/jarfilter/src/test/resources/delete-val-property/kotlin/net/corda/gradle/HasValPropertyForDelete.kt deleted file mode 100644 index 26f9ebfad3..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-val-property/kotlin/net/corda/gradle/HasValPropertyForDelete.kt +++ /dev/null @@ -1,11 +0,0 @@ -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe -import net.corda.gradle.unwanted.HasUnwantedVal - -class HasValPropertyForDelete(@DeleteMe override val unwantedVal: String) : HasUnwantedVal - -class HasValGetterForDelete(@get:DeleteMe override val unwantedVal: String): HasUnwantedVal - -class HasValJvmFieldForDelete(@DeleteMe @JvmField val unwantedVal: String) \ No newline at end of file diff --git a/buildSrc/jarfilter/src/test/resources/delete-var-property/build.gradle b/buildSrc/jarfilter/src/test/resources/delete-var-property/build.gradle deleted file mode 100644 index dfc29b78b6..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-var-property/build.gradle +++ /dev/null @@ -1,33 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/delete-var-property/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' - compileOnly files('../../unwanteds/build/libs/unwanteds.jar') -} - -jar { - baseName = 'delete-var-property' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forDelete = ["net.corda.gradle.jarfilter.DeleteMe"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/delete-var-property/kotlin/net/corda/gradle/HasVarPropertyForDelete.kt b/buildSrc/jarfilter/src/test/resources/delete-var-property/kotlin/net/corda/gradle/HasVarPropertyForDelete.kt deleted file mode 100644 index 4726ef9e3a..0000000000 --- a/buildSrc/jarfilter/src/test/resources/delete-var-property/kotlin/net/corda/gradle/HasVarPropertyForDelete.kt +++ /dev/null @@ -1,14 +0,0 @@ -@file:JvmName("HasVarPropertyForDelete") -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe -import net.corda.gradle.unwanted.HasUnwantedVar - -class HasUnwantedVarPropertyForDelete(@DeleteMe override var unwantedVar: String) : HasUnwantedVar - -class HasUnwantedGetForDelete(@get:DeleteMe override var unwantedVar: String) : HasUnwantedVar - -class HasUnwantedSetForDelete(@set:DeleteMe override var unwantedVar: String) : HasUnwantedVar - -class HasVarJvmFieldForDelete(@DeleteMe @JvmField var unwantedVar: String) diff --git a/buildSrc/jarfilter/src/test/resources/gradle.properties b/buildSrc/jarfilter/src/test/resources/gradle.properties deleted file mode 100644 index 0c744a8a05..0000000000 --- a/buildSrc/jarfilter/src/test/resources/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -org.gradle.jvmargs=-javaagent:"$jacocoAgent"=destfile="$buildDir/jacoco/test.exec",includes=net/corda/gradle/jarfilter/** diff --git a/buildSrc/jarfilter/src/test/resources/interface-function/build.gradle b/buildSrc/jarfilter/src/test/resources/interface-function/build.gradle deleted file mode 100644 index dbea447e6b..0000000000 --- a/buildSrc/jarfilter/src/test/resources/interface-function/build.gradle +++ /dev/null @@ -1,34 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/interface-function/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' - compileOnly files('../../unwanteds/build/libs/unwanteds.jar') -} - -jar { - baseName = 'interface-function' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forDelete = ["net.corda.gradle.jarfilter.DeleteMe"] - forStub = ["net.corda.gradle.jarfilter.StubMeOut"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/interface-function/kotlin/net/corda/gradle/InterfaceFunctions.kt b/buildSrc/jarfilter/src/test/resources/interface-function/kotlin/net/corda/gradle/InterfaceFunctions.kt deleted file mode 100644 index cbc782794a..0000000000 --- a/buildSrc/jarfilter/src/test/resources/interface-function/kotlin/net/corda/gradle/InterfaceFunctions.kt +++ /dev/null @@ -1,13 +0,0 @@ -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe -import net.corda.gradle.jarfilter.StubMeOut - -interface InterfaceFunctions { - @DeleteMe - fun toDelete(value: Long): Long - - @StubMeOut - fun toStubOut(value: Long): Long -} diff --git a/buildSrc/jarfilter/src/test/resources/remove-annotations/build.gradle b/buildSrc/jarfilter/src/test/resources/remove-annotations/build.gradle deleted file mode 100644 index e477038ce9..0000000000 --- a/buildSrc/jarfilter/src/test/resources/remove-annotations/build.gradle +++ /dev/null @@ -1,33 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/remove-annotations/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' - compileOnly files('../../unwanteds/build/libs/unwanteds.jar') -} - -jar { - baseName = 'remove-annotations' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forRemove = ["net.corda.gradle.jarfilter.RemoveMe"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/remove-annotations/kotlin/net/corda/gradle/HasUnwantedAnnotations.kt b/buildSrc/jarfilter/src/test/resources/remove-annotations/kotlin/net/corda/gradle/HasUnwantedAnnotations.kt deleted file mode 100644 index e0732943ee..0000000000 --- a/buildSrc/jarfilter/src/test/resources/remove-annotations/kotlin/net/corda/gradle/HasUnwantedAnnotations.kt +++ /dev/null @@ -1,33 +0,0 @@ -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.RemoveMe -import net.corda.gradle.unwanted.HasUnwantedFun -import net.corda.gradle.unwanted.HasUnwantedVal -import net.corda.gradle.unwanted.HasUnwantedVar - -@RemoveMe -class HasUnwantedAnnotations @RemoveMe constructor( - longValue: Long, message: String -) : HasUnwantedVar, HasUnwantedVal, HasUnwantedFun { - @RemoveMe - constructor() : this(999L, "") - - @field:RemoveMe - @JvmField - val longField: Long = longValue - - @get:RemoveMe - @property:RemoveMe - override val unwantedVal: String = message - - @get:RemoveMe - @set:RemoveMe - @property:RemoveMe - override var unwantedVar: String = message - - @RemoveMe - override fun unwantedFun(str: String): String { - return "[$str]" - } -} diff --git a/buildSrc/jarfilter/src/test/resources/repositories.gradle b/buildSrc/jarfilter/src/test/resources/repositories.gradle deleted file mode 100644 index 2a25f5bbd4..0000000000 --- a/buildSrc/jarfilter/src/test/resources/repositories.gradle +++ /dev/null @@ -1,4 +0,0 @@ -repositories { - mavenLocal() - jcenter() -} diff --git a/buildSrc/jarfilter/src/test/resources/sanitise-delete-constructor/build.gradle b/buildSrc/jarfilter/src/test/resources/sanitise-delete-constructor/build.gradle deleted file mode 100644 index 6fc9780cf8..0000000000 --- a/buildSrc/jarfilter/src/test/resources/sanitise-delete-constructor/build.gradle +++ /dev/null @@ -1,34 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/sanitise-delete-constructor/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' - compileOnly files('../../unwanteds/build/libs/unwanteds.jar') -} - -jar { - baseName = 'sanitise-delete-constructor' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forDelete = ["net.corda.gradle.jarfilter.DeleteMe"] - forSanitise = ["net.corda.gradle.jarfilter.DeleteMe"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/sanitise-delete-constructor/kotlin/net/corda/gradle/HasOverloadedConstructorsToDelete.kt b/buildSrc/jarfilter/src/test/resources/sanitise-delete-constructor/kotlin/net/corda/gradle/HasOverloadedConstructorsToDelete.kt deleted file mode 100644 index b5b257ab99..0000000000 --- a/buildSrc/jarfilter/src/test/resources/sanitise-delete-constructor/kotlin/net/corda/gradle/HasOverloadedConstructorsToDelete.kt +++ /dev/null @@ -1,48 +0,0 @@ -@file:JvmName("HasOverloadedConstructorsToDelete") -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.DeleteMe -import net.corda.gradle.unwanted.* - -private const val DEFAULT_MESSAGE = "" - -class HasOverloadedStringConstructorToDelete @JvmOverloads @DeleteMe constructor(private val message: String = DEFAULT_MESSAGE) : HasString { - override fun stringData(): String = message -} - -class HasOverloadedLongConstructorToDelete @JvmOverloads @DeleteMe constructor(private val data: Long = 0) : HasLong { - override fun longData(): Long = data -} - -class HasOverloadedIntConstructorToDelete @JvmOverloads @DeleteMe constructor(private val data: Int = 0) : HasInt { - override fun intData(): Int = data -} - -/** - * This case is complex because: - * - The primary constructor has two parameters. - * - The first constructor parameter has a default value. - * - The second constructor parameter is mandatory. - */ -class HasOverloadedComplexConstructorToDelete @JvmOverloads @DeleteMe constructor(private val data: Int = 0, private val message: String) - : HasInt, HasString -{ - override fun stringData(): String = message - override fun intData(): Int = data -} - -class HasMultipleStringConstructorsToDelete(private val message: String) : HasString { - @DeleteMe constructor() : this(DEFAULT_MESSAGE) - override fun stringData(): String = message -} - -class HasMultipleLongConstructorsToDelete(private val data: Long) : HasLong { - @DeleteMe constructor() : this(0) - override fun longData(): Long = data -} - -class HasMultipleIntConstructorsToDelete(private val data: Int) : HasInt { - @DeleteMe constructor() : this(0) - override fun intData(): Int = data -} diff --git a/buildSrc/jarfilter/src/test/resources/sanitise-stub-constructor/build.gradle b/buildSrc/jarfilter/src/test/resources/sanitise-stub-constructor/build.gradle deleted file mode 100644 index 0eef51c207..0000000000 --- a/buildSrc/jarfilter/src/test/resources/sanitise-stub-constructor/build.gradle +++ /dev/null @@ -1,34 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/sanitise-stub-constructor/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' - compileOnly files('../../unwanteds/build/libs/unwanteds.jar') -} - -jar { - baseName = 'sanitise-stub-constructor' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forStub = ["net.corda.gradle.jarfilter.StubMeOut"] - forSanitise = ["net.corda.gradle.jarfilter.StubMeOut"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/sanitise-stub-constructor/kotlin/net/corda/gradle/HasOverloadedConstructorsToStub.kt b/buildSrc/jarfilter/src/test/resources/sanitise-stub-constructor/kotlin/net/corda/gradle/HasOverloadedConstructorsToStub.kt deleted file mode 100644 index 47e4882957..0000000000 --- a/buildSrc/jarfilter/src/test/resources/sanitise-stub-constructor/kotlin/net/corda/gradle/HasOverloadedConstructorsToStub.kt +++ /dev/null @@ -1,48 +0,0 @@ -@file:JvmName("HasOverloadedConstructorsToStub") -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.StubMeOut -import net.corda.gradle.unwanted.* - -private const val DEFAULT_MESSAGE = "" - -class HasOverloadedStringConstructorToStub @JvmOverloads @StubMeOut constructor(private val message: String = DEFAULT_MESSAGE) : HasString { - override fun stringData(): String = message -} - -class HasOverloadedLongConstructorToStub @JvmOverloads @StubMeOut constructor(private val data: Long = 0) : HasLong { - override fun longData(): Long = data -} - -class HasOverloadedIntConstructorToStub @JvmOverloads @StubMeOut constructor(private val data: Int = 0) : HasInt { - override fun intData(): Int = data -} - -/** - * This case is complex because: - * - The primary constructor has two parameters. - * - The first constructor parameter has a default value. - * - The second constructor parameter is mandatory. - */ -class HasOverloadedComplexConstructorToStub @JvmOverloads @StubMeOut constructor(private val data: Int = 0, private val message: String) - : HasInt, HasString -{ - override fun stringData(): String = message - override fun intData(): Int = data -} - -class HasMultipleStringConstructorsToStub(private val message: String) : HasString { - @StubMeOut constructor() : this(DEFAULT_MESSAGE) - override fun stringData(): String = message -} - -class HasMultipleLongConstructorsToStub(private val data: Long) : HasLong { - @StubMeOut constructor() : this(0) - override fun longData(): Long = data -} - -class HasMultipleIntConstructorsToStub(private val data: Int) : HasInt { - @StubMeOut constructor() : this(0) - override fun intData(): Int = data -} diff --git a/buildSrc/jarfilter/src/test/resources/settings.gradle b/buildSrc/jarfilter/src/test/resources/settings.gradle deleted file mode 100644 index 7e0a88c8e3..0000000000 --- a/buildSrc/jarfilter/src/test/resources/settings.gradle +++ /dev/null @@ -1,6 +0,0 @@ -// Common settings for all Gradle test projects. -pluginManagement { - repositories { - gradlePluginPortal() - } -} diff --git a/buildSrc/jarfilter/src/test/resources/stub-constructor/build.gradle b/buildSrc/jarfilter/src/test/resources/stub-constructor/build.gradle deleted file mode 100644 index 857ce08d50..0000000000 --- a/buildSrc/jarfilter/src/test/resources/stub-constructor/build.gradle +++ /dev/null @@ -1,33 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/stub-constructor/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' - compileOnly files('../../unwanteds/build/libs/unwanteds.jar') -} - -jar { - baseName = 'stub-constructor' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forStub = ["net.corda.gradle.jarfilter.StubMeOut"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/stub-constructor/kotlin/net/corda/gradle/HasConstructorToStub.kt b/buildSrc/jarfilter/src/test/resources/stub-constructor/kotlin/net/corda/gradle/HasConstructorToStub.kt deleted file mode 100644 index 5683a97243..0000000000 --- a/buildSrc/jarfilter/src/test/resources/stub-constructor/kotlin/net/corda/gradle/HasConstructorToStub.kt +++ /dev/null @@ -1,15 +0,0 @@ -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.StubMeOut -import net.corda.gradle.unwanted.HasAll - -class HasConstructorToStub(private val message: String, private val data: Long) : HasAll { - @StubMeOut constructor(message: String) : this(message, 0) - @StubMeOut constructor(data: Long) : this("", data) - constructor(data: Int) : this("", data.toLong()) - - override fun stringData(): String = message - override fun longData(): Long = data - override fun intData(): Int = data.toInt() -} diff --git a/buildSrc/jarfilter/src/test/resources/stub-constructor/kotlin/net/corda/gradle/PrimaryConstructorsToStub.kt b/buildSrc/jarfilter/src/test/resources/stub-constructor/kotlin/net/corda/gradle/PrimaryConstructorsToStub.kt deleted file mode 100644 index 1e25467643..0000000000 --- a/buildSrc/jarfilter/src/test/resources/stub-constructor/kotlin/net/corda/gradle/PrimaryConstructorsToStub.kt +++ /dev/null @@ -1,21 +0,0 @@ -@file:JvmName("PrimaryConstructorsToStub") -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.StubMeOut -import net.corda.gradle.unwanted.HasInt -import net.corda.gradle.unwanted.HasLong -import net.corda.gradle.unwanted.HasString - -class PrimaryIntConstructorToStub @StubMeOut constructor(private val value: Int) : HasInt { - override fun intData() = value -} - -class PrimaryLongConstructorToStub @StubMeOut constructor(private val value: Long) : HasLong { - override fun longData() = value -} - -class PrimaryStringConstructorToStub @StubMeOut constructor(private val value: String) : HasString { - override fun stringData() = value -} - diff --git a/buildSrc/jarfilter/src/test/resources/stub-function/build.gradle b/buildSrc/jarfilter/src/test/resources/stub-function/build.gradle deleted file mode 100644 index 98a3d6275a..0000000000 --- a/buildSrc/jarfilter/src/test/resources/stub-function/build.gradle +++ /dev/null @@ -1,33 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/stub-function/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' - compileOnly files('../../unwanteds/build/libs/unwanteds.jar') -} - -jar { - baseName = 'stub-function' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forStub = ["net.corda.gradle.jarfilter.StubMeOut"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/stub-function/kotlin/net/corda/gradle/HasFunctionToStub.kt b/buildSrc/jarfilter/src/test/resources/stub-function/kotlin/net/corda/gradle/HasFunctionToStub.kt deleted file mode 100644 index 32c3a17533..0000000000 --- a/buildSrc/jarfilter/src/test/resources/stub-function/kotlin/net/corda/gradle/HasFunctionToStub.kt +++ /dev/null @@ -1,14 +0,0 @@ -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.StubMeOut -import net.corda.gradle.unwanted.HasUnwantedFun -import javax.annotation.Resource - -class HasFunctionToStub : HasUnwantedFun { - @StubMeOut - @Resource - override fun unwantedFun(@Parameter str: String): String { - return str - } -} diff --git a/buildSrc/jarfilter/src/test/resources/stub-function/kotlin/net/corda/gradle/RuntimeAnnotations.kt b/buildSrc/jarfilter/src/test/resources/stub-function/kotlin/net/corda/gradle/RuntimeAnnotations.kt deleted file mode 100644 index ef1e66b89b..0000000000 --- a/buildSrc/jarfilter/src/test/resources/stub-function/kotlin/net/corda/gradle/RuntimeAnnotations.kt +++ /dev/null @@ -1,11 +0,0 @@ -@file:JvmName("RuntimeAnnotations") -package net.corda.gradle - -import kotlin.annotation.AnnotationRetention.* -import kotlin.annotation.AnnotationTarget.* -import kotlin.annotation.Retention -import kotlin.annotation.Target - -@Target(VALUE_PARAMETER) -@Retention(RUNTIME) -annotation class Parameter diff --git a/buildSrc/jarfilter/src/test/resources/stub-static-function/build.gradle b/buildSrc/jarfilter/src/test/resources/stub-static-function/build.gradle deleted file mode 100644 index 75eb1e2cfe..0000000000 --- a/buildSrc/jarfilter/src/test/resources/stub-static-function/build.gradle +++ /dev/null @@ -1,33 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/stub-static-function/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' - compileOnly files('../../unwanteds/build/libs/unwanteds.jar') -} - -jar { - baseName = 'stub-static-function' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forStub = ["net.corda.gradle.jarfilter.StubMeOut"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/stub-static-function/kotlin/net/corda/gradle/StaticFunctionsToStub.kt b/buildSrc/jarfilter/src/test/resources/stub-static-function/kotlin/net/corda/gradle/StaticFunctionsToStub.kt deleted file mode 100644 index ffeece6a04..0000000000 --- a/buildSrc/jarfilter/src/test/resources/stub-static-function/kotlin/net/corda/gradle/StaticFunctionsToStub.kt +++ /dev/null @@ -1,22 +0,0 @@ -@file:JvmName("StaticFunctionsToStub") -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.StubMeOut - -@StubMeOut -fun unwantedStringToStub(value: String): String = value - -@StubMeOut -fun unwantedIntToStub(value: Int): Int = value - -@StubMeOut -fun unwantedLongToStub(value: Long): Long = value - -private var seed: Int = 0 -val staticSeed: Int get() = seed - -@StubMeOut -fun unwantedVoidToStub() { - ++seed -} diff --git a/buildSrc/jarfilter/src/test/resources/stub-val-property/build.gradle b/buildSrc/jarfilter/src/test/resources/stub-val-property/build.gradle deleted file mode 100644 index e92e2b68c0..0000000000 --- a/buildSrc/jarfilter/src/test/resources/stub-val-property/build.gradle +++ /dev/null @@ -1,33 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/stub-val-property/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' - compileOnly files('../../unwanteds/build/libs/unwanteds.jar') -} - -jar { - baseName = 'stub-val-property' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forStub = ["net.corda.gradle.jarfilter.StubMeOut"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/stub-val-property/kotlin/net/corda/gradle/HasValPropertyForStub.kt b/buildSrc/jarfilter/src/test/resources/stub-val-property/kotlin/net/corda/gradle/HasValPropertyForStub.kt deleted file mode 100644 index b9a6c042b4..0000000000 --- a/buildSrc/jarfilter/src/test/resources/stub-val-property/kotlin/net/corda/gradle/HasValPropertyForStub.kt +++ /dev/null @@ -1,7 +0,0 @@ -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.StubMeOut -import net.corda.gradle.unwanted.HasUnwantedVal - -class HasValPropertyForStub(@get:StubMeOut override val unwantedVal: String) : HasUnwantedVal diff --git a/buildSrc/jarfilter/src/test/resources/stub-var-property/build.gradle b/buildSrc/jarfilter/src/test/resources/stub-var-property/build.gradle deleted file mode 100644 index d02be34534..0000000000 --- a/buildSrc/jarfilter/src/test/resources/stub-var-property/build.gradle +++ /dev/null @@ -1,33 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '$kotlin_version' - id 'net.corda.plugins.jar-filter' -} -apply from: 'repositories.gradle' - -sourceSets { - main { - kotlin { - srcDir files( - '../resources/test/stub-var-property/kotlin', - '../resources/test/annotations/kotlin' - ) - } - } -} - -dependencies { - compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' - compileOnly files('../../unwanteds/build/libs/unwanteds.jar') -} - -jar { - baseName = 'stub-var-property' -} - -import net.corda.gradle.jarfilter.JarFilterTask -task jarFilter(type: JarFilterTask) { - jars jar - annotations { - forStub = ["net.corda.gradle.jarfilter.StubMeOut"] - } -} diff --git a/buildSrc/jarfilter/src/test/resources/stub-var-property/kotlin/net/corda/gradle/HasVarPropertyForStub.kt b/buildSrc/jarfilter/src/test/resources/stub-var-property/kotlin/net/corda/gradle/HasVarPropertyForStub.kt deleted file mode 100644 index 8f346142b0..0000000000 --- a/buildSrc/jarfilter/src/test/resources/stub-var-property/kotlin/net/corda/gradle/HasVarPropertyForStub.kt +++ /dev/null @@ -1,10 +0,0 @@ -@file:JvmName("HasVarPropertyForStub") -@file:Suppress("UNUSED") -package net.corda.gradle - -import net.corda.gradle.jarfilter.StubMeOut -import net.corda.gradle.unwanted.HasUnwantedVar - -class HasUnwantedGetForStub(@get:StubMeOut override var unwantedVar: String) : HasUnwantedVar - -class HasUnwantedSetForStub(@set:StubMeOut override var unwantedVar: String) : HasUnwantedVar \ No newline at end of file diff --git a/buildSrc/jarfilter/unwanteds/build.gradle b/buildSrc/jarfilter/unwanteds/build.gradle deleted file mode 100644 index 0f2deeb1c6..0000000000 --- a/buildSrc/jarfilter/unwanteds/build.gradle +++ /dev/null @@ -1,12 +0,0 @@ -apply plugin: 'kotlin' - -description 'Test artifacts for the jar-filter plugin.' - -repositories { - mavenLocal() - jcenter() -} - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" -} diff --git a/buildSrc/jarfilter/unwanteds/src/main/kotlin/net/corda/gradle/unwanted/HasData.kt b/buildSrc/jarfilter/unwanteds/src/main/kotlin/net/corda/gradle/unwanted/HasData.kt deleted file mode 100644 index 87e52bbbf7..0000000000 --- a/buildSrc/jarfilter/unwanteds/src/main/kotlin/net/corda/gradle/unwanted/HasData.kt +++ /dev/null @@ -1,16 +0,0 @@ -@file:JvmName("HasData") -package net.corda.gradle.unwanted - -interface HasString { - fun stringData(): String -} - -interface HasLong { - fun longData(): Long -} - -interface HasInt { - fun intData(): Int -} - -interface HasAll : HasInt, HasLong, HasString \ No newline at end of file diff --git a/buildSrc/jarfilter/unwanteds/src/main/kotlin/net/corda/gradle/unwanted/HasUnwantedFun.kt b/buildSrc/jarfilter/unwanteds/src/main/kotlin/net/corda/gradle/unwanted/HasUnwantedFun.kt deleted file mode 100644 index f66b53c8b7..0000000000 --- a/buildSrc/jarfilter/unwanteds/src/main/kotlin/net/corda/gradle/unwanted/HasUnwantedFun.kt +++ /dev/null @@ -1,5 +0,0 @@ -package net.corda.gradle.unwanted - -interface HasUnwantedFun { - fun unwantedFun(str: String): String -} diff --git a/buildSrc/jarfilter/unwanteds/src/main/kotlin/net/corda/gradle/unwanted/HasUnwantedVal.kt b/buildSrc/jarfilter/unwanteds/src/main/kotlin/net/corda/gradle/unwanted/HasUnwantedVal.kt deleted file mode 100644 index b19d043345..0000000000 --- a/buildSrc/jarfilter/unwanteds/src/main/kotlin/net/corda/gradle/unwanted/HasUnwantedVal.kt +++ /dev/null @@ -1,5 +0,0 @@ -package net.corda.gradle.unwanted - -interface HasUnwantedVal { - val unwantedVal: String -} diff --git a/buildSrc/jarfilter/unwanteds/src/main/kotlin/net/corda/gradle/unwanted/HasUnwantedVar.kt b/buildSrc/jarfilter/unwanteds/src/main/kotlin/net/corda/gradle/unwanted/HasUnwantedVar.kt deleted file mode 100644 index 7406028cb8..0000000000 --- a/buildSrc/jarfilter/unwanteds/src/main/kotlin/net/corda/gradle/unwanted/HasUnwantedVar.kt +++ /dev/null @@ -1,5 +0,0 @@ -package net.corda.gradle.unwanted - -interface HasUnwantedVar { - var unwantedVar: String -} diff --git a/buildSrc/jarfilter/unwanteds/src/main/kotlin/net/corda/gradle/unwanted/HasVal.kt b/buildSrc/jarfilter/unwanteds/src/main/kotlin/net/corda/gradle/unwanted/HasVal.kt deleted file mode 100644 index 7aeb75ca35..0000000000 --- a/buildSrc/jarfilter/unwanteds/src/main/kotlin/net/corda/gradle/unwanted/HasVal.kt +++ /dev/null @@ -1,17 +0,0 @@ -@file:JvmName("HasVal") -@file:Suppress("UNUSED") -package net.corda.gradle.unwanted - -interface HasStringVal { - val stringVal: String -} - -interface HasLongVal { - val longVal: Long -} - -interface HasIntVal { - val intVal: Int -} - -interface HasAllVal : HasIntVal, HasLongVal, HasStringVal \ No newline at end of file diff --git a/buildSrc/jarfilter/unwanteds/src/main/kotlin/net/corda/gradle/unwanted/HasVar.kt b/buildSrc/jarfilter/unwanteds/src/main/kotlin/net/corda/gradle/unwanted/HasVar.kt deleted file mode 100644 index 74fa87062c..0000000000 --- a/buildSrc/jarfilter/unwanteds/src/main/kotlin/net/corda/gradle/unwanted/HasVar.kt +++ /dev/null @@ -1,17 +0,0 @@ -@file:JvmName("HasVar") -@file:Suppress("UNUSED") -package net.corda.gradle.unwanted - -interface HasStringVar { - var stringVar: String -} - -interface HasLongVar { - var longVar: Long -} - -interface HasIntVar { - var intVar: Int -} - -interface HasAllVar : HasIntVar, HasLongVar, HasStringVar diff --git a/buildSrc/settings.gradle b/buildSrc/settings.gradle index 4bd3f3acd2..ba2a28b8ad 100644 --- a/buildSrc/settings.gradle +++ b/buildSrc/settings.gradle @@ -10,6 +10,3 @@ rootProject.name = 'buildSrc' include 'canonicalizer' -include 'jarfilter' -include 'jarfilter:unwanteds' -include 'jarfilter:kotlin-metadata' diff --git a/constants.properties b/constants.properties index 9e3bdc0ec6..ad4981675b 100644 --- a/constants.properties +++ b/constants.properties @@ -8,7 +8,7 @@ # Distribution of this file or any portion thereof via any medium without the express permission of R3 is strictly prohibited. # -gradlePluginsVersion=4.0.26 +gradlePluginsVersion=4.0.27 kotlinVersion=1.2.51 platformVersion=4 guavaVersion=25.1-jre diff --git a/docs/source/corda-networks-index.rst b/docs/source/corda-networks-index.rst index cbe7d5e66f..3fedfce5cb 100644 --- a/docs/source/corda-networks-index.rst +++ b/docs/source/corda-networks-index.rst @@ -12,4 +12,7 @@ Networks corda-testnet-intro azure-template-guide testnet-explorer + gcp-vm + deploy-locally + testnet-explorer-corda cipher-suites diff --git a/docs/source/deploy-locally.rst b/docs/source/deploy-locally.rst index 9180c78247..bf2221d3c8 100644 --- a/docs/source/deploy-locally.rst +++ b/docs/source/deploy-locally.rst @@ -155,3 +155,10 @@ Run the ``run-corda.sh`` script to start your Corda node. Congratulations! You now have a running Corda node on Testnet. .. warning:: It is possible to copy the ``node.zip`` file from your local machine to any other host machine and run the Corda node from there. Do not run multiple copies of the same node (i.e. with the same identity). If a new copy of the node appears on the network then the network map server will interpret this as a change in the address of the node and route traffic to the most recent instance. Any states which are on the old node will no longer be available and undefined behaviour may result. Please provision a new node from the application instead. + + +Testing your deployment +----------------------- + +To test your deployment is working correctly follow the instructions in :doc:`testnet-explorer-corda` to set up the Finance CorDapp and issue cash to a counterparty. + diff --git a/docs/source/gcp-vm.rst b/docs/source/gcp-vm.rst new file mode 100644 index 0000000000..02ecd600f0 --- /dev/null +++ b/docs/source/gcp-vm.rst @@ -0,0 +1,136 @@ +Deploying Corda to Corda Testnet from a Google Cloud Platform VM +================================================================ + +.. contents:: + +This document explains how to deploy a Corda node to Google Cloud Platform that can connect directly to the Corda Testnet. A self service download link can be obtained from https://testnet.corda.network. This document will describe how to set up a virtual machine on the Google Cloud Platform (GCP) to deploy your pre-configured Corda node and automatically connnect to Testnet. + +Pre-requisites +-------------- +* Ensure you have a registered Google Cloud Platform account with + billing enabled (https://cloud.google.com/billing/docs/how-to/manage-billing-account) which can create virtual machines under your subscription(s) and you are logged on to the GCP console: https://console.cloud.google.com. + + +Deploy Corda node +----------------- + +Browse to https://console.cloud.google.com and log in with your +Google credentials. + +**STEP 1: Create a GCP Project** + +In the project drop down click on the plus icon to create a new +project to house your Corda resources. + +.. image:: resources/consolegcp.png + +.. image:: resources/console2.png + +.. image:: resources/newprojectgcp.png + +Enter a project name and click Create. + +**STEP 2: Launch the VM** + +In the left hand side nav click on Compute Engine. + +.. image:: resources/gcpcompute.png + +Click on Create Instance. + +.. image:: resources/consolegcpcreatevm.png + +Fill in the form with the desired VM specs: + +Recommended minimum 4vCPU with 15GB memory and 40GB Persistent disk. +Ubuntu 16.04 LTS. + +Allow full API access. + +Dont worry about firewall settings as you will configure those later. + +.. image:: resources/gcpconsolevmsettings.png + +Click Create and wait a few sections for your instance to provision +and start running. + +**STEP 3: Connect to your VM and set up the environment** + +Once your instance is running click on the SSH button to launch a +cloud SSH terminal in a new window. + +.. image:: resources/gcpconsolelaunchssh.png + +.. image:: resources/gcpshell.png + +Run the following to configure the firewall to allow Corda traffic + +.. code:: bash + + gcloud compute firewall-rules create nodetonode --allow tcp:10002 + gcloud compute firewall-rules create nodetorpc --allow tcp:10003 + gcloud compute firewall-rules create webserver --allow tcp:8080 + + +Promote the ephemeral IP address associated with this +instance to a static IP address. + +First check the region and select the one you are using from the list: + +.. code:: bash + + gcloud compute regions list + +Find your external IP: + +.. code:: bash + + gcloud compute addresses list + +Run this command with the ephemeral IP address as the argument to +the --addresses flag and the region: + +.. code:: bash + + gcloud compute addresses create corda-node --addresses 35.204.53.61 --region europe-west4 + +**STEP 4: Download and set up your Corda node** + +Now your GCP environment is configured you can switch to the Testnet +web application and click on the copy to clipboard button to get a one +time installation script. + +.. note:: If you have not already set up your account on Testnet then please visit https://testnet.corda.network and sign up. + +.. image:: resources/testnet-platform.png + +You can generate as many Testnet identites as you like by refreshing +this page to generate a new one time link. + +In the terminal of your cloud instance paste the command you just copied to install and run +your unique Corda instance: + +.. code:: bash + + sudo ONE_TIME_DOWNLOAD_KEY=YOUR_UNIQUE_DOWNLOAD_KEY_HERE bash -c "$(curl -L https://testnet.corda.network/api/user/node/install.sh)" + +.. warning:: This command will execute the install script as ROOT on your cloud instance. You may wish to examine the script prior to executing it on your machine. + +You can follow the progress of the installation by typing the following command in your terminal: + +.. code:: bash + + tail -f /opt/corda/logs/node-.log + +Once the node has booted up you can navigate to the external web address of the instance on port 8080. If everything is working you should see the following: + +.. image:: resources/installed-cordapps.png + + +Testing your deployment +----------------------- + +To test your deployment is working correctly follow the instructions in :doc:`testnet-explorer-corda` to set up the Finance CorDapp and issue cash to a counterparty. + +This will also demonstrate how to install a custom CorDapp. + diff --git a/docs/source/getting-set-up.rst b/docs/source/getting-set-up.rst index e90766c415..a46607ee86 100644 --- a/docs/source/getting-set-up.rst +++ b/docs/source/getting-set-up.rst @@ -47,12 +47,14 @@ The set-up instructions are available for the following platforms: * :ref:`mac-label` (or `in video form `__) +* :ref:`deb-ubuntu-label` + .. _windows-label: Windows ------- -.. warning:: If you are using a Mac machine, please follow the :ref:`mac-label` instructions instead. +.. warning:: If you are using a Mac or a Debian/Ubuntu machine, please follow the :ref:`mac-label` or :ref:`deb-ubuntu-label` instructions instead. Java ^^^^ @@ -140,7 +142,7 @@ Run from IntelliJ Mac --- -.. warning:: If you are using a Windows machine, please follow the :ref:`windows-label` instructions instead. +.. warning:: If you are using a Windows or a Debian/Ubuntu machine, please follow the :ref:`windows-label` or :ref:`deb-ubuntu-label` instructions instead. Java ^^^^ @@ -242,6 +244,35 @@ And a list of simple sample CorDapps for you to explore basic concepts is availa You can clone these repos to your local machine by running the command ``git clone [repo URL]``. +.. _deb-ubuntu-label: + +Debian/Ubuntu +------ + +.. warning:: If you are using a Mac or a Windows machine, please follow the :ref:`mac-label` or :ref:`windows-label` instructions instead. + +These instructions were tested on Ubuntu Desktop 18.04 LTS. + +Java +^^^^ +1. Open a new terminal and add the Oracle PPA to your repositories by typing ``sudo add-apt-repository ppa:webupd8team/java``. Press ENTER when prompted. +2. Update your packages list with the command ``sudo apt update`` +3. Install the Oracle JDK 8 by typing ``sudo apt install oracle-java8-installer``. Press Y when prompted and agree to the licence terms. +4. Verify that the JDK was installed correctly by running ``java -version`` + +Git +^^^^ +1. From the terminal, Git can be installed using apt with the command ``sudo apt install git`` +2. Verify that git was installed correctly by typing ``git --version`` + +IntelliJ +^^^^^^^^ +Jetbrains offers a pre-built snap package that allows for easy, one-step installation of IntelliJ onto Ubuntu. + +1. To download the snap, navigate to https://snapcraft.io/intellij-idea-community +2. Click ``Install``, then ``View in Desktop Store``. Choose ``Ubuntu Software`` in the Launch Application window. +3. Ensure the Kotlin plugin in Intellij is updated to version |kotlin_version| + Next steps ---------- The best way to check that everything is working fine is by taking a deeper look at the diff --git a/docs/source/node-database.rst b/docs/source/node-database.rst index fe3c034dc8..c9847f5345 100644 --- a/docs/source/node-database.rst +++ b/docs/source/node-database.rst @@ -382,4 +382,4 @@ To add support for another database to a Corda node, the following JAR files mus All additional JAR files need to be copy into ``./drivers`` subdirectory of the node. -.. note:: This is a general guideline. In some cases, it might not be feasible to add support for your desired database without recompiling the Corda source code. +.. note:: This is a general guideline. In some cases, it might not be feasible to add support for your desired database without recompiling the Corda source code. \ No newline at end of file diff --git a/docs/source/resources/installed-cordapps.png b/docs/source/resources/installed-cordapps.png new file mode 100644 index 0000000000..13e6783a5b Binary files /dev/null and b/docs/source/resources/installed-cordapps.png differ diff --git a/docs/source/testnet-explorer-corda.rst b/docs/source/testnet-explorer-corda.rst new file mode 100644 index 0000000000..c9217dfca2 --- /dev/null +++ b/docs/source/testnet-explorer-corda.rst @@ -0,0 +1,127 @@ +Using the Node Explorer to test a Corda node on Corda Testnet +============================================================= + +This document will explain how to test the installation of a Corda node on Testnet. + + +Prerequisites +------------- + +This guide assumes you have deployed a Corda node to the Corda Testnet. + +.. note:: + + If you need to set up a node on Testnet first please follow the instructions: :doc:`corda-testnet-intro`. + + +Get the testing tools +--------------------- + +To run the tests and make sure your node is connecting correctly to the network you will need to download and install a +couple of resources. + +1. Log into your Cloud VM via SSH. + + +2. Stop the Corda node(s) running on your cloud instance. + + .. code:: bash + + ps aux | grep corda.jar | awk '{ print $2 }' | xargs sudo kill + + +3. Download the finance CorDapp + + In the terminal on your cloud instance run: + + .. code:: bash + + wget https://ci-artifactory.corda.r3cev.com/artifactory/corda-releases/net/corda/corda-finance/-corda/corda-finance--corda.jar + + This is required to run some flows to check your connections, and to issue/transfer cash to counterparties. Copy it to the Corda installation location: + + .. code:: bash + + sudo cp /home//corda-finance--corda.jar /opt/corda/cordapps/ + +4. Add the following line to the bottom of your ``node.conf``: + + .. code:: bash + + issuableCurrencies : [ USD ] + + .. note:: Make sure that the config file is in the correct format, e.g., by ensuring that there's a comma at the end of the line prior to the added config. + +4. Restart the Corda node: + + .. code:: bash + + cd /opt/corda + sudo ./run-corda.sh + + Your node is now running the Finance Cordapp. + + .. note:: You can double-check that the CorDapp is loaded in the log file ``/opt/corda/logs/node-.log``. This file will list installed apps at startup. Search for ``Loaded CorDapps`` in the logs. + +6. Now download the Node Explorer to your **LOCAL** machine: + + .. note:: Node Explorer is a JavaFX GUI which connects to the node over the RPC interface and allows you to send transactions. + + Download the Node Explorer from here: + + .. code:: bash + + http://ci-artifactory.corda.r3cev.com/artifactory/corda-releases/net/corda/corda-tools-explorer/-corda/corda-tools-explorer--corda.jar + + .. warning:: This Node Explorer is incompatible with the Corda Enterprise distribution and vice versa as they currently use different serialisation schemes (Kryo vs AMQP). + +7. Run the Node Explorer tool on your **LOCAL** machine. + + .. code:: bash + + java -jar corda-tools-explorer--corda.jar + + .. image:: resources/explorer-login.png + + +Connect to the node +------------------- + +To connect to the node you will need: + +* The IP address of your node (the public IP of your cloud instance). You can find this in the instance page of your cloud console. +* The port number of the RPC interface to the node, specified in ``/opt/corda/node.conf`` in the ``rpcSettings`` section, (by default this is 10003 on Testnet). +* The username and password of the RPC interface of the node, also in the ``node.conf`` in the ``rpcUsers`` section, (by default the username is ``cordazoneservice`` on Testnet). + +Click on ``Connect`` to log into the node. + +Check your network identity and counterparties +---------------------------------------------- + +Once Explorer has logged in to your node over RPC click on the ``Network`` tab in the side navigation of the Explorer UI: + +.. image:: resources/explorer-network.png + +If your Corda node is correctly configured and connected to the Testnet then you should be able to see the identities of your node, the Testnet notary and the network map listing all the counterparties currently on the network. + + +Test issuance transaction +------------------------- + +Now we are going to try and issue some cash to a 'bank'. Click on the ``Cash`` tab. + +.. image:: resources/explorer-cash-issue1.png + +Now click on ``New Transaction`` and create an issuance to a known counterparty on the network by filling in the form: + +.. image:: resources/explorer-cash-issue2.png + +Click ``Execute`` and the transaction will start. + +.. image:: resources/explorer-cash-issue3.png + +Click on the red X to close the notification window and click on ``Transactions`` tab to see the transaction in progress, or wait for a success message to be displayed: + +.. image:: resources/explorer-transactions.png + +Congratulations! You have now successfully installed a CorDapp and executed a transaction on the Corda Testnet. \ No newline at end of file diff --git a/jdk8u-deterministic/build.gradle b/jdk8u-deterministic/build.gradle index 2e4d0a2153..5bf793708f 100644 --- a/jdk8u-deterministic/build.gradle +++ b/jdk8u-deterministic/build.gradle @@ -26,7 +26,7 @@ dependencies { task copyJdk(type: Copy) { outputs.dir jdk_home - from(configurations.jdk.asPath) { + from(configurations.jdk) { rename 'deterministic-rt-(.*).jar', 'rt.jar' } into "$jdk_home/jre/lib" diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/config/ConfigUtilities.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/config/ConfigUtilities.kt index 7318207f8f..88b4847383 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/config/ConfigUtilities.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/config/ConfigUtilities.kt @@ -131,7 +131,7 @@ private fun Config.getSingleValue(path: String, type: KType, onUnknownKeys: (Set Int::class -> getInt(path) Long::class -> getLong(path) Double::class -> getDouble(path) - Boolean::class -> getBoolean(path) + Boolean::class -> getBooleanCaseInsensitive(path) LocalDate::class -> LocalDate.parse(getString(path)) Duration::class -> getDuration(path) Instant::class -> Instant.parse(getString(path)) @@ -286,6 +286,19 @@ private fun Iterable<*>.toConfigIterable(field: Field): Iterable { } } +// The typesafe .getBoolean function is case sensitive, this is a case insensitive version +fun Config.getBooleanCaseInsensitive(path: String): Boolean { + try { + return getBoolean(path) + } catch(e:Exception) { + val stringVal = getString(path).toLowerCase() + if (stringVal == "true" || stringVal == "false") { + return stringVal.toBoolean() + } + throw e + } +} + private val logger = LoggerFactory.getLogger("net.corda.nodeapi.internal.config") enum class UnknownConfigKeysPolicy(private val handle: (Set, logger: Logger) -> Unit) { diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NetworkBootstrapper.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NetworkBootstrapper.kt index b8039a2808..ee86116d96 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NetworkBootstrapper.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NetworkBootstrapper.kt @@ -31,6 +31,7 @@ import net.corda.core.utilities.days import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.seconds import net.corda.nodeapi.internal.* +import net.corda.nodeapi.internal.config.getBooleanCaseInsensitive import net.corda.nodeapi.internal.network.NodeInfoFilesCopier.Companion.NODE_INFO_FILE_NAME_PREFIX import net.corda.serialization.internal.AMQP_P2P_CONTEXT import net.corda.serialization.internal.CordaSerializationMagic @@ -299,7 +300,7 @@ class NetworkBootstrapper // The config contains the notary type val nodeConfig = configs[nodeInfoFile.parent]!! if (nodeConfig.hasPath("notary")) { - val validating = nodeConfig.getBoolean("notary.validating") + val validating = nodeConfig.getBooleanCaseInsensitive("notary.validating") // And the node-info file contains the notary's identity val nodeInfo = nodeInfoFile.readObject().verified() NotaryInfo(nodeInfo.notaryIdentity(), validating) diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/config/ConfigParsingTest.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/config/ConfigParsingTest.kt index 26b23f3807..6b230865ac 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/config/ConfigParsingTest.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/config/ConfigParsingTest.kt @@ -11,6 +11,7 @@ package net.corda.nodeapi.internal.config import com.typesafe.config.Config +import com.typesafe.config.ConfigException import com.typesafe.config.ConfigFactory.empty import com.typesafe.config.ConfigRenderOptions.defaults import com.typesafe.config.ConfigValueFactory @@ -18,6 +19,7 @@ import net.corda.core.identity.CordaX500Name import net.corda.core.internal.div import net.corda.core.utilities.NetworkHostAndPort import org.assertj.core.api.Assertions.* +import org.hibernate.exception.DataException import org.junit.Test import java.net.URL import java.nio.file.Path @@ -51,8 +53,16 @@ class ConfigParsingTest { @Test fun Boolean() { testPropertyType(true, false) + assertThat(config(Pair("value", "false")).parseAs().value).isEqualTo(false) + assertThat(config(Pair("value", "False")).parseAs().value).isEqualTo(false) + assertThat(config(Pair("value", "FALSE")).parseAs().value).isEqualTo(false) + assertThat(config(Pair("value", "true")).parseAs().value).isEqualTo(true) + assertThat(config(Pair("value", "True")).parseAs().value).isEqualTo(true) + assertThat(config(Pair("value", "TRUE")).parseAs().value).isEqualTo(true) + assertThatThrownBy { config(Pair("value", "stilton")).parseAs().value } + .isInstanceOf(ConfigException.WrongType::class.java) + .hasMessageContaining("hardcoded value: value has type STRING rather than BOOLEAN") } - @Test fun Enum() { testPropertyType(TestEnum.Value2, TestEnum.Value1, valuesToString = true) diff --git a/node/src/main/kotlin/net/corda/node/internal/cordapp/TypesafeCordappConfig.kt b/node/src/main/kotlin/net/corda/node/internal/cordapp/TypesafeCordappConfig.kt index ade7bd6f17..22a3bb25b6 100644 --- a/node/src/main/kotlin/net/corda/node/internal/cordapp/TypesafeCordappConfig.kt +++ b/node/src/main/kotlin/net/corda/node/internal/cordapp/TypesafeCordappConfig.kt @@ -14,6 +14,7 @@ import com.typesafe.config.Config import com.typesafe.config.ConfigException import net.corda.core.cordapp.CordappConfig import net.corda.core.cordapp.CordappConfigException +import net.corda.nodeapi.internal.config.getBooleanCaseInsensitive /** * Provides configuration from a typesafe config source @@ -81,7 +82,7 @@ class TypesafeCordappConfig(private val cordappConfig: Config) : CordappConfig { override fun getBoolean(path: String): Boolean { try { - return cordappConfig.getBoolean(path) + return cordappConfig.getBooleanCaseInsensitive(path) } catch (e: ConfigException) { throw CordappConfigException("Cordapp configuration is incorrect due to exception", e) } diff --git a/node/src/main/kotlin/net/corda/node/services/vault/NodeVaultService.kt b/node/src/main/kotlin/net/corda/node/services/vault/NodeVaultService.kt index a5558936fd..a4f34b2877 100644 --- a/node/src/main/kotlin/net/corda/node/services/vault/NodeVaultService.kt +++ b/node/src/main/kotlin/net/corda/node/services/vault/NodeVaultService.kt @@ -477,7 +477,11 @@ class NodeVaultService( if (paging.pageSize < 1) throw VaultQueryException("Page specification: invalid page size ${paging.pageSize} [must be a value between 1 and $MAX_PAGE_SIZE]") } - query.firstResult = if (paging.pageNumber > 0) (paging.pageNumber - 1) * paging.pageSize else 0 //some DB don't allow a negative value in SELECT TOP query + // For both SQLServer and PostgresSQL, firstResult must be >= 0. So we set a floor at 0. + // TODO: This is a catch-all solution. But why is the default pageNumber set to be -1 in the first place? + // Even if we set the default pageNumber to be 1 instead, that may not cover the non-default cases. + // So the floor may be necessary anyway. + query.firstResult = maxOf(0, (paging.pageNumber - 1) * paging.pageSize) query.maxResults = paging.pageSize + 1 // detection too many results // execution diff --git a/node/src/test/kotlin/net/corda/node/services/config/NodeConfigurationImplTest.kt b/node/src/test/kotlin/net/corda/node/services/config/NodeConfigurationImplTest.kt index 02500556ea..2d2d0252ed 100644 --- a/node/src/test/kotlin/net/corda/node/services/config/NodeConfigurationImplTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/config/NodeConfigurationImplTest.kt @@ -17,6 +17,7 @@ import net.corda.core.utilities.NetworkHostAndPort import net.corda.nodeapi.internal.persistence.CordaPersistence.DataSourceConfigTag import net.corda.core.utilities.seconds import net.corda.nodeapi.internal.config.UnknownConfigKeysPolicy +import net.corda.nodeapi.internal.config.getBooleanCaseInsensitive import net.corda.testing.core.ALICE_NAME import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties import net.corda.tools.shell.SSHDConfiguration @@ -108,16 +109,16 @@ class NodeConfigurationImplTest { val os = System.getProperty("os.name") setSystemOs("Windows 98") - assertTrue(getConfig("test-config-empty.conf").getBoolean("devMode")) + assertTrue(getConfig("test-config-empty.conf").getBooleanCaseInsensitive("devMode")) setSystemOs("Mac Sierra") - assertTrue(getConfig("test-config-empty.conf").getBoolean("devMode")) + assertTrue(getConfig("test-config-empty.conf").getBooleanCaseInsensitive("devMode")) setSystemOs("Windows server 2008") - assertFalse(getConfig("test-config-empty.conf").getBoolean("devMode")) + assertFalse(getConfig("test-config-empty.conf").getBooleanCaseInsensitive("devMode")) setSystemOs("Linux") - assertFalse(getConfig("test-config-empty.conf").getBoolean("devMode")) + assertFalse(getConfig("test-config-empty.conf").getBooleanCaseInsensitive("devMode")) setSystemOs(os) } @@ -128,22 +129,22 @@ class NodeConfigurationImplTest { @Test fun `Dev mode is read from the config over the autodetect logic`() { - assertTrue(getConfig("test-config-DevMode.conf").getBoolean("devMode")) - assertFalse(getConfig("test-config-noDevMode.conf").getBoolean("devMode")) + assertTrue(getConfig("test-config-DevMode.conf").getBooleanCaseInsensitive("devMode")) + assertFalse(getConfig("test-config-noDevMode.conf").getBooleanCaseInsensitive("devMode")) } @Test fun `Dev mode is true if overriden`() { - assertTrue(getConfig("test-config-DevMode.conf", ConfigFactory.parseMap(mapOf("devMode" to true))).getBoolean("devMode")) - assertTrue(getConfig("test-config-noDevMode.conf", ConfigFactory.parseMap(mapOf("devMode" to true))).getBoolean("devMode")) - assertTrue(getConfig("test-config-empty.conf", ConfigFactory.parseMap(mapOf("devMode" to true))).getBoolean("devMode")) + assertTrue(getConfig("test-config-DevMode.conf", ConfigFactory.parseMap(mapOf("devMode" to true))).getBooleanCaseInsensitive("devMode")) + assertTrue(getConfig("test-config-noDevMode.conf", ConfigFactory.parseMap(mapOf("devMode" to true))).getBooleanCaseInsensitive("devMode")) + assertTrue(getConfig("test-config-empty.conf", ConfigFactory.parseMap(mapOf("devMode" to true))).getBooleanCaseInsensitive("devMode")) } @Test fun `Dev mode is false if overriden`() { - assertFalse(getConfig("test-config-DevMode.conf", ConfigFactory.parseMap(mapOf("devMode" to false))).getBoolean("devMode")) - assertFalse(getConfig("test-config-noDevMode.conf", ConfigFactory.parseMap(mapOf("devMode" to false))).getBoolean("devMode")) - assertFalse(getConfig("test-config-empty.conf", ConfigFactory.parseMap(mapOf("devMode" to false))).getBoolean("devMode")) + assertFalse(getConfig("test-config-DevMode.conf", ConfigFactory.parseMap(mapOf("devMode" to false))).getBooleanCaseInsensitive("devMode")) + assertFalse(getConfig("test-config-noDevMode.conf", ConfigFactory.parseMap(mapOf("devMode" to false))).getBooleanCaseInsensitive("devMode")) + assertFalse(getConfig("test-config-empty.conf", ConfigFactory.parseMap(mapOf("devMode" to false))).getBooleanCaseInsensitive("devMode")) } private fun getConfig(cfgName: String, overrides: Config = ConfigFactory.empty()): Config { diff --git a/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/volumes/Volume.kt b/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/volumes/Volume.kt index fa514dd168..4ec5d47f02 100644 --- a/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/volumes/Volume.kt +++ b/tools/network-bootstrapper/src/main/kotlin/net/corda/bootstrapper/volumes/Volume.kt @@ -9,6 +9,7 @@ import net.corda.core.node.NotaryInfo import net.corda.core.serialization.deserialize import net.corda.nodeapi.internal.DEV_ROOT_CA import net.corda.nodeapi.internal.SignedNodeInfo +import net.corda.nodeapi.internal.config.getBooleanCaseInsensitive import net.corda.nodeapi.internal.createDevNetworkMapCa import java.io.File import java.security.cert.X509Certificate @@ -36,7 +37,7 @@ interface Volume { fun convertNodeIntoToNetworkParams(notaryFiles: List>): NetworkParameters { val notaryInfos = notaryFiles.map { (configFile, nodeInfoFile) -> - val validating = ConfigFactory.parseFile(configFile).getConfig("notary").getBoolean("validating") + val validating = ConfigFactory.parseFile(configFile).getConfig("notary").getBooleanCaseInsensitive("validating") nodeInfoFile.readBytes().deserialize().verified().let { NotaryInfo(it.legalIdentities.first(), validating) } }