Guidewire 10中GOSU创建含internal构造函数类实例报错解决
Guidewire 10中调用internal构造函数创建实例报错的解决方法
问题场景
在Guidewire 10环境下做单元测试时,尝试通过反射创建仅包含internal构造函数的InternalBucketS3Service类实例,调用newInstance时抛出IllegalArgumentException。
测试代码
var s3ServiceCtor = InternalBucketS3Service.getClass().getDeclaredConstructors().first() s3ServiceCtor.setAccessible(true) var newInstanceResult = s3ServiceCtor.newInstance({_testClaim}.toArray()) return newInstanceResult as S3Service
目标类代码
class InternalBucketS3Service extends AbstractS3Service { private var _claim : Claim internal construct(claim : Claim) { super(Configuration.S3InternalBucket) _claim = claim } // 无其他构造函数,仅包含方法... }
报错信息
junit.framework.AssertionFailedError: Exception in constructor: testGeneralS3ServicesCompare (java.lang.IllegalArgumentException at jdk.internal.reflect.GeneratedConstructorAccessor141.newInstance(Unknown Source) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490) at ru.tinkoff.util.s3.S3TestServiceImplComparisonTest.getRealS3(S3TestServiceImplComparisonTest.gs:59) at ru.tinkoff.util.s3.S3TestServiceImplComparisonTest.<init>(S3TestServiceImplComparisonTest.gs:25) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
问题原因
报错根源是参数传递方式错误:Constructor.newInstance(Object...)是可变参数方法,当传入{_testClaim}.toArray()生成的Object数组时,Java会将数组拆分为多个参数,但目标构造函数仅接受单个Claim类型参数,导致参数数量不匹配,触发IllegalArgumentException。
解决方法
方法1:直接传递单个参数
移除toArray()调用,直接将_testClaim作为单个参数传入newInstance:
var s3ServiceCtor = InternalBucketS3Service.getClass().getDeclaredConstructors().first() s3ServiceCtor.setAccessible(true) var newInstanceResult = s3ServiceCtor.newInstance(_testClaim) return newInstanceResult as S3Service
方法2:使用Guidewire的TypeRef工具类(推荐)
借助Gosu原生的TypeRef类简化反射操作,更贴合Guidewire生态:
var typeRef = TypeRef.of(InternalBucketS3Service) var constructor = typeRef.getDeclaredConstructor(TypeRef.of(Claim)) constructor.setAccessible(true) var newInstanceResult = constructor.newInstance(_testClaim) return newInstanceResult as S3Service
方法3:包装数组为单个元素(补充方案)
如果必须使用数组传递,需将数组作为单个元素传入,避免被拆分:
var s3ServiceCtor = InternalBucketS3Service.getClass().getDeclaredConstructors().first() s3ServiceCtor.setAccessible(true) var newInstanceResult = s3ServiceCtor.newInstance([_testClaim] as Object[]) return newInstanceResult as S3Service
内容的提问来源于stack exchange,提问作者Maxim Kozlyuk
相关产品推荐
相关产品推荐

