summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2004-02-24 01:17:01 +0000
committerMark Spruiell <mes@zeroc.com>2004-02-24 01:17:01 +0000
commit77a6cfbb8aad38be3d323f628681b0359f38f38e (patch)
treed332cb72abaaf71ed5580181494b0dd19ad36e59
parentcerts (diff)
downloadice-77a6cfbb8aad38be3d323f628681b0359f38f38e.tar.bz2
ice-77a6cfbb8aad38be3d323f628681b0359f38f38e.tar.xz
ice-77a6cfbb8aad38be3d323f628681b0359f38f38e.zip
adding ice_preMarshal/ice_postUnmarshal, and tests in Ice/objects
-rw-r--r--cpp/CHANGES15
-rw-r--r--cpp/include/Ice/BasicStream.h4
-rw-r--r--cpp/include/Ice/Object.h3
-rw-r--r--cpp/src/Ice/BasicStream.cpp67
-rw-r--r--cpp/src/Ice/Object.cpp10
-rw-r--r--cpp/test/Ice/objects/AllTests.cpp20
-rw-r--r--cpp/test/Ice/objects/Client.cpp8
-rw-r--r--cpp/test/Ice/objects/Makefile7
-rw-r--r--cpp/test/Ice/objects/Test.ice9
-rw-r--r--cpp/test/Ice/objects/TestI.cpp94
-rw-r--r--cpp/test/Ice/objects/TestI.h48
-rw-r--r--java/CHANGES17
-rw-r--r--java/src/Ice/Object.java3
-rw-r--r--java/src/Ice/ObjectImpl.java10
-rw-r--r--java/src/IceInternal/BasicStream.java66
-rw-r--r--java/test/Ice/objects/AllTests.java20
-rw-r--r--java/test/Ice/objects/Client.java36
-rw-r--r--java/test/Ice/objects/InitialI.java25
-rw-r--r--java/test/Ice/objects/Test.ice9
19 files changed, 440 insertions, 31 deletions
diff --git a/cpp/CHANGES b/cpp/CHANGES
index 669c9896004..d965a92b6d0 100644
--- a/cpp/CHANGES
+++ b/cpp/CHANGES
@@ -1,7 +1,12 @@
Changes since version 1.2.0
---------------------------
-- Added the demo/IcePack/simple demo.
+- Added the virtual member functions ice_preMarshal and
+ ice_postUnmarshal to Ice::Object. The default implementations do
+ nothing, but subclasses may override them to take special action
+ before marshaling and after unmarshaling, respectively.
+
+- Added the demo/IcePack/simple example.
- Fixed a bug in IcePack that could cause the node to crash if a
server failed to start.
@@ -9,8 +14,8 @@ Changes since version 1.2.0
- IceBox services deployed with IcePack are now loaded in the order
they appear in the XML IceBox descriptor.
-- Connections are now not closed anymore when that last proxy using
- the connection is destroyed. Doing so is error prone:
+- Connections are no longer closed when the last proxy using the
+ connection is destroyed. Doing so is error prone:
* Quite often, proxies are created on the fly, resulting in
connections being opened and closed all the time. This is
@@ -23,8 +28,8 @@ Changes since version 1.2.0
* It doesn't work well with AMI requests, because the AMI callback
objects keep track of connections directly. This would mean that
if a process only uses AMI requests, a connection is opened and
- closed for each such request, as each request typically has its
- own AMI callback object.
+ closed for each request, as each request typically has its own
+ AMI callback object.
Instead, ACM (Automatic Connection Management) is now enabled by
default, with a default value of one minute. This means that idle
diff --git a/cpp/include/Ice/BasicStream.h b/cpp/include/Ice/BasicStream.h
index 161a5861168..4a799f84245 100644
--- a/cpp/include/Ice/BasicStream.h
+++ b/cpp/include/Ice/BasicStream.h
@@ -189,6 +189,8 @@ public:
typedef std::map<Ice::ObjectPtr, Ice::Int> PtrToIndexMap;
typedef std::map<std::string, Ice::Int> TypeIdWriteMap;
+ typedef std::vector<Ice::ObjectPtr> ObjectList;
+
private:
//
@@ -260,6 +262,8 @@ private:
bool _sliceObjects;
const Container::size_type _messageSizeMax;
+
+ ObjectList* _objectList;
};
}
diff --git a/cpp/include/Ice/Object.h b/cpp/include/Ice/Object.h
index 9e1a24d9616..321974b0680 100644
--- a/cpp/include/Ice/Object.h
+++ b/cpp/include/Ice/Object.h
@@ -79,6 +79,9 @@ public:
void __copyMembers(::Ice::ObjectPtr) const;
virtual ::Ice::ObjectPtr ice_clone() const;
+ virtual void ice_preMarshal();
+ virtual void ice_postUnmarshal();
+
static ::std::string __all[];
virtual ::IceInternal::DispatchStatus __dispatch(::IceInternal::Incoming&, const Current&);
diff --git a/cpp/src/Ice/BasicStream.cpp b/cpp/src/Ice/BasicStream.cpp
index 24d9ea4bbda..179bb853e04 100644
--- a/cpp/src/Ice/BasicStream.cpp
+++ b/cpp/src/Ice/BasicStream.cpp
@@ -25,6 +25,7 @@
#include <Ice/FactoryTable.h>
#include <Ice/TraceUtil.h>
#include <Ice/TraceLevels.h>
+#include <Ice/LoggerUtil.h>
template<typename InputIter, typename OutputIter>
inline void
@@ -55,7 +56,8 @@ IceInternal::BasicStream::BasicStream(Instance* instance) :
_traceSlicing(-1),
_marshalFacets(true),
_sliceObjects(true),
- _messageSizeMax(_instance->messageSizeMax()) // Cached for efficiency.
+ _messageSizeMax(_instance->messageSizeMax()), // Cached for efficiency.
+ _objectList(0)
{
}
@@ -74,6 +76,8 @@ IceInternal::BasicStream::~BasicStream()
_currentWriteEncaps = _currentWriteEncaps->previous;
delete oldEncaps;
}
+
+ delete _objectList;
}
Instance*
@@ -91,6 +95,7 @@ IceInternal::BasicStream::swap(BasicStream& other)
std::swap(i, other.i);
std::swap(_currentReadEncaps, other._currentReadEncaps);
std::swap(_currentWriteEncaps, other._currentWriteEncaps);
+ std::swap(_objectList, other._objectList);
}
void
@@ -1312,6 +1317,16 @@ IceInternal::BasicStream::read(PatchFunc patchFunc, void* patchAddr)
IndexToPtrMap::const_iterator unmarshaledPos =
_currentReadEncaps->unmarshaledMap->insert(make_pair(index, v)).first;
+ //
+ // Record each object instance so that readPendingObjects can invoke ice_postUnmarshal
+ // after all objects have been unmarshaled.
+ //
+ if(!_objectList)
+ {
+ _objectList = new ObjectList;
+ }
+ _objectList->push_back(v);
+
v->__read(this, false);
patchPointers(index, unmarshaledPos, _currentReadEncaps->patchMap->end());
return;
@@ -1449,6 +1464,37 @@ IceInternal::BasicStream::readPendingObjects()
}
}
while(num);
+
+ //
+ // Iterate over the object list and invoke ice_postUnmarshal on each object.
+ // We must do this after all objects have been unmarshaled in order to ensure
+ // that any object data members have been properly patched.
+ //
+ if(_objectList)
+ {
+ for(ObjectList::iterator p = _objectList->begin(); p != _objectList->end(); ++p)
+ {
+ try
+ {
+ (*p)->ice_postUnmarshal();
+ }
+ catch(const Ice::Exception& ex)
+ {
+ Ice::Warning out(_instance->logger());
+ out << "Ice::Exception raised by ice_postUnmarshal:\n" << ex;
+ }
+ catch(const std::exception& ex)
+ {
+ Ice::Warning out(_instance->logger());
+ out << "std::exception raised by ice_postUnmarshal:\n" << ex.what();
+ }
+ catch(...)
+ {
+ Ice::Warning out(_instance->logger());
+ out << "unknown exception raised by ice_postUnmarshal";
+ }
+ }
+ }
}
void
@@ -1479,6 +1525,25 @@ void
IceInternal::BasicStream::writeInstance(const ObjectPtr& v, Int index)
{
write(index);
+ try
+ {
+ v->ice_preMarshal();
+ }
+ catch(const Ice::Exception& ex)
+ {
+ Ice::Warning out(_instance->logger());
+ out << "Ice::Exception raised by ice_preMarshal:\n" << ex;
+ }
+ catch(const std::exception& ex)
+ {
+ Ice::Warning out(_instance->logger());
+ out << "std::exception raised by ice_preMarshal:\n" << ex.what();
+ }
+ catch(...)
+ {
+ Ice::Warning out(_instance->logger());
+ out << "unknown exception raised by ice_preMarshal";
+ }
v->__write(this, _marshalFacets);
}
diff --git a/cpp/src/Ice/Object.cpp b/cpp/src/Ice/Object.cpp
index 123370949ed..20cc3371795 100644
--- a/cpp/src/Ice/Object.cpp
+++ b/cpp/src/Ice/Object.cpp
@@ -122,6 +122,16 @@ Ice::Object::ice_clone() const
return __p;
}
+void
+Ice::Object::ice_preMarshal()
+{
+}
+
+void
+Ice::Object::ice_postUnmarshal()
+{
+}
+
DispatchStatus
Ice::Object::___ice_isA(Incoming& __in, const Current& __current)
{
diff --git a/cpp/test/Ice/objects/AllTests.cpp b/cpp/test/Ice/objects/AllTests.cpp
index 53ab064d30e..4e6b4cb2ebc 100644
--- a/cpp/test/Ice/objects/AllTests.cpp
+++ b/cpp/test/Ice/objects/AllTests.cpp
@@ -67,6 +67,15 @@ allTests(const Ice::CommunicatorPtr& communicator, bool collocated)
test(BPtr::dynamicCast(b1->theA)->theB == b1);
test(CPtr::dynamicCast(BPtr::dynamicCast(b1->theA)->theC));
test(CPtr::dynamicCast(BPtr::dynamicCast(b1->theA)->theC)->theB == b1->theA);
+ if(!collocated)
+ {
+ test(b1->preMarshalInvoked);
+ test(b1->postUnmarshalInvoked());
+ test(b1->theA->preMarshalInvoked);
+ test(b1->theA->postUnmarshalInvoked());
+ test(BPtr::dynamicCast(b1->theA)->theC->preMarshalInvoked);
+ test(BPtr::dynamicCast(b1->theA)->theC->postUnmarshalInvoked());
+ }
// More tests possible for b2 and d, but I think this is already sufficient.
test(b2->theA == b2);
test(d->theC == 0);
@@ -127,6 +136,17 @@ allTests(const Ice::CommunicatorPtr& communicator, bool collocated)
test(d->theA == b1);
test(d->theB == b2);
test(d->theC == 0);
+ if(!collocated)
+ {
+ test(d->preMarshalInvoked);
+ test(d->postUnmarshalInvoked());
+ test(d->theA->preMarshalInvoked);
+ test(d->theA->postUnmarshalInvoked());
+ test(d->theB->preMarshalInvoked);
+ test(d->theB->postUnmarshalInvoked());
+ test(d->theB->theC->preMarshalInvoked);
+ test(d->theB->theC->postUnmarshalInvoked());
+ }
cout << "ok" << endl;
//
diff --git a/cpp/test/Ice/objects/Client.cpp b/cpp/test/Ice/objects/Client.cpp
index 9a6a80c1873..2eea6e63466 100644
--- a/cpp/test/Ice/objects/Client.cpp
+++ b/cpp/test/Ice/objects/Client.cpp
@@ -14,7 +14,7 @@
#include <Ice/Ice.h>
#include <TestCommon.h>
-#include <Test.h>
+#include <TestI.h>
using namespace std;
@@ -26,15 +26,15 @@ public:
{
if(type == "::B")
{
- return new B;
+ return new BI;
}
else if(type == "::C")
{
- return new C;
+ return new CI;
}
else if(type == "::D")
{
- return new D;
+ return new DI;
}
assert(false); // Should never be reached
return 0;
diff --git a/cpp/test/Ice/objects/Makefile b/cpp/test/Ice/objects/Makefile
index f3502da1d93..9f7c5f346b7 100644
--- a/cpp/test/Ice/objects/Makefile
+++ b/cpp/test/Ice/objects/Makefile
@@ -21,15 +21,14 @@ COLLOCATED = collocated
TARGETS = $(CLIENT) $(SERVER) $(COLLOCATED)
OBJS = Test.o \
+ TestI.o
COBJS = Client.o \
AllTests.o
-SOBJS = TestI.o \
- Server.o
+SOBJS = Server.o
-COLOBJS = TestI.o \
- Collocated.o \
+COLOBJS = Collocated.o \
AllTests.o
SRCS = $(OBJS:.o=.cpp) \
diff --git a/cpp/test/Ice/objects/Test.ice b/cpp/test/Ice/objects/Test.ice
index e1d696af92c..c6c94c810ee 100644
--- a/cpp/test/Ice/objects/Test.ice
+++ b/cpp/test/Ice/objects/Test.ice
@@ -22,6 +22,9 @@ class A
{
B theB;
C theC;
+
+ bool preMarshalInvoked;
+ bool postUnmarshalInvoked();
};
class B extends A
@@ -32,6 +35,9 @@ class B extends A
class C
{
B theB;
+
+ bool preMarshalInvoked;
+ bool postUnmarshalInvoked();
};
class D
@@ -39,6 +45,9 @@ class D
A theA;
B theB;
C theC;
+
+ bool preMarshalInvoked;
+ bool postUnmarshalInvoked();
};
class Initial
diff --git a/cpp/test/Ice/objects/TestI.cpp b/cpp/test/Ice/objects/TestI.cpp
index ef961501878..5dd46076762 100644
--- a/cpp/test/Ice/objects/TestI.cpp
+++ b/cpp/test/Ice/objects/TestI.cpp
@@ -15,12 +15,81 @@
#include <Ice/Ice.h>
#include <TestI.h>
+BI::BI() :
+ _postUnmarshalInvoked(false)
+{
+}
+
+bool
+BI::postUnmarshalInvoked(const Ice::Current&)
+{
+ return _postUnmarshalInvoked;
+}
+
+void
+BI::ice_preMarshal()
+{
+ preMarshalInvoked = true;
+}
+
+void
+BI::ice_postUnmarshal()
+{
+ _postUnmarshalInvoked = true;
+}
+
+CI::CI() :
+ _postUnmarshalInvoked(false)
+{
+}
+
+bool
+CI::postUnmarshalInvoked(const Ice::Current&)
+{
+ return _postUnmarshalInvoked;
+}
+
+void
+CI::ice_preMarshal()
+{
+ preMarshalInvoked = true;
+}
+
+void
+CI::ice_postUnmarshal()
+{
+ _postUnmarshalInvoked = true;
+}
+
+DI::DI() :
+ _postUnmarshalInvoked(false)
+{
+}
+
+bool
+DI::postUnmarshalInvoked(const Ice::Current&)
+{
+ return _postUnmarshalInvoked;
+}
+
+void
+DI::ice_preMarshal()
+{
+ preMarshalInvoked = true;
+}
+
+void
+DI::ice_postUnmarshal()
+{
+ _postUnmarshalInvoked = true;
+}
+
InitialI::InitialI(const Ice::ObjectAdapterPtr& adapter) :
_adapter(adapter),
- _b1(new B),
- _b2(new B),
- _c(new C),
- _d(new D)
+ _b1(new BI),
+ _b2(new BI),
+ _c(new CI),
+ _d(new DI)
{
_b1->theA = _b2; // Cyclic reference to another B
_b1->theB = _b1; // Self reference.
@@ -64,30 +133,47 @@ InitialI::shutdown(const Ice::Current&)
BPtr
InitialI::getB1(const Ice::Current&)
{
+ _b1->preMarshalInvoked = false;
+ _b2->preMarshalInvoked = false;
+ _c->preMarshalInvoked = false;
return _b1;
}
BPtr
InitialI::getB2(const Ice::Current&)
{
+ _b1->preMarshalInvoked = false;
+ _b2->preMarshalInvoked = false;
+ _c->preMarshalInvoked = false;
return _b2;
}
CPtr
InitialI::getC(const Ice::Current&)
{
+ _b1->preMarshalInvoked = false;
+ _b2->preMarshalInvoked = false;
+ _c->preMarshalInvoked = false;
return _c;
}
DPtr
InitialI::getD(const Ice::Current&)
{
+ _b1->preMarshalInvoked = false;
+ _b2->preMarshalInvoked = false;
+ _c->preMarshalInvoked = false;
+ _d->preMarshalInvoked = false;
return _d;
}
void
InitialI::getAll(BPtr& b1, BPtr& b2, CPtr& c, DPtr& d, const Ice::Current&)
{
+ _b1->preMarshalInvoked = false;
+ _b2->preMarshalInvoked = false;
+ _c->preMarshalInvoked = false;
+ _d->preMarshalInvoked = false;
b1 = _b1;
b2 = _b2;
c = _c;
diff --git a/cpp/test/Ice/objects/TestI.h b/cpp/test/Ice/objects/TestI.h
index f21e677677f..b03ff8d43b3 100644
--- a/cpp/test/Ice/objects/TestI.h
+++ b/cpp/test/Ice/objects/TestI.h
@@ -17,6 +17,54 @@
#include <Test.h>
+class BI : public B
+{
+public:
+
+ BI();
+
+ virtual bool postUnmarshalInvoked(const Ice::Current&);
+
+ virtual void ice_preMarshal();
+ virtual void ice_postUnmarshal();
+
+private:
+
+ bool _postUnmarshalInvoked;
+};
+
+class CI : public C
+{
+public:
+
+ CI();
+
+ virtual bool postUnmarshalInvoked(const Ice::Current&);
+
+ virtual void ice_preMarshal();
+ virtual void ice_postUnmarshal();
+
+private:
+
+ bool _postUnmarshalInvoked;
+};
+
+class DI : public D
+{
+public:
+
+ DI();
+
+ virtual bool postUnmarshalInvoked(const Ice::Current&);
+
+ virtual void ice_preMarshal();
+ virtual void ice_postUnmarshal();
+
+private:
+
+ bool _postUnmarshalInvoked;
+};
+
class InitialI : public Initial
{
public:
diff --git a/java/CHANGES b/java/CHANGES
index 7ed5065a87a..f3cf3e5027c 100644
--- a/java/CHANGES
+++ b/java/CHANGES
@@ -1,8 +1,15 @@
Changes since version 1.2.0
---------------------------
-- Connections are now not closed anymore when that last proxy using
- the connection is destroyed. Doing so is error prone:
+- Added the methods ice_preMarshal and ice_postUnmarshal to Ice.Object.
+ The default implementations do nothing, but subclasses may override
+ them to take special action before marshaling and after unmarshaling,
+ respectively.
+
+- Added the demo/IcePack/simple example.
+
+- Connections are no longer closed when the last proxy using the
+ connection is destroyed. Doing so is error prone:
* Quite often, proxies are created on the fly, resulting in
connections being opened and closed all the time. This is
@@ -15,8 +22,8 @@ Changes since version 1.2.0
* It doesn't work well with AMI requests, because the AMI callback
objects keep track of connections directly. This would mean that
if a process only uses AMI requests, a connection is opened and
- closed for each such request, as each request typically has its
- own AMI callback object.
+ closed for each request, as each request typically has its own
+ AMI callback object.
Instead, ACM (Automatic Connection Management) is now enabled by
default, with a default value of one minute. This means that idle
@@ -47,7 +54,7 @@ Changes since version 1.2.0
messages are sent rapidly in parallel, using separate threads or
AMI.
-- Ported IcePack demo from C++.
+- Ported demo/IcePack/hello from C++.
- Added new mechanism for generating Java code into packages.
The global metadata prefix "java:package:" now specifies the
diff --git a/java/src/Ice/Object.java b/java/src/Ice/Object.java
index eac98105262..ecd382e9719 100644
--- a/java/src/Ice/Object.java
+++ b/java/src/Ice/Object.java
@@ -32,6 +32,9 @@ public interface Object
String[] ice_facets(Current current);
+ void ice_preMarshal();
+ void ice_postUnmarshal();
+
IceInternal.DispatchStatus __dispatch(IceInternal.Incoming in, Current current);
void __write(IceInternal.BasicStream __os, boolean __marshalFacets);
diff --git a/java/src/Ice/ObjectImpl.java b/java/src/Ice/ObjectImpl.java
index adbe1191736..5e4abee7585 100644
--- a/java/src/Ice/ObjectImpl.java
+++ b/java/src/Ice/ObjectImpl.java
@@ -147,6 +147,16 @@ public class ObjectImpl implements Object, java.lang.Cloneable
return __ids[0];
}
+ public void
+ ice_preMarshal()
+ {
+ }
+
+ public void
+ ice_postUnmarshal()
+ {
+ }
+
private final static String[] __all =
{
"ice_facets",
diff --git a/java/src/IceInternal/BasicStream.java b/java/src/IceInternal/BasicStream.java
index 7226a5c296a..ae2887b7a29 100644
--- a/java/src/IceInternal/BasicStream.java
+++ b/java/src/IceInternal/BasicStream.java
@@ -38,6 +38,8 @@ public class BasicStream
_sliceObjects = true;
_messageSizeMax = _instance.messageSizeMax(); // Cached for efficiency.
+
+ _objectList = null;
}
//
@@ -70,6 +72,11 @@ public class BasicStream
_readEncapsCache = _readEncapsStack;
_readEncapsStack = null;
}
+
+ if(_objectList != null)
+ {
+ _objectList.clear();
+ }
}
public IceInternal.Instance
@@ -118,6 +125,10 @@ public class BasicStream
int tmpWriteSlice = other._writeSlice;
other._writeSlice = _writeSlice;
_writeSlice = tmpWriteSlice;
+
+ java.util.ArrayList tmpObjectList = other._objectList;
+ other._objectList = _objectList;
+ _objectList = tmpObjectList;
}
public void
@@ -1190,6 +1201,17 @@ public class BasicStream
Integer i = new Integer(index);
_readEncapsStack.unmarshaledMap.put(i, v);
+
+ //
+ // Record each object instance so that readPendingObjects can invoke ice_postUnmarshal
+ // after all objects have been unmarshaled.
+ //
+ if(_objectList == null)
+ {
+ _objectList = new java.util.ArrayList();
+ }
+ _objectList.add(v);
+
v.__read(this, false);
patchReferences(i, null);
return;
@@ -1321,6 +1343,33 @@ public class BasicStream
}
}
while(num > 0);
+
+ //
+ // Iterate over unmarshaledMap and invoke ice_postUnmarshal on each object.
+ // We must do this after all objects in this encapsulation have been
+ // unmarshaled in order to ensure that any object data members have been
+ // properly patched.
+ //
+ java.util.Iterator e = _objectList.iterator();
+ while(e.hasNext())
+ {
+ Ice.Object obj = (Ice.Object)e.next();
+ try
+ {
+ obj.ice_postUnmarshal();
+ }
+ catch(Exception ex)
+ {
+ java.io.StringWriter sw = new java.io.StringWriter();
+ java.io.PrintWriter pw = new java.io.PrintWriter(sw);
+ IceUtil.OutputBase out = new IceUtil.OutputBase(pw);
+ out.setUseTab(false);
+ out.print("exception raised by ice_postUnmarshal:\n");
+ ex.printStackTrace(pw);
+ pw.flush();
+ _instance.logger().warning(sw.toString());
+ }
+ }
}
public void
@@ -1339,6 +1388,21 @@ public class BasicStream
writeInstance(Ice.Object v, Integer index)
{
writeInt(index.intValue());
+ try
+ {
+ v.ice_preMarshal();
+ }
+ catch(Exception ex)
+ {
+ java.io.StringWriter sw = new java.io.StringWriter();
+ java.io.PrintWriter pw = new java.io.PrintWriter(sw);
+ IceUtil.OutputBase out = new IceUtil.OutputBase(pw);
+ out.setUseTab(false);
+ out.print("exception raised by ice_preMarshal:\n");
+ ex.printStackTrace(pw);
+ pw.flush();
+ _instance.logger().warning(sw.toString());
+ }
v.__write(this, _marshalFacets);
}
@@ -1673,4 +1737,6 @@ public class BasicStream
private boolean _sliceObjects;
private int _messageSizeMax;
+
+ private java.util.ArrayList _objectList;
}
diff --git a/java/test/Ice/objects/AllTests.java b/java/test/Ice/objects/AllTests.java
index a24e22f2ddf..19522a13c38 100644
--- a/java/test/Ice/objects/AllTests.java
+++ b/java/test/Ice/objects/AllTests.java
@@ -79,6 +79,15 @@ public class AllTests
test(((B)b1.theA).theB == b1);
test(((B)b1.theA).theC instanceof C);
test(((C)(((B)b1.theA).theC)).theB == b1.theA);
+ if(!collocated)
+ {
+ test(b1.preMarshalInvoked);
+ test(b1.postUnmarshalInvoked(null));
+ test(b1.theA.preMarshalInvoked);
+ test(b1.theA.postUnmarshalInvoked(null));
+ test(((B)b1.theA).theC.preMarshalInvoked);
+ test(((B)b1.theA).theC.postUnmarshalInvoked(null));
+ }
// More tests possible for b2 and d, but I think this is already
// sufficient.
test(b2.theA == b2);
@@ -150,6 +159,17 @@ public class AllTests
test(d.theA == b1);
test(d.theB == b2);
test(d.theC == null);
+ if(!collocated)
+ {
+ test(d.preMarshalInvoked);
+ test(d.postUnmarshalInvoked(null));
+ test(d.theA.preMarshalInvoked);
+ test(d.theA.postUnmarshalInvoked(null));
+ test(d.theB.preMarshalInvoked);
+ test(d.theB.postUnmarshalInvoked(null));
+ test(d.theB.theC.preMarshalInvoked);
+ test(d.theB.theC.postUnmarshalInvoked(null));
+ }
System.out.println("ok");
//
diff --git a/java/test/Ice/objects/Client.java b/java/test/Ice/objects/Client.java
index d9236d0d86f..b44c3ffe7ea 100644
--- a/java/test/Ice/objects/Client.java
+++ b/java/test/Ice/objects/Client.java
@@ -14,13 +14,41 @@
public class Client
{
+ private static class MyObjectFactory extends Ice.LocalObjectImpl implements Ice.ObjectFactory
+ {
+ public Ice.Object
+ create(String type)
+ {
+ if(type.equals("::B"))
+ {
+ return new BI();
+ }
+ else if(type.equals("::C"))
+ {
+ return new CI();
+ }
+ else if(type.equals("::D"))
+ {
+ return new DI();
+ }
+ assert(false); // Should never be reached
+ return null;
+ }
+
+ public void
+ destroy()
+ {
+ // Nothing to do
+ }
+ }
+
private static int
run(String[] args, Ice.Communicator communicator)
{
- //
- // NOTE: Factories do not need to be explicitly installed
- // in Java.
- //
+ Ice.ObjectFactory factory = new MyObjectFactory();
+ communicator.addObjectFactory(factory, "::B");
+ communicator.addObjectFactory(factory, "::C");
+ communicator.addObjectFactory(factory, "::D");
InitialPrx initial = AllTests.allTests(communicator, false);
initial.shutdown();
diff --git a/java/test/Ice/objects/InitialI.java b/java/test/Ice/objects/InitialI.java
index 13504dd5b01..62fe6ff019a 100644
--- a/java/test/Ice/objects/InitialI.java
+++ b/java/test/Ice/objects/InitialI.java
@@ -18,10 +18,10 @@ public final class InitialI extends Initial
InitialI(Ice.ObjectAdapter adapter)
{
_adapter = adapter;
- _b1 = new B();
- _b2 = new B();
- _c = new C();
- _d = new D();
+ _b1 = new BI();
+ _b2 = new BI();
+ _c = new CI();
+ _d = new DI();
_b1.theA = _b2; // Cyclic reference to another B
_b1.theB = _b1; // Self reference.
@@ -50,6 +50,10 @@ public final class InitialI extends Initial
public void
getAll(BHolder b1, BHolder b2, CHolder c, DHolder d, Ice.Current current)
{
+ _b1.preMarshalInvoked = false;
+ _b2.preMarshalInvoked = false;
+ _c.preMarshalInvoked = false;
+ _d.preMarshalInvoked = false;
b1.value = _b1;
b2.value = _b2;
c.value = _c;
@@ -59,24 +63,37 @@ public final class InitialI extends Initial
public B
getB1(Ice.Current current)
{
+ _b1.preMarshalInvoked = false;
+ _b2.preMarshalInvoked = false;
+ _c.preMarshalInvoked = false;
return _b1;
}
public B
getB2(Ice.Current current)
{
+ _b1.preMarshalInvoked = false;
+ _b2.preMarshalInvoked = false;
+ _c.preMarshalInvoked = false;
return _b2;
}
public C
getC(Ice.Current current)
{
+ _b1.preMarshalInvoked = false;
+ _b2.preMarshalInvoked = false;
+ _c.preMarshalInvoked = false;
return _c;
}
public D
getD(Ice.Current current)
{
+ _b1.preMarshalInvoked = false;
+ _b2.preMarshalInvoked = false;
+ _c.preMarshalInvoked = false;
+ _d.preMarshalInvoked = false;
return _d;
}
diff --git a/java/test/Ice/objects/Test.ice b/java/test/Ice/objects/Test.ice
index e1d696af92c..c6c94c810ee 100644
--- a/java/test/Ice/objects/Test.ice
+++ b/java/test/Ice/objects/Test.ice
@@ -22,6 +22,9 @@ class A
{
B theB;
C theC;
+
+ bool preMarshalInvoked;
+ bool postUnmarshalInvoked();
};
class B extends A
@@ -32,6 +35,9 @@ class B extends A
class C
{
B theB;
+
+ bool preMarshalInvoked;
+ bool postUnmarshalInvoked();
};
class D
@@ -39,6 +45,9 @@ class D
A theA;
B theB;
C theC;
+
+ bool preMarshalInvoked;
+ bool postUnmarshalInvoked();
};
class Initial