Bernhard
Bernhard

Reputation: 444

java/groovy/grails instanceof fails

I have a class called Video and an object of this class (here called "b")

This is the test case:

log.debug b
log.debug b.class
log.debug (b.class == Video)
log.debug (b instanceof Video)
log.debug (b.instanceOf(Video))
log.debug (b in Video)

the output is:

DEBUG NavLinkHelperTagLib  - product.content.Video : 4352
DEBUG NavLinkHelperTagLib  - class product.content.Video
DEBUG NavLinkHelperTagLib  - true
DEBUG NavLinkHelperTagLib  - false
DEBUG NavLinkHelperTagLib  - true
DEBUG NavLinkHelperTagLib  - false

Can somebody tell me why the instanceof fails?!

EDIT:

I have the feeling that this is GORM related. Here are my donain classes:

abstract class Product implements Serializable {

    static hasMany = [additionalContents:AdditionalContent]
}

abstract class AdditionalContent implements Serializable{
    static belongsTo = [product:Product]

}

class Video extends AdditionalContent {
}

I think the problem here is lazy loading? But when this is the proxy/lazy problem then normally I would see something like Video$$javaassist when calling .getClass() but I am not seeing this...

Upvotes: 2

Views: 420

Answers (2)

saw303
saw303

Reputation: 9072

This is Hibernate / Gorm related. Your domain object is most likely proxied by Hibernate. Therefore you cannot use Java instanceOf.

The Grails team is aware of that problem and therefore they introduce the instanceOf() method on every Grails domain object. The following quote is from the Grails reference.

You can protect yourself to a degree from this problem by using the instanceOf method by GORM:

def person = Person.get(1)

assert Pet.list()[0].instanceOf(Dog)

Therefore only compare domain classes by using instanceOf() method.

In order to see how instanceOf is implemented you need to decompile your Video domain class by using JD-GUI.

In a Grails 3 application this is implemented by the trait GormEntity.

@Traits.TraitBridge(traitClass=GormEntity.class, desc="(Ljava/lang/Class;)Z")
  public boolean instanceOf(Class arg1)
  {
    // Byte code:
    //   0: invokestatic 88 ch/silviowangler/zscsupporter/Game:$getCallSiteArray    ()[Lorg/codehaus/groovy/runtime/callsite/CallSite;
    //   3: astore_2
    //   4: aload_2
    //   5: ldc_w 548
    //   8: aaload
    //   9: ldc -104
    //   11: aload_0
    //   12: aload_1
    //   13: invokeinterface 209 4 0
    //   18: invokestatic 182   org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation:booleanUnbox (Ljava/lang/Object;)Z
    //   21: ireturn
    //   22: nop
    //   23: nop
    //   24: nop
    //   25: nop
    //   26: nop
    //   27: nop
    //   28: nop
    //   29: nop
    //   30: athrow
    // Local variable table:
    //   start  length  slot    name    signature
    //   0  22  0   this    Game
    //   0  22  1   arg1    Class
  }

This is the only way to understand how the instanceOf method behaves.

Upvotes: 1

Hans Bogaards
Hans Bogaards

Reputation: 687

Not sure why the instanceof (I first wrote instanceOf but meant the java keyword) fails, but the normal way of checking type is in.

log.debug b in Video

should return true

Upvotes: 0

Related Questions