Archived

This forum has been archived. Please start a new discussion on GitHub.

NoObjectFactoryException

Ive written some classes in slice that contain both data and getter methods for that data. In another class I define methods which take those classes as input parameters, like this:
class MyCommand {
    int mCommandId;
    int getCommandId();
};

class Transceiver1 {
    void sendCommand(MyCommand command);
};

class Transceiver2 {
    void sendCommand(MyCommand command);
};


Ive also got a concrete implementation of both Transceiver1 and 2 which takes care of Ice initialization. Both classes set themselves up as servers but Transceiver1 alone attempts to get a proxy to Transceiver2 and call sendCommand().

Everything compiles without a problem and even works to some small degree: If I run instances of Transceiver1 and 2 from one application, everything works beautifully - messages are sent and received. But if I run them as two separate applications and try to get them to talk to eachother, disaster strikes. Here's what I see from each application's perspective:

Transceiver1:
(acting as a client)
Sending test command...
Problem: Outgoing.cpp:478: Ice::UnknownLocalException:
unknown local exception:
BasicStream.cpp:1830: Ice::NoObjectFactoryException:
protocol error: no suitable object factory found for `MyCommand'

Transceiver2:
(acting as a server)
10/21/09 18:32:19.019 warning: dispatch exception: BasicStream.cpp:1830: Ice::No
ObjectFactoryException:
protocol error: no suitable object factory found for `MyCommand'
identity: Transceiver2
facet:
operation: sendCommand

I've read through the various threads that I could find on the subject and see that I should create an ObjectFactory to solve this problem.

My two questions are these:
#1 - Why does it work when both objects are running from within the same application?

#2 - I read in one of the other threads that if I remove the method declarations from MyCommand's slice definition, I will no longer need anObjectFactory. Is this true?

For various reasons, an ObjectFactory is not an option for me so I am trying to work around that if at all possible.

Comments

  • benoit
    benoit Rennes, France
    Hi,
    halfhp wrote: »
    My two questions are these:
    #1 - Why does it work when both objects are running from within the same application?

    Most likely, this works because within the same process using the same communicator, the invocations on the transceiver proxies are "collocation optimized" and bypass the marshalling/un-marshalling. See here in the Ice manual for more information on Ice collocation optimization.
    #2 - I read in one of the other threads that if I remove the method declarations from MyCommand's slice definition, I will no longer need anObjectFactory. Is this true?

    For various reasons, an ObjectFactory is not an option for me so I am trying to work around that if at all possible.

    Yes, this is correct. If you remove the getCommandId() method from the MyCommand Slice class, this class will no longer be abstract and no object factory is necessary: Ice can instantiate an instance of MyCommand directly. If you add a method, the class becomes abstract and the communicator can't instantiate anymore a MyCommand instance, instead it needs to instantiate one your concrete implementation of this class and therefore you need to tell the Ice communicator how to instantiate it by registering an object factory.

    Note that if you're using the Java mapping, you can use the ["java:getset"] metadata to have the Slice compiler generate automatically a getter/setter for the attribute. See here for more information on this metadata.

    Cheers,
    Benoit.
  • Thanks Benoit for the great help - completely answers my question. Regarding collocation optimization - I found this:
    For collocated invocations, classes and exceptions are never sliced. Instead, the receiver always receives a class or exception as the derived type that was sent by the sender.
    - You really know your stuff :-)

    Regarding methodless classes, since I would have to give public access to the members of these classes (was using ["protected"]) is there any way to make class members final/const? I know I can make constants outside of classes, but I dont see anything anywhere about constant members.

    Thanks,
    Nick
  • benoit
    benoit Rennes, France
    Hi Nick,

    No, I'm afraid there's currently no way to mark some attributes as const/final.

    Cheers,
    Benoit.