Search code examples
javadistributed-systemice

ICE - How to cast implementation to proxy?


I use ICE in my code. And I want to run function that needs GameObserverPrx as parameter. I don't want to pass GameObserver by value and I use GameObserver* in slice interface to pass proxy.

What function should I use to cast GameObserver to GameObserverPrx? And second question - Why ICE coudn't do it instead of me? I was searching answer in internet. I only found ObjectAdapter.checkedCast but it serve to another purpose.

Here is error:

The method addObserver(String, GameObserverPrx, Current) in the type GameProxyImpl is not applicable for the arguments (String, GameObserverImpl, null) PrzeciwnikKomputerowy.java /warcaby-serwer/src/main/java/sr/warcaby/serwer line 74 Java Problem

Here are fragments from my code: In this line I see an error.

partia.addObserver(token, new GameObserverImpl(this)), null);

Fragment of GameObserver implementation:

class GameObserverImpl extends _GameObserverDisp { //extends IGameObserverPOA{

    private static final long serialVersionUID = 1L;
    PrzeciwnikKomputerowy p;
    public GameObserverImpl(PrzeciwnikKomputerowy p) {
        this.p = p;
    }

Fragments of api.ice:

interface GameObserver {
    void notifyObserver(  CORBAMove lastMove);
};



interface GameProxy {
    void addObserver(  string token,   GameObserver* o) throws MyException;
    bool isMyTurn(  string token) throws MyException;
    void doMove(  string token,   CORBAMove move) throws MyException;
    Position getPosition(  string token) throws MyException;
    string showPosition(  string token) throws MyException;
};

Don't feel confused about the name CORBAMove. I used CORBA but I changed my code to ICE.


Solution

  • I have found answer to my question. Now my application works as intended.

    I wrote method which create ObjectPrx from Ice.Object. This method use reflection to find cast method for specified class.

    On this site I found functions that I needed: https://doc.zeroc.com/display/Ice/Object+Incarnation+in+Java#ObjectIncarnationinJava-proxies

    Most important line is: ObjectPrx objectPrx = adapter.addWithUUID(iceObject).

    And then I cast using method xxxPrxHelper.checkedCast(objectPrx) which I get from reflection. Here is changed code:

    partia.addObserver(token, (GameObserverPrx)
        serwer.createProxyForObject(observer, GameObserverPrxHelper.class), null)
    

    Method in class ServerImpl:

    public ObjectPrx createProxyForObject(Ice.Object iceObject, Class<?> clazz) {
        ObjectPrx objectPrx = adapter.addWithUUID(iceObject);
        try {
            Method method = clazz.getMethod("checkedCast", ObjectPrx.class);
            objectPrx =  (ObjectPrx) method.invoke(null, objectPrx);//adapter.createIndirectProxy(id));
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    
        return objectPrx;
    

    Method createProxyForObject is using normal adapter initialized in server constructor (because PrzeciwnikKomputerowy class is still part of server program).

        Ice.Communicator communicator = Ice.Util.initialize(args); 
    
        ObjectAdapter adapter = communicator.createObjectAdapter("ChessServer");