Aram Arabyan
Aram Arabyan

Reputation: 2359

ClassCastException after checking of instanceOf

I Have grails (version 3.2.11) application (it includes groovy-2.4.11.jar). And following code

 @CompileStatic
def removeAllErrors(DomainClass domainInstance) {
    newAssociationOperationRunnerBuilder(domainInstance)
    .setSkipChain({DomainObjectDetails<DomainObjectDataSingle> domainObjectDetails ->
        skipValidation(domainObjectDetails.currentDomain.domainObject, domainObjectDetails.associationProp?.name)})
    .build().run({DomainObjectDetails<DomainObjectDataSingle> domainObjectDetails ->
        DomainClass domain = domainObjectDetails.currentDomain.domainObject
        if (domain instanceof GormValidateable) {
            ((GormValidateable)domain).clearErrors()
        }
        if(domain instanceof WarningsHolder) {
            WarningsHolder warningsHolder = domain as WarningsHolder //<--- line 120
            Warnings warnings = warningsHolder.getWarnings()
            warnings.clearWarnings(false, true)
        }
    })
}

And I am getting following exception

2018-06-14 10:16:41,647 ERROR StackTrace - Full Stack Trace:
java.lang.IllegalArgumentException: java.lang.ClassCastException@3f6e3869
    at sun.reflect.GeneratedMethodAccessor5958.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1213)
    at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1125)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
    at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:925)
    at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:908)
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:168)
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.asType(ScriptBytecodeAdapter.java:591)
    at com.webbfontaine.grails.plugins.validation.rules.DocVerificationService$_removeAllErrors_closure5.doCall(DocVerificationService.groovy:120)

Any idea what can be the reason ? Pay attention that I have @CompileStatic there also.

========================================================================= Previous version of this code was without @CompileStatic

 def removeAllErrors(def domainInstance) {
    newAssociationOperationRunnerBuilder(domainInstance)
    .setSkipChain({DomainObjectDetails<DomainObjectDataSingle> domainObjectDetails ->
        skipValidation(domainObjectDetails.currentDomain.domainObject, domainObjectDetails.associationProp?.name)})
    .build().run({DomainObjectDetails<DomainObjectDataSingle> domainObjectDetails ->
        domainObjectDetails.currentDomain.domainObject.clearErrors()
        if(domainObjectDetails.currentDomain.domainObject instanceof WarningsHolder) {
            Warnings warnings = domainObjectDetails.currentDomain.domainObject.getWarnings()
            warnings.clearWarnings(false, true)
        }
    })
}

And I was getting this exception

com.webbfontaine.sw.sad.ci.Item cannot be cast to com.webbfontaine.sw.sad.ci.Item_$$_jvst840_3. Stacktrace follows: java.lang.ClassCastException: com.webbfontaine.sw.sad.ci.Item cannot be cast to com.webbfontaine.sw.sad.ci.Item_$$_jvst840_3
at com.webbfontaine.grails.plugins.validation.rules.DocVerificationService$_removeAllErrors_closure5.doCall(DocVerificationService.groovy:111)

Upvotes: 0

Views: 274

Answers (1)

injecteer
injecteer

Reputation: 20699

You should not be using instanceof with proxies at all, as it' going to lead to unpredictable results.

If you want to check the objects for class, you can use either isAssignableFrom():

if ( GormValidateable.isAssignableFrom( domain.getClass() ) ) {...}

or isCase() / switch:

switch( domain ){
  case GormValidateable: doStuff(); break
  case WarningsHolder: doOtherSTuff(); break
}

Upvotes: 2

Related Questions