簡體   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