javasap-enterprise-portal

Can't get round a ClassCastException


While trying to cast the result of a context.lookup() call in my portal application, I'm getting a ClassCastException for two out of three attempts at casting different results.

After some research I think this: http://wiki.sdn.sap.com/wiki/display/TechTSG/%28AS+Java%29+ClassCastException+Occurs+After+Lookup+Operation holds the answer, but it doesn't explain really how to carry out the two steps.

This code works for fetching the details of an iView, from its path stored in list :

IiView transView1 = (IiView) context.lookup(list.get(i).toString());

but when fetching details of a workset like this:

IPcdContext attrSet = (IPcdContext) context.lookup(list.get(i).toString());

I get a ClassCastException. Any help or explanation as to why I get this error would be greatly appreciated!

edit: This is what the code is based on: http://www.sdn.sap.com/irj/scn/go/portal/prtroot/docs/library/uuid/6112ecb7-0a01-0010-ef90-941c70c9e401?overridelayout=true

edit2: The object I get back from context.lookup is com.sapportals.portal.pcd.pcm.roles.PortalWorkset which I can't find documentation on.


Solution

  • If context.lookup returns you a PortalWorkset, then there's no way to "get round" the ClassCastException.

    Casting does not convert an object to a different class - it's merely a way for you to tell the compiler that you're sure it's a more specific class than its current declared type. In this case, you're saying "I realise that the lookup() method is declared to return Object, but when I call it in this particular context I'm sure that it will always specifically return an IPcdContext object." Your assumption here turned out not to hold, and the program correctly signals this by throwing the exception.

    There are potential two causes to your problem:

    1. Your assumption is correct in general, but due to a logic bug you're not passing in the string you expect to the lookup method, and so are getting the wrong thing back altogether. In this case, ensure that the parameter passed to the method is always correct.
    2. Your assumption is incorrect, and you might not always get an IPcdContext back. In this case, you'll need to decide what to do with other objects that are returned, and deal with them appropriately (you can use the instanceof operator to check the class of the returned object).

    In any case, whenever you do a cast it's usually beneficial to check that it will succeed first, with an idiom like:

    IPcdContext context;
    Object obj = context.lookup("foo");
    if (obj instanceof IPcdContext) {
        context = (IPcdContext)obj;
    }
    else {
        // You got back something else.  What to do?
    }