Fix toString generated method that breaks Introspection for BEANS

Pass signature as null, not empty string, otherwise the class asm isn't
correct. Using javap at the command line prior to the fix yields

public class MyClass implements
net.corda.core.serialization.carpenter.SimpleFieldAccess {
    protected final java.lang.Integer a;
        descriptor: Ljava/lang/Integer;
    public MyClass(java.lang.Integer);
        descriptor: (Ljava/lang/Integer;)V

    public java.lang.Integer getA();
        descriptor: ()Ljava/lang/Integer;

    public java.lang.Object get(java.lang.String);
        descriptor:
(Ljava/lang/String;)Ljava/lang/Object;
Error: A serious internal error has occurred: java.lang.StringIndexOutOfBoundsException: String index out of range: 0
This commit is contained in:
Katelyn Baker 2017-07-12 17:53:21 +01:00
parent 78ecff7933
commit 0d0a6d7966
2 changed files with 17 additions and 5 deletions

View File

@ -216,7 +216,7 @@ class ClassCarpenter {
* Generate bytecode for the given schema and load into the JVM. The returned class object can be used to
* construct instances of the generated class.
*
* @throws DuplicateName if the schema's name is already taken in this namespace (you can create a new ClassCarpenter if you're OK with ambiguous names)
* @throws DuplicateNameException if the schema's name is already taken in this namespace (you can create a new ClassCarpenter if you're OK with ambiguous names)
*/
fun build(schema: Schema): Class<*> {
validateSchema(schema)
@ -291,7 +291,7 @@ class ClassCarpenter {
private fun ClassWriter.generateToString(schema: Schema) {
val toStringHelper = "com/google/common/base/MoreObjects\$ToStringHelper"
with(visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", "", null)) {
with(visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null)) {
visitCode()
// com.google.common.base.MoreObjects.toStringHelper("TypeName")
visitLdcInsn(schema.name.split('.').last())

View File

@ -1,12 +1,11 @@
package net.corda.core.serialization.carpenter
import org.junit.Test
import java.lang.reflect.Field
import java.lang.reflect.Method
import kotlin.test.assertEquals
import kotlin.test.assertTrue
import java.beans.Introspector
import kotlin.test.assertNotEquals
class ClassCarpenterTest {
interface DummyInterface {
@ -491,4 +490,17 @@ class ClassCarpenterTest {
assertEquals (javax.annotation.Nonnull::class.java, clazz.getMethod("getB").annotations[0].annotationClass.java)
}
@Test
fun beanTest() {
val schema = ClassCarpenter.ClassSchema(
"pantsPantsPants",
mapOf("a" to ClassCarpenter.NonNullableField(Integer::class.java)))
val clazz = cc.build(schema)
val descriptors = Introspector.getBeanInfo(clazz).propertyDescriptors
assertEquals(2, descriptors.size)
assertNotEquals(null, descriptors.find { it.name == "a" })
assertNotEquals(null, descriptors.find { it.name == "class" })
}
}