summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichi Henning <michi@zeroc.com>2003-05-23 08:07:40 +0000
committerMichi Henning <michi@zeroc.com>2003-05-23 08:07:40 +0000
commit5c89803b442f059bd7444b286adb3e0a1c4afeca (patch)
treee79bae21964782dc9a89df7ae2d0985caa822c26
parentVC70 install improvements (diff)
downloadice-5c89803b442f059bd7444b286adb3e0a1c4afeca.tar.bz2
ice-5c89803b442f059bd7444b286adb3e0a1c4afeca.tar.xz
ice-5c89803b442f059bd7444b286adb3e0a1c4afeca.zip
Fixed the bug that Benoit found yesterday in both ice and icej.
(Zero-length sequence containing class elements caused an crash.) :Ice::Object). Obviously, this would cause an assertion failure or a {{{ClassCastException}}}. The solution is simply to force the down-cast in the generated patch function and to check whether the cast failed: if so, the class was sliced too much and we throw a {{{NoObjectFactoryException}}} as we should. (For Java, the exception is thrown from {{{BasicStream.readObject}}}, after catching a {{{ClassCastException}}}. For C++, the exception is thrown directly from the generated patch function.) :Ice::Object}}} and {{{::Printer}}}. Updated the code generator to correctly initialize the {{{type}}} member of a {{{NoObjectFactoryException}}} with the type ID of the type that wasn't found. (Unfortunately, this involved modifying {{{Parser.h}}}, so you will have to rebuild both ice and icej.) Added code generation for custom sequence types for icej. Generated code compiles and looks OK, but I haven't written tests yet, so there may still be a latent bug in this.
-rw-r--r--cpp/demo/Ice/value/Client.cpp47
-rw-r--r--cpp/demo/Ice/value/Value.ice1
-rw-r--r--cpp/demo/Ice/value/ValueI.cpp6
-rw-r--r--cpp/demo/Ice/value/ValueI.h1
-rw-r--r--cpp/include/Slice/Parser.h10
-rw-r--r--cpp/src/Slice/JavaUtil.cpp21
-rw-r--r--cpp/src/Slice/Parser.cpp76
-rw-r--r--cpp/src/slice2cpp/Gen.cpp7
-rw-r--r--cpp/src/slice2java/Gen.cpp180
-rw-r--r--java/demo/Ice/value/Client.java46
-rw-r--r--java/demo/Ice/value/InitialI.java6
-rw-r--r--java/demo/Ice/value/Value.ice1
-rw-r--r--java/src/Ice/ObjectHolder.java6
-rw-r--r--java/src/Ice/ObjectImpl.java8
-rw-r--r--java/src/IceInternal/BasicStream.java6
-rw-r--r--java/src/IceInternal/Patcher.java3
16 files changed, 302 insertions, 123 deletions
diff --git a/cpp/demo/Ice/value/Client.cpp b/cpp/demo/Ice/value/Client.cpp
index 408d810a2c1..4626a5e7690 100644
--- a/cpp/demo/Ice/value/Client.cpp
+++ b/cpp/demo/Ice/value/Client.cpp
@@ -52,13 +52,25 @@ run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
cout << '\n'
<< "Ok, this worked. Now let's try to transfer an object for a class\n"
- << "with operations, without installing a factory first. This should\n"
- << "give us a `no factory' exception.\n"
+ << "with operations as type ::Ice::Object. Because no factory is installed,\n"
+ << "the class will be sliced to ::Ice::Object.\n"
+ << "[press enter]\n";
+ cin.getline(&c, 1);
+
+ ::Ice::ObjectPtr obj = initial->getPrinterAsObject();
+ cout << "==> The type ID of the received object is \"" << obj->ice_id() << "\"" << endl;
+ assert(obj->ice_id() == "::Ice::Object");
+
+ cout << '\n'
+ << "Yes, this worked. Now let's try to transfer an object for a class\n"
+ << "with operations as type ::Printer, without installing a factory first.\n"
+ << "This should give us a `no factory' exception.\n"
<< "[press enter]\n";
cin.getline(&c, 1);
PrinterPtr printer;
PrinterPrx printerProxy;
+ bool gotException = false;
try
{
initial->getPrinter(printer, printerProxy);
@@ -66,7 +78,9 @@ run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
catch(const Ice::NoObjectFactoryException& ex)
{
cout << "==> " << ex << endl;
+ gotException = true;
}
+ assert(gotException);
cout << '\n'
<< "Yep, that's what we expected. Now let's try again, but with\n"
@@ -99,28 +113,22 @@ run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
printerProxy->printBackwards();
cout << '\n'
- << "Next, we transfer a derived object from the server as base\n"
- << "object. Since we didn't install a factory for the derived\n"
- << "class yet, we will get another `no factory' exception.\n"
+ << "Next, we transfer a derived object from the server as a base\n"
+ << "object. Since we haven't yet installed a factory for the derived\n"
+ << "class, the derived class (::DerivedPrinter) is sliced\n"
+ << "to its base class (::Printer).\n"
<< "[press enter]\n";
cin.getline(&c, 1);
PrinterPtr derivedAsBase;
- try
- {
- derivedAsBase = initial->getDerivedPrinter();
- assert(false);
- }
- catch(const Ice::NoObjectFactoryException& ex)
- {
- cout << "==> " << ex << endl;
- }
+ derivedAsBase = initial->getDerivedPrinter();
+ cout << "==> The type ID of the received object is \"" << derivedAsBase->ice_id() << "\"" << endl;
+ assert(derivedAsBase->ice_id() == "::Printer");
cout << '\n'
<< "Now we install a factory for the derived class, and try again.\n"
- << "We won't get a `no factory' exception anymore, but since we\n"
- << "receive the derived object as base object, we need to do a\n"
- << "dynamic_cast<> to get from the base to the derived object.\n"
+ << "Because we receive the derived object as a base object, we\n"
+ << "we need to do a dynamic_cast<> to get from the base to the derived object.\n"
<< "[press enter]\n";
cin.getline(&c, 1);
@@ -129,8 +137,8 @@ run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
derivedAsBase = initial->getDerivedPrinter();
DerivedPrinterPtr derived = DerivedPrinterPtr::dynamicCast(derivedAsBase);
assert(derived);
-
cout << "==> dynamic_cast<> to derived object succeded" << endl;
+ cout << "==> The type ID of the received object is \"" << derived->ice_id() << "\"" << endl;
cout << '\n'
<< "Let's print the message contained in the derived object, and\n"
@@ -150,6 +158,7 @@ run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
<< "[press enter]\n";
cin.getline(&c, 1);
+ gotException = false;
try
{
initial->throwDerivedPrinter();
@@ -158,7 +167,9 @@ run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
{
derived = ex.derived;
assert(derived);
+ gotException = true;
}
+ assert(gotException);
cout << "==> " << derived->derivedMessage << endl;
cout << "==> ";
diff --git a/cpp/demo/Ice/value/Value.ice b/cpp/demo/Ice/value/Value.ice
index 3ef695aff55..4a69d6b6a7d 100644
--- a/cpp/demo/Ice/value/Value.ice
+++ b/cpp/demo/Ice/value/Value.ice
@@ -40,6 +40,7 @@ exception DerivedPrinterException
class Initial
{
Simple getSimple();
+ Object getPrinterAsObject();
void getPrinter(out Printer impl, out Printer* proxy);
Printer getDerivedPrinter();
void throwDerivedPrinter() throws DerivedPrinterException;
diff --git a/cpp/demo/Ice/value/ValueI.cpp b/cpp/demo/Ice/value/ValueI.cpp
index fdb34fae120..9c096219ae5 100644
--- a/cpp/demo/Ice/value/ValueI.cpp
+++ b/cpp/demo/Ice/value/ValueI.cpp
@@ -39,6 +39,12 @@ InitialI::getSimple(const Ice::Current&)
return _simple;
}
+::Ice::ObjectPtr
+InitialI::getPrinterAsObject(const Ice::Current&)
+{
+ return _printer;
+}
+
void
InitialI::getPrinter(PrinterPtr& impl, PrinterPrx& proxy, const Ice::Current&)
{
diff --git a/cpp/demo/Ice/value/ValueI.h b/cpp/demo/Ice/value/ValueI.h
index 8e1c811537f..67f2d9ae701 100644
--- a/cpp/demo/Ice/value/ValueI.h
+++ b/cpp/demo/Ice/value/ValueI.h
@@ -24,6 +24,7 @@ public:
InitialI(const Ice::ObjectAdapterPtr&);
virtual SimplePtr getSimple(const Ice::Current&);
+ virtual ::Ice::ObjectPtr getPrinterAsObject(const Ice::Current&);
virtual void getPrinter(PrinterPtr&, PrinterPrx&, const Ice::Current&);
virtual PrinterPtr getDerivedPrinter(const Ice::Current&);
virtual void throwDerivedPrinter(const Ice::Current&);
diff --git a/cpp/include/Slice/Parser.h b/cpp/include/Slice/Parser.h
index db6835e227f..0ab0eed528f 100644
--- a/cpp/include/Slice/Parser.h
+++ b/cpp/include/Slice/Parser.h
@@ -236,6 +236,7 @@ class SLICE_API Type : virtual public SyntaxTreeBase
public:
virtual bool isLocal() const = 0;
+ virtual std::string typeId() const = 0;
virtual bool usesClasses() const = 0;
protected:
@@ -267,6 +268,7 @@ public:
};
virtual bool isLocal() const;
+ virtual std::string typeId() const;
virtual bool usesClasses() const;
Kind kind() const;
@@ -426,7 +428,8 @@ class SLICE_API Constructed : virtual public Type, virtual public Contained
{
public:
- bool isLocal() const;
+ virtual bool isLocal() const;
+ virtual std::string typeId() const;
ConstructedList dependencies();
virtual void recDependencies(std::set<ConstructedPtr>&) = 0; // Internal operation, don't use directly.
@@ -548,7 +551,7 @@ public:
DataMemberList allClassDataMembers() const;
bool isAbstract() const;
bool isInterface() const;
- bool isLocal() const;
+ virtual bool isLocal() const;
bool hasDataMembers() const;
virtual ContainedType containedType() const;
virtual bool uses(const ContainedPtr&) const;
@@ -576,6 +579,7 @@ class SLICE_API Proxy : virtual public Type
public:
virtual bool isLocal() const;
+ virtual std::string typeId() const;
virtual bool usesClasses() const;
ClassDeclPtr _class() const;
@@ -603,7 +607,7 @@ public:
DataMemberList allClassDataMembers() const;
ExceptionPtr base() const;
ExceptionList allBases() const;
- bool isLocal() const;
+ virtual bool isLocal() const;
virtual ContainedType containedType() const;
virtual bool uses(const ContainedPtr&) const;
bool usesClasses() const;
diff --git a/cpp/src/Slice/JavaUtil.cpp b/cpp/src/Slice/JavaUtil.cpp
index 8986ff98b3c..a5b55146e1f 100644
--- a/cpp/src/Slice/JavaUtil.cpp
+++ b/cpp/src/Slice/JavaUtil.cpp
@@ -990,10 +990,25 @@ Slice::JavaGenerator::writeSequenceMarshalUnmarshalCode(Output& out,
out << nl << "for(int __i" << iter << " = 0; __i" << iter << " < __len" << iter << "; __i" << iter
<< "++)";
out << sb;
- out << nl << origContentS << " __elem;";
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(origContent);
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(origContent))
+ {
+ out << nl << v << ".add(null);";
+ ostringstream patchParams;
+ patchParams << v << ", __i" << iter;
+ writeMarshalUnmarshalCode(out, scope, seq->type(), "__elem", false, iter, false,
+ list<string>(), patchParams.str());
+ }
+ else
+ {
+ out << nl << origContentS << " __elem;";
+ writeMarshalUnmarshalCode(out, scope, seq->type(), "__elem", false, iter, false);
+ }
iter++;
- writeMarshalUnmarshalCode(out, scope, seq->type(), "__elem", false, iter, false);
- out << nl << v << ".add(__elem);";
+ if((builtin && builtin->kind() != Builtin::KindObject) && !ClassDeclPtr::dynamicCast(origContent))
+ {
+ out << nl << v << ".add(__elem);";
+ }
out << eb;
}
}
diff --git a/cpp/src/Slice/Parser.cpp b/cpp/src/Slice/Parser.cpp
index 869b9ba115f..f04292a71d5 100644
--- a/cpp/src/Slice/Parser.cpp
+++ b/cpp/src/Slice/Parser.cpp
@@ -84,6 +84,70 @@ Slice::Builtin::isLocal() const
return _kind == KindLocalObject;
}
+string
+Slice::Builtin::typeId() const
+{
+ switch(_kind)
+ {
+ case KindByte:
+ {
+ return "::Ice::Byte";
+ break;
+ }
+ case KindBool:
+ {
+ return "::Ice::Bool";
+ break;
+ }
+ case KindShort:
+ {
+ return "::Ice::Short";
+ break;
+ }
+ case KindInt:
+ {
+ return "::Ice::Int";
+ break;
+ }
+ case KindLong:
+ {
+ return "::Ice::Long";
+ break;
+ }
+ case KindFloat:
+ {
+ return "::Ice::Float";
+ break;
+ }
+ case KindDouble:
+ {
+ return "::Ice::Double";
+ break;
+ }
+ case KindString:
+ {
+ return "::Ice::String";
+ break;
+ }
+ case KindObject:
+ {
+ return "::Ice::Object";
+ break;
+ }
+ case KindObjectProxy:
+ {
+ return "::Ice::Object*";
+ break;
+ }
+ case KindLocalObject:
+ {
+ return "::Ice::LocalObject";
+ break;
+ }
+ }
+ assert(false);
+}
+
bool
Slice::Builtin::usesClasses() const
{
@@ -1612,6 +1676,12 @@ Slice::Constructed::isLocal() const
return _local;
}
+string
+Slice::Constructed::typeId() const
+{
+ return scoped();
+}
+
ConstructedList
Slice::Constructed::dependencies()
{
@@ -2395,6 +2465,12 @@ Slice::Proxy::isLocal() const
return __class->isLocal();
}
+string
+Slice::Proxy::typeId() const
+{
+ return __class->scoped();
+}
+
bool
Slice::Proxy::usesClasses() const
{
diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp
index 6a5de35ff21..97aebb857a4 100644
--- a/cpp/src/slice2cpp/Gen.cpp
+++ b/cpp/src/slice2cpp/Gen.cpp
@@ -2446,7 +2446,12 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p)
C << nl << scope << name << "Ptr* p = static_cast< " << scope << name << "Ptr*>(__addr);";
C << nl << "assert(p);";
C << nl << "*p = " << scope << name << "Ptr::dynamicCast(v);";
- C << nl << "assert(!v || *p);";
+ C << nl << "if(v && !*p)";
+ C << sb;
+ C << nl << "::Ice::NoObjectFactoryException e(__FILE__, __LINE__);";
+ C << nl << "e.type = " << scope << name << "::ice_staticId();";
+ C << nl << "throw e;";
+ C << eb;
C << eb;
C << sp;
diff --git a/cpp/src/slice2java/Gen.cpp b/cpp/src/slice2java/Gen.cpp
index 88295a2bd1e..671e852fa03 100644
--- a/cpp/src/slice2java/Gen.cpp
+++ b/cpp/src/slice2java/Gen.cpp
@@ -1227,59 +1227,6 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p)
out << sb;
-#if 0
- //
- // hashCode
- //
- if(!p->isInterface())
- {
- //
- // Does the class have (or inherit) any data members?
- //
- bool baseHasDataMembers = false;
- ClassList l = p->bases();
- while(!l.empty() && !l.front()->isInterface())
- {
- if(l.front()->hasDataMembers())
- {
- baseHasDataMembers = true;
- break;
- }
- l = l.front()->bases();
- }
-
- if(p->hasDataMembers() || baseHasDataMembers)
- {
- out << sp << nl << "public int" << nl << "hashCode()";
- out << sb;
- if(p->hasDataMembers())
- {
- DataMemberList members = p->dataMembers();
- DataMemberList::const_iterator d;
-
- out << nl << "int __h = 0;";
- int iter = 0;
- for(d = members.begin(); d != members.end(); ++d)
- {
- string memberName = fixKwd((*d)->name());
- list<string> metaData = (*d)->getMetaData();
- writeHashCode(out, (*d)->type(), memberName, iter, metaData);
- }
- if(baseHasDataMembers)
- {
- out << nl << "__h = 5 * __h + super.hashCode();";
- }
- out << nl << "return __h;";
- }
- else
- {
- out << nl << "return super.hashCode();";
- }
- out << eb;
- }
- }
-#endif
-
//
// Default factory for non-abstract classes.
//
@@ -1359,6 +1306,10 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p)
out << nl << "case " << memberCount << ":";
out.inc();
}
+ if(allClassMembers.size() > 1)
+ {
+ out << nl << "__typeId = \"" << (*d)->type()->typeId() << "\";";
+ }
string memberName = fixKwd((*d)->name());
string memberScope = fixKwd((*d)->scope());
string memberType = typeToString((*d)->type(), TypeModeMember, memberScope);
@@ -1374,9 +1325,23 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p)
out << eb;
}
out << eb;
+
+ out << sp << nl << "public String" << nl << "type()";
+ out << sb;
if(allClassMembers.size() > 1)
{
- out << nl << nl << "private int __member;";
+ out << nl << "return __typeId;";
+ }
+ else
+ {
+ out << nl << "return \"" << (*allClassMembers.begin())->type()->typeId() << "\";";
+ }
+ out << eb;
+
+ if(allClassMembers.size() > 1)
+ {
+ out << sp << nl << "private int __member;";
+ out << nl << "private String __typeId;";
}
out << eb;
}
@@ -1561,6 +1526,10 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p)
out << nl << "case " << memberCount << ":";
out.inc();
}
+ if(allClassMembers.size() > 1)
+ {
+ out << nl << "__typeId = \"" << (*d)->type()->typeId() << "\";";
+ }
string memberName = fixKwd((*d)->name());
string memberScope = fixKwd((*d)->scope());
string memberType = typeToString((*d)->type(), TypeModeMember, memberScope);
@@ -1576,9 +1545,22 @@ Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p)
out << eb;
}
out << eb;
+
+ out << sp << nl << "public String" << nl << "type()";
+ out << sb;
+ if(allClassMembers.size() > 1)
+ {
+ out << nl << "return __typeId;";
+ }
+ else
+ {
+ out << nl << "return \"" << (*allClassMembers.begin())->type()->typeId() << "\";";
+ }
+ out << eb;
if(allClassMembers.size() > 1)
{
- out << nl << nl << "private int __member;";
+ out << sp << nl << "private int __member;";
+ out << nl << "private String __typeId;";
}
out << eb;
}
@@ -1862,6 +1844,10 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p)
out << nl << "case " << memberCount << ":";
out.inc();
}
+ if(classMembers.size() > 1)
+ {
+ out << nl << "__typeId = \"" << (*d)->type()->typeId() << "\";";
+ }
string memberName = fixKwd((*d)->name());
string memberScope = fixKwd((*d)->scope());
string memberType = typeToString((*d)->type(), TypeModeMember, memberScope);
@@ -1877,9 +1863,23 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p)
out << eb;
}
out << eb;
+
+ out << sp << nl << "public String" << nl << "type()";
+ out << sb;
+ if(classMembers.size() > 1)
+ {
+ out << nl << "return __typeId;";
+ }
+ else
+ {
+ out << nl << "return \"" << (*classMembers.begin())->type()->typeId() << "\";";
+ }
+ out << eb;
+
if(classMembers.size() > 1)
{
- out << nl << nl << "private int __member;";
+ out << sp << nl << "private int __member;";
+ out << nl << "private String __typeId;";
}
out << eb;
}
@@ -2265,23 +2265,31 @@ Slice::Gen::HolderVisitor::writeHolder(const TypePtr& p)
out << sb;
out << nl << "this.value = value;";
out << eb;
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(p);
- if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(p))
+ if(!p->isLocal())
{
- out << sp << nl << "public class Patcher implements IceInternal.Patcher";
- out << sb;
- out << nl << "public void";
- out << nl << "patch(Ice.Object v)";
- out << sb;
- out << nl << "value = (" << typeS << ")v;";
- out << eb;
- out << eb;
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(p);
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(p))
+ {
+ out << sp << nl << "public class Patcher implements IceInternal.Patcher";
+ out << sb;
+ out << nl << "public void";
+ out << nl << "patch(Ice.Object v)";
+ out << sb;
+ out << nl << "value = (" << typeS << ")v;";
+ out << eb;
- out << sp << nl << "public Patcher";
- out << nl << "getPatcher()";
- out << sb;
- out << nl << "return new Patcher();";
- out << eb;
+ out << sp << nl << "public String" << nl << "type()";
+ out << sb;
+ out << nl << "return \"" << p->typeId() << "\";";
+ out << eb;
+ out << eb;
+
+ out << sp << nl << "public Patcher";
+ out << nl << "getPatcher()";
+ out << sb;
+ out << nl << "return new Patcher();";
+ out << eb;
+ }
}
out << sp << nl << "public " << typeS << " value;";
out << eb;
@@ -2611,9 +2619,12 @@ Slice::Gen::HelperVisitor::visitSequence(const SequencePtr& p)
//
// The sequence has class elements.
//
+ string metaData = findMetaData(p->getMetaData());
+ string listType = metaData.empty() ? typeS : "java.util.List";
+
out << sp << nl << "private static class Patcher implements IceInternal.Patcher";
out << sb;
- out << sp << nl << "Patcher(" << typeS << " values, int index)";
+ out << sp << nl << "Patcher(" << listType << " values, int index)";
out << sb;
out << nl << "__values = values;";
out << nl << "__index = index;";
@@ -2621,10 +2632,23 @@ Slice::Gen::HelperVisitor::visitSequence(const SequencePtr& p)
out << sp << nl << "public void" << nl << "patch(Ice.Object v)";
out << sb;
- out << nl << "__values[__index] = (" << typeToString(p->type(), TypeModeIn, scope) << ")v;";
+ string elmtType = typeToString(p->type(), TypeModeIn, scope);
+ if(metaData.empty())
+ {
+ out << nl << "__values[__index] = (" << elmtType << ")v;";
+ }
+ else
+ {
+ out << nl << "__values.set(__index, (" << elmtType << ")v);";
+ }
out << eb;
- out << sp << nl << "private " << typeS << " __values;";
+ out << sp << nl << "public String" << nl << "type()";
+ out << sb;
+ out << nl << "return \"" << p->type()->typeId() << "\";";
+ out << eb;
+
+ out << sp << nl << "private " << listType << " __values;";
out << nl << "private int __index;";
out << eb;
}
@@ -2633,7 +2657,7 @@ Slice::Gen::HelperVisitor::visitSequence(const SequencePtr& p)
out << sb;
out << nl << typeS << " __v;";
iter = 0;
- writeSequenceMarshalUnmarshalCode(out, scope, p, "__v", false, iter, false);
+ writeSequenceMarshalUnmarshalCode(out, scope, p, "__v", false, iter, false);
out << nl << "return __v;";
out << eb;
@@ -2844,9 +2868,15 @@ Slice::Gen::HelperVisitor::visitDictionary(const DictionaryPtr& p)
out << sp << nl << "public void" << nl << "patch(Ice.Object v)";
out << sb;
+ out << nl << valueS << " _v = (" << valueS << ")v;";
out << nl << "__m.put(__key, v);";
out << eb;
+ out << sp << nl << "public String" << nl << "type()";
+ out << sb;
+ out << nl << "return \"" << value->typeId() << "\";";
+ out << eb;
+
out << sp << nl << "private java.util.Map __m;";
out << nl << "private " << keyTypeS << " __key;";
out << eb;
diff --git a/java/demo/Ice/value/Client.java b/java/demo/Ice/value/Client.java
index bf1a2711cd2..9058936804f 100644
--- a/java/demo/Ice/value/Client.java
+++ b/java/demo/Ice/value/Client.java
@@ -61,13 +61,25 @@ public class Client
System.out.println();
System.out.println("Ok, this worked. Now let's try to transfer an object for a class");
- System.out.println("with operations, without installing a factory first. This should");
- System.out.println("give us a `no factory' exception.");
+ System.out.println("with operations as type Ice.Object. Because no factory is installed,");
+ System.out.println("the class will be sliced to Ice.Object.");
+ System.out.println("[press enter]");
+ readline(in);
+
+ Ice.Object obj = initial.getPrinterAsObject();
+ System.out.println("The type ID of the received object is \"" + obj.ice_id(null) + "\"");
+ assert(obj.ice_id(null).equals("::Ice::Object"));
+
+ System.out.println();
+ System.out.println("Yes, this worked. Now let's try to transfer an object for a class");
+ System.out.println("with operations as type Printer, without installing a factory first.");
+ System.out.println("This should give us a `no factory' exception.");
System.out.println("[press enter]");
readline(in);
PrinterHolder printer = new PrinterHolder();
PrinterPrxHolder printerProxy = new PrinterPrxHolder();
+ boolean gotException = false;
try
{
initial.getPrinter(printer, printerProxy);
@@ -75,7 +87,9 @@ public class Client
catch(Ice.NoObjectFactoryException ex)
{
System.out.println("==> " + ex);
+ gotException = true;
}
+ assert(gotException);
System.out.println();
System.out.println("Yep, that's what we expected. Now let's try again, but with");
@@ -102,34 +116,27 @@ public class Client
System.out.println();
System.out.println("Now we call the same method, but on the remote object. Watch the");
System.out.println("server's output.");
- System.out.println("[press enter]");
+ System.out.println("press enter]");
readline(in);
printerProxy.value.printBackwards();
System.out.println();
System.out.println("Next, we transfer a derived object from the server as base");
- System.out.println("object. Since we didn't install a factory for the derived");
- System.out.println("class yet, we will get another `no factory' exception.");
+ System.out.println("object. Since we haven't yet installed a factory for the derived");
+ System.out.println("class, the derived class (DerivedPrinter) is sliced");
+ System.out.println("to its base class (Printer).");
System.out.println("[press enter]");
readline(in);
- Printer derivedAsBase;
- try
- {
- derivedAsBase = initial.getDerivedPrinter();
- assert(false);
- }
- catch(Ice.NoObjectFactoryException ex)
- {
- System.out.println("==> " + ex);
- }
+ Printer derivedAsBase = initial.getDerivedPrinter();
+ System.out.println("The type ID of the received object is \"" + derivedAsBase.ice_id(null) + "\"");
+ assert(derivedAsBase.ice_id(null).equals("::Printer"));
System.out.println();
System.out.println("Now we install a factory for the derived class, and try again.");
- System.out.println("We won't get a `no factory' exception anymore, but since we");
- System.out.println("receive the derived object as base object, we need to do a");
- System.out.println("dynamic_cast<> to get from the base to the derived object.");
+ System.out.println("Because we receive the derived object as base object,");
+ System.out.println("we need to do a class cast to get from the base to the derived object.");
System.out.println("[press enter]");
readline(in);
@@ -138,7 +145,8 @@ public class Client
derivedAsBase = initial.getDerivedPrinter();
DerivedPrinter derived = (DerivedPrinter)derivedAsBase;
- System.out.println("==> dynamic_cast<> to derived object succeded");
+ System.out.println("==> class cast to derived object succeded");
+ System.out.println("The type ID of the received object is \"" + derived.ice_id(null) + "\"");
System.out.println();
System.out.println("Let's print the message contained in the derived object, and");
diff --git a/java/demo/Ice/value/InitialI.java b/java/demo/Ice/value/InitialI.java
index 2919ec10b64..a7a64a2660d 100644
--- a/java/demo/Ice/value/InitialI.java
+++ b/java/demo/Ice/value/InitialI.java
@@ -37,6 +37,12 @@ class InitialI extends Initial
return _simple;
}
+ public Ice.Object
+ getPrinterAsObject(Ice.Current current)
+ {
+ return _printer;
+ }
+
public void
getPrinter(PrinterHolder impl, PrinterPrxHolder proxy, Ice.Current current)
{
diff --git a/java/demo/Ice/value/Value.ice b/java/demo/Ice/value/Value.ice
index 3ef695aff55..4a69d6b6a7d 100644
--- a/java/demo/Ice/value/Value.ice
+++ b/java/demo/Ice/value/Value.ice
@@ -40,6 +40,7 @@ exception DerivedPrinterException
class Initial
{
Simple getSimple();
+ Object getPrinterAsObject();
void getPrinter(out Printer impl, out Printer* proxy);
Printer getDerivedPrinter();
void throwDerivedPrinter() throws DerivedPrinterException;
diff --git a/java/src/Ice/ObjectHolder.java b/java/src/Ice/ObjectHolder.java
index 9d1ad91e088..5d88becf0b9 100644
--- a/java/src/Ice/ObjectHolder.java
+++ b/java/src/Ice/ObjectHolder.java
@@ -34,6 +34,12 @@ public final class ObjectHolder
{
value = v;
}
+
+ public String
+ type()
+ {
+ return Ice.ObjectImpl.ice_staticId();
+ }
}
public Patcher
diff --git a/java/src/Ice/ObjectImpl.java b/java/src/Ice/ObjectImpl.java
index 551ae4de307..eec827b0217 100644
--- a/java/src/Ice/ObjectImpl.java
+++ b/java/src/Ice/ObjectImpl.java
@@ -198,7 +198,7 @@ public class ObjectImpl implements Object, java.lang.Cloneable
{
synchronized(_activeFacetMap)
{
- __os.writeTypeId("::Ice::Object");
+ __os.writeTypeId(ice_staticId());
__os.startWriteSlice();
final int sz = _activeFacetMap.size();
__os.writeSize(sz);
@@ -228,6 +228,12 @@ public class ObjectImpl implements Object, java.lang.Cloneable
_activeFacetMap.put(__key, v);
}
+ public String
+ type()
+ {
+ return ice_staticId();
+ }
+
private String __key;
}
diff --git a/java/src/IceInternal/BasicStream.java b/java/src/IceInternal/BasicStream.java
index c157d980dae..09e68ff2f9a 100644
--- a/java/src/IceInternal/BasicStream.java
+++ b/java/src/IceInternal/BasicStream.java
@@ -1116,7 +1116,7 @@ public class BasicStream
while(true)
{
String id = readTypeId();
- if(id.equals("::Ice::Object"))
+ if(id.equals(Ice.ObjectImpl.ice_staticId()))
{
v = new Ice.ObjectImpl();
}
@@ -1323,7 +1323,9 @@ public class BasicStream
}
catch(ClassCastException ex)
{
- throw new Ice.UnmarshalOutOfBoundsException();
+ Ice.NoObjectFactoryException nof = new Ice.NoObjectFactoryException();
+ nof.type = p.type();
+ throw nof;
}
}
diff --git a/java/src/IceInternal/Patcher.java b/java/src/IceInternal/Patcher.java
index 11fdbf06adb..b5e30377bd0 100644
--- a/java/src/IceInternal/Patcher.java
+++ b/java/src/IceInternal/Patcher.java
@@ -17,4 +17,5 @@ package IceInternal;
public interface Patcher
{
void patch(Ice.Object v);
-};
+ String type();
+}