繁体   English   中英

Groovy 与 Java / Spring 集成导致类转换异常

[英]Groovy Integration with Java / Spring results in classcastexception

我正在使用 Spring Boot starter 2.3.1,Groovy-all 2.4.13。 我有一种机制,使我能够在运行时从我的 Java 程序中执行 Groovy 脚本。 如下所示:

GroovyShell groovyShell = new GroovyShell(this.getClass().getClassLoader());
Class<Script> pScriptClass = groovyShell.parse(pScriptString).getClass();
Script pScriptObject = pScriptClass.newInstance();
pScriptObject.setBinding(pBinding);
return pScriptObject.invokeMethod("process", null);

只要脚本不涉及任何强制转换,它就可以正常运行。 但是,在我的一个脚本中,我有一个 class 铸件,如下所示:

Object process(){
   RestServiceUtil resServ = (RestServiceUtil) applicationContext.getBean("restServiceUtil");
   .
   .
   .
}

In the case above I understand that the LHS refers to the class object from the GroovyClassLoader whereas the RHS is from the java class loader. 但是,无论我发现什么,这都不会造成问题,因为 GroovyShell 是使用 java class 加载程序作为父级创建的,即new GroovyShell(this.getClass().getClassLoader())

但是当我尝试运行这个脚本时,我仍然看到 class 转换异常。 由于 Groovy class 加载器使用的是 Java ZA2F2ED4F8EBC2CBB4C21A29DC40AB619Z ZA2F2ED4F8EBC2CBB4C21A29DC40AB6 加载器,因此认为我们应该将两个加载器分别编译为父级。

org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'com.bell.na.nt.bnsm.nets.consumer.utils.RestServiceUtil@1f239d3f' with class 'com.bell.na.nt.bnsm.nets.consumer.utils.RestServiceUtil$$EnhancerBySpringCGLIB$$88984819' to class 'com.bell.na.nt.bnsm.nets.consumer.utils.RestServiceUtil'
    at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnSAM(DefaultTypeTransformation.java:405) ~[groovy-all-2.4.13.jar:2.4.13]
    at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnNumber(DefaultTypeTransformation.java:319) ~[groovy-all-2.4.13.jar:2.4.13]
    at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToType(DefaultTypeTransformation.java:232) ~[groovy-all-2.4.13.jar:2.4.13]
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.castToType(ScriptBytecodeAdapter.java:603) ~[groovy-all-2.4.13.jar:2.4.13]
    at Script33.process(Script33.groovy:16) ~[?:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_282]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_282]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_282]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_282]
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93) ~[groovy-all-2.4.13.jar:2.4.13]
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325) ~[groovy-all-2.4.13.jar:2.4.13]
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1213) ~[groovy-all-2.4.13.jar:2.4.13]
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022) ~[groovy-all-2.4.13.jar:2.4.13]
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:803) ~[groovy-all-2.4.13.jar:2.4.13]
    at groovy.lang.GroovyObjectSupport.invokeMethod(GroovyObjectSupport.java:46) ~[groovy-all-2.4.13.jar:2.4.13]
    at groovy.lang.Script.invokeMethod(Script.java:80) ~[groovy-all-2.4.13.jar:2.4.13]
    at com.bell.na.nt.remedy.groovy.NetsUtilityGroovyUtils.execute(NetsUtilityGroovyUtils.java:62) ~[ms-nets-utility-library-1.0.jar:1.0]
    at com.bell.na.nt.json.utils.NetsUtilityJSONDatumUtils.getJsonValue(NetsUtilityJSONDatumUtils.java:260) [ms-nets-utility-library-1.0.jar:1.0]
    at com.bell.na.nt.json.utils.NetsUtilityJSONDatumUtils.createPlainJsonObjectFromJsonObject(NetsUtilityJSONDatumUtils.java:169) [ms-nets-utility-library-1.0.jar:1.0]
    at com.bell.na.nt.json.utils.NetsUtilityJSONDatumUtils$createPlainJsonObjectFromJsonObject.call(Unknown Source) [ms-nets-utility-library-1.0.jar:1.0]
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) [groovy-all-2.4.13.jar:2.4.13]
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) [groovy-all-2.4.13.jar:2.4.13]
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) [groovy-all-2.4.13.jar:2.4.13]
    at Script8.process(Script8.groovy:17) [shell:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_282]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_282]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_282]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_282]
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93) [groovy-all-2.4.13.jar:2.4.13]
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325) [groovy-all-2.4.13.jar:2.4.13]
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1213) [groovy-all-2.4.13.jar:2.4.13]
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022) [groovy-all-2.4.13.jar:2.4.13]
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:803) [groovy-all-2.4.13.jar:2.4.13]
    at groovy.lang.GroovyObjectSupport.invokeMethod(GroovyObjectSupport.java:46) [groovy-all-2.4.13.jar:2.4.13]
    at groovy.lang.Script.invokeMethod(Script.java:80) [groovy-all-2.4.13.jar:2.4.13]
    at com.bell.na.nt.remedy.groovy.NetsUtilityGroovyUtils.execute(NetsUtilityGroovyUtils.java:62) [ms-nets-utility-library-1.0.jar:1.0]
    at com.bell.na.nt.json.utils.NetsUtilityJSONDatumUtils.getJsonValue(NetsUtilityJSONDatumUtils.java:260) [ms-nets-utility-library-1.0.jar:1.0]
    at com.bell.na.nt.json.utils.NetsUtilityJSONDatumUtils.createPlainJsonObjectFromJsonObject(NetsUtilityJSONDatumUtils.java:169) [ms-nets-utility-library-1.0.jar:1.0]
    at com.bell.na.nt.bnsm.nets.consumer.service.BNSMNETSReaderService.transformJSONMsg(BNSMNETSReaderService.java:138) [classes/:?]
    at com.bell.na.nt.bnsm.nets.consumer.service.BNSMNETSReaderService.iterativelyTrnsfrmJSON(BNSMNETSReaderService.java:117) [classes/:?]
    at com.bell.na.nt.bnsm.nets.consumer.service.BNSMNETSReaderService.processEventMessage(BNSMNETSReaderService.java:76) [classes/:?]
    at com.bell.na.nt.bnsm.nets.consumer.processor.EventReaderMessageProcessor.processMessage(EventReaderMessageProcessor.java:42) [classes/:?]
    at com.bell.na.nt.kafka.consumer.KafkaConsumer.onMessage(KafkaConsumer.java:52) [spring-kafka-consumer-module-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_282]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_282]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_282]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_282]
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:171) [spring-messaging-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:120) [spring-messaging-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.kafka.listener.adapter.HandlerAdapter.invoke(HandlerAdapter.java:48) [spring-kafka-2.5.4.RELEASE.jar:2.5.4.RELEASE]
    at org.springframework.kafka.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:329) [spring-kafka-2.5.4.RELEASE.jar:2.5.4.RELEASE]
    at org.springframework.kafka.listener.adapter.RecordMessagingMessageListenerAdapter.onMessage(RecordMessagingMessageListenerAdapter.java:86) [spring-kafka-2.5.4.RELEASE.jar:2.5.4.RELEASE]
    at org.springframework.kafka.listener.adapter.RecordMessagingMessageListenerAdapter.onMessage(RecordMessagingMessageListenerAdapter.java:51) [spring-kafka-2.5.4.RELEASE.jar:2.5.4.RELEASE]
    at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.doInvokeOnMessage(KafkaMessageListenerContainer.java:1878) [spring-kafka-2.5.4.RELEASE.jar:2.5.4.RELEASE]
    at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeOnMessage(KafkaMessageListenerContainer.java:1860) [spring-kafka-2.5.4.RELEASE.jar:2.5.4.RELEASE]
    at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.doInvokeRecordListener(KafkaMessageListenerContainer.java:1797) [spring-kafka-2.5.4.RELEASE.jar:2.5.4.RELEASE]
    at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.doInvokeWithRecords(KafkaMessageListenerContainer.java:1737) [spring-kafka-2.5.4.RELEASE.jar:2.5.4.RELEASE]
    at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeRecordListener(KafkaMessageListenerContainer.java:1634) [spring-kafka-2.5.4.RELEASE.jar:2.5.4.RELEASE]
    at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeListener(KafkaMessageListenerContainer.java:1364) [spring-kafka-2.5.4.RELEASE.jar:2.5.4.RELEASE]
    at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.pollAndInvoke(KafkaMessageListenerContainer.java:1080) [spring-kafka-2.5.4.RELEASE.jar:2.5.4.RELEASE]
    at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.run(KafkaMessageListenerContainer.java:988) [spring-kafka-2.5.4.RELEASE.jar:2.5.4.RELEASE]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_282]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_282]
    at java.lang.Thread.run(Thread.java:748) [?:1.8.0_282]

在这方面的任何帮助将不胜感激。

所以显然是两个不同的类加载器层次结构导致了问题。 Java class 加载器,然后是这个 GroovyClassLoader,它具有相同的 Object 的单独实例,它试图转换为类似于我们在下面看到的东西。

在此处输入图像描述

因此,以下使用 java class 加载器作为父加载器初始化 groovyclassloader 的方法应该有效。 GroovyShell groovyShell = new GroovyShell(this.getClass().getClassLoader());

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM