summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2019-07-11 17:42:59 +0200
committerBenoit Foucher <benoit@zeroc.com>2019-07-11 17:42:59 +0200
commitbcd2c2d1b01e721be924b96247be86384ddc9738 (patch)
tree7b84ec6832dc13c548fe7d3c7098675c61bb06ec
parentFix .gitignore syntax (diff)
downloadice-bcd2c2d1b01e721be924b96247be86384ddc9738.tar.bz2
ice-bcd2c2d1b01e721be924b96247be86384ddc9738.tar.xz
ice-bcd2c2d1b01e721be924b96247be86384ddc9738.zip
Fixed dispatcher interceptor bug #435
-rw-r--r--cpp/src/Ice/DispatchInterceptor.cpp13
-rw-r--r--cpp/src/Ice/Incoming.cpp2
-rw-r--r--cpp/test/Ice/interceptor/AMDInterceptorI.cpp38
-rw-r--r--cpp/test/Ice/interceptor/Client.cpp55
-rw-r--r--cpp/test/Ice/interceptor/InterceptorI.cpp39
-rw-r--r--csharp/src/Ice/DispatchInterceptor.cs18
-rw-r--r--csharp/test/Ice/interceptor/Client.cs56
-rw-r--r--csharp/test/Ice/interceptor/InterceptorI.cs35
-rw-r--r--java-compat/src/Ice/src/main/java/Ice/DispatchInterceptor.java13
-rw-r--r--java-compat/test/src/main/java/test/Ice/interceptor/AMDInterceptorI.java37
-rw-r--r--java-compat/test/src/main/java/test/Ice/interceptor/Client.java66
-rw-r--r--java-compat/test/src/main/java/test/Ice/interceptor/InterceptorI.java37
-rw-r--r--java/src/Ice/src/main/java/com/zeroc/Ice/DispatchInterceptor.java18
-rw-r--r--java/test/src/main/java/test/Ice/interceptor/Client.java66
-rw-r--r--java/test/src/main/java/test/Ice/interceptor/InterceptorI.java36
15 files changed, 525 insertions, 4 deletions
diff --git a/cpp/src/Ice/DispatchInterceptor.cpp b/cpp/src/Ice/DispatchInterceptor.cpp
index 10457e990e9..ae12e77f900 100644
--- a/cpp/src/Ice/DispatchInterceptor.cpp
+++ b/cpp/src/Ice/DispatchInterceptor.cpp
@@ -21,4 +21,17 @@ Ice::DispatchInterceptor::_iceDispatch(IceInternal::Incoming& in, const Current&
{
return false;
}
+ catch(const std::exception&)
+ {
+ //
+ // If the input parameters weren't read, make sure we skip them here. It's needed to read the
+ // encoding version used by the client to eventually marshal the user exception. It's also needed
+ // if we are dispatch a batch oneway request to read the next batch request.
+ //
+ if(in.getCurrent().encoding.major == 0 && in.getCurrent().encoding.minor == 0)
+ {
+ in.skipReadParams();
+ }
+ throw;
+ }
}
diff --git a/cpp/src/Ice/Incoming.cpp b/cpp/src/Ice/Incoming.cpp
index 1fce4e5f107..b7cc91488d2 100644
--- a/cpp/src/Ice/Incoming.cpp
+++ b/cpp/src/Ice/Incoming.cpp
@@ -59,6 +59,8 @@ IceInternal::IncomingBase::IncomingBase(Instance* instance, ResponseHandler* res
_current.con = connection;
#endif
_current.requestId = requestId;
+ _current.encoding.major = 0;
+ _current.encoding.minor = 0;
}
IceInternal::IncomingBase::IncomingBase(IncomingBase& other) :
diff --git a/cpp/test/Ice/interceptor/AMDInterceptorI.cpp b/cpp/test/Ice/interceptor/AMDInterceptorI.cpp
index 33cfb5e0b38..e2e2d95b001 100644
--- a/cpp/test/Ice/interceptor/AMDInterceptorI.cpp
+++ b/cpp/test/Ice/interceptor/AMDInterceptorI.cpp
@@ -4,7 +4,7 @@
#include <IceUtil/DisableWarnings.h>
#include <AMDInterceptorI.h>
-#include <Test.h>
+#include <MyObjectI.h>
#include <TestHelper.h>
using namespace std;
@@ -56,6 +56,24 @@ AMDInterceptorI::dispatch(Ice::Request& request)
#endif
Ice::Current& current = const_cast<Ice::Current&>(request.getCurrent());
+
+ Ice::Context::const_iterator p = current.ctx.find("raiseBeforeDispatch");
+ if(p != current.ctx.end())
+ {
+ if(p->second == "user")
+ {
+ throw Test::InvalidInputException();
+ }
+ else if(p->second == "notExist")
+ {
+ throw Ice::ObjectNotExistException(__FILE__, __LINE__);
+ }
+ else if(p->second == "system")
+ {
+ throw MySystemException(__FILE__, __LINE__);
+ }
+ }
+
_lastOperation = current.operation;
if(_lastOperation == "amdAddWithRetry")
@@ -105,6 +123,24 @@ AMDInterceptorI::dispatch(Ice::Request& request)
#else
_lastStatus = _servant->ice_dispatch(request, _defaultCb);
#endif
+
+ p = current.ctx.find("raiseAfterDispatch");
+ if(p != current.ctx.end())
+ {
+ if(p->second == "user")
+ {
+ throw Test::InvalidInputException();
+ }
+ else if(p->second == "notExist")
+ {
+ throw Ice::ObjectNotExistException(__FILE__, __LINE__);
+ }
+ else if(p->second == "system")
+ {
+ throw MySystemException(__FILE__, __LINE__);
+ }
+ }
+
return _lastStatus;
}
diff --git a/cpp/test/Ice/interceptor/Client.cpp b/cpp/test/Ice/interceptor/Client.cpp
index fd7c8314d26..dc93891e819 100644
--- a/cpp/test/Ice/interceptor/Client.cpp
+++ b/cpp/test/Ice/interceptor/Client.cpp
@@ -35,6 +35,7 @@ private:
void runTest(const Test::MyObjectPrxPtr&, const InterceptorIPtr&);
void runAmdTest(const Test::MyObjectPrxPtr&, const AMDInterceptorIPtr&);
+ void testInterceptorExceptions(const Test::MyObjectPrx&);
};
void
@@ -169,6 +170,10 @@ Client::runTest(const Test::MyObjectPrxPtr& prx, const InterceptorIPtr& intercep
test(interceptor->getLastOperation() == "amdAdd");
test(!interceptor->getLastStatus());
cout << "ok" << endl;
+
+ cout << "testing exceptions raised by the interceptor... " << flush;
+ testInterceptorExceptions(prx);
+ cout << "ok" << endl;
}
void
@@ -234,6 +239,56 @@ Client::runAmdTest(const Test::MyObjectPrxPtr& prx, const AMDInterceptorIPtr& in
test(!interceptor->getLastStatus());
test(dynamic_cast<MySystemException*>(interceptor->getException()) != 0);
cout << "ok" << endl;
+
+ cout << "testing exceptions raised by the interceptor... " << flush;
+ testInterceptorExceptions(prx);
+ cout << "ok" << endl;
+}
+
+void
+Client::testInterceptorExceptions(const Test::MyObjectPrx& prx)
+{
+ vector<pair<string, string> > exceptions;
+ exceptions.push_back(make_pair("raiseBeforeDispatch", "user"));
+ exceptions.push_back(make_pair("raiseBeforeDispatch", "notExist"));
+ exceptions.push_back(make_pair("raiseBeforeDispatch", "system"));
+ exceptions.push_back(make_pair("raiseAfterDispatch", "user"));
+ exceptions.push_back(make_pair("raiseAfterDispatch", "notExist"));
+ exceptions.push_back(make_pair("raiseAfterDispatch", "system"));
+ for(vector<pair<string, string> >::const_iterator p = exceptions.begin(); p != exceptions.end(); ++p)
+ {
+ Ice::Context ctx;
+ ctx[p->first] = p->second;
+ try
+ {
+ prx->ice_ping(ctx);
+ test(false);
+ }
+ catch(const Ice::UnknownUserException&)
+ {
+ test(p->second == "user");
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ test(p->second == "notExist");
+ }
+ catch(const Ice::UnknownException&)
+ {
+ test(p->second == "system"); // non-collocated
+ }
+ catch(const MySystemException&)
+ {
+ test(p->second == "system"); // collocated
+ }
+ {
+ Ice::ObjectPrx batch = prx->ice_batchOneway();
+ batch->ice_ping(ctx);
+ batch->ice_ping();
+ batch->ice_flushBatchRequests();
+ }
+ }
+ // Force the last batch request to be dispatched by the server thread using invocation timeouts
+ prx->ice_invocationTimeout(10000)->ice_ping();
}
DEFINE_TEST(Client)
diff --git a/cpp/test/Ice/interceptor/InterceptorI.cpp b/cpp/test/Ice/interceptor/InterceptorI.cpp
index 04b60f7a8f6..171aaf0c25a 100644
--- a/cpp/test/Ice/interceptor/InterceptorI.cpp
+++ b/cpp/test/Ice/interceptor/InterceptorI.cpp
@@ -3,7 +3,7 @@
//
#include <InterceptorI.h>
-#include <Test.h>
+#include <MyObjectI.h>
#include <TestHelper.h>
using namespace std;
@@ -18,6 +18,24 @@ bool
InterceptorI::dispatch(Ice::Request& request)
{
Ice::Current& current = const_cast<Ice::Current&>(request.getCurrent());
+
+ Ice::Context::const_iterator p = current.ctx.find("raiseBeforeDispatch");
+ if(p != current.ctx.end())
+ {
+ if(p->second == "user")
+ {
+ throw Test::InvalidInputException();
+ }
+ else if(p->second == "notExist")
+ {
+ throw Ice::ObjectNotExistException(__FILE__, __LINE__);
+ }
+ else if(p->second == "system")
+ {
+ throw MySystemException(__FILE__, __LINE__);
+ }
+ }
+
_lastOperation = current.operation;
if(_lastOperation == "addWithRetry")
@@ -39,7 +57,26 @@ InterceptorI::dispatch(Ice::Request& request)
current.ctx["retry"] = "no";
}
+
_lastStatus = _servant->ice_dispatch(request);
+
+ p = current.ctx.find("raiseAfterDispatch");
+ if(p != current.ctx.end())
+ {
+ if(p->second == "user")
+ {
+ throw Test::InvalidInputException();
+ }
+ else if(p->second == "notExist")
+ {
+ throw Ice::ObjectNotExistException(__FILE__, __LINE__);
+ }
+ else if(p->second == "system")
+ {
+ throw MySystemException(__FILE__, __LINE__);
+ }
+ }
+
return _lastStatus;
}
diff --git a/csharp/src/Ice/DispatchInterceptor.cs b/csharp/src/Ice/DispatchInterceptor.cs
index 665b504ef3e..58a63672bd3 100644
--- a/csharp/src/Ice/DispatchInterceptor.cs
+++ b/csharp/src/Ice/DispatchInterceptor.cs
@@ -26,7 +26,23 @@ namespace Ice
public override System.Threading.Tasks.Task<OutputStream>
iceDispatch(IceInternal.Incoming inc, Current current)
{
- return dispatch(inc);
+ try
+ {
+ return dispatch(inc);
+ }
+ catch(Exception)
+ {
+ //
+ // If the input parameters weren't read, make sure we skip them here. It's needed to read the
+ // encoding version used by the client to eventually marshal the user exception. It's also needed
+ // if we are dispatch a batch oneway request to read the next batch request.
+ //
+ if(current.encoding == null || (current.encoding.major == 0 && current.encoding.minor == 0))
+ {
+ inc.skipReadParams();
+ }
+ throw;
+ }
}
}
}
diff --git a/csharp/test/Ice/interceptor/Client.cs b/csharp/test/Ice/interceptor/Client.cs
index a459ee8fb65..6c8b59cfd52 100644
--- a/csharp/test/Ice/interceptor/Client.cs
+++ b/csharp/test/Ice/interceptor/Client.cs
@@ -3,6 +3,7 @@
//
using System;
+using System.Collections.Generic;
using Test;
namespace Ice
@@ -89,6 +90,11 @@ namespace Ice
test(interceptor.getLastOperation().Equals("badSystemAdd"));
test(!interceptor.getLastStatus());
output.WriteLine("ok");
+
+ output.Write("testing exceptions raised by the interceptor... ");
+ output.Flush();
+ testInterceptorExceptions(prx);
+ output.WriteLine("ok");
}
private void runAmdTest(Test.MyObjectPrx prx, InterceptorI interceptor)
@@ -163,6 +169,11 @@ namespace Ice
test(interceptor.getLastOperation().Equals("amdBadSystemAdd"));
test(interceptor.getLastStatus());
output.WriteLine("ok");
+
+ output.Write("testing exceptions raised by the interceptor... ");
+ output.Flush();
+ testInterceptorExceptions(prx);
+ output.WriteLine("ok");
}
public override void run(string[] args)
@@ -206,6 +217,51 @@ namespace Ice
{
return TestDriver.runTest<Client>(args);
}
+
+ private void testInterceptorExceptions(Test.MyObjectPrx prx)
+ {
+ var exceptions = new List<Tuple<string, string>>();
+ exceptions.Add(new Tuple<string, string>("raiseBeforeDispatch", "user"));
+ exceptions.Add(new Tuple<string, string>("raiseBeforeDispatch", "notExist"));
+ exceptions.Add(new Tuple<string, string>("raiseBeforeDispatch", "system"));
+ exceptions.Add(new Tuple<string, string>("raiseAfterDispatch", "user"));
+ exceptions.Add(new Tuple<string, string>("raiseAfterDispatch", "notExist"));
+ exceptions.Add(new Tuple<string, string>("raiseAfterDispatch", "system"));
+ foreach(var e in exceptions)
+ {
+ var ctx = new Dictionary<string, string>();
+ ctx.Add(e.Item1, e.Item2);
+ try
+ {
+ prx.ice_ping(ctx);
+ test(false);
+ }
+ catch(Ice.UnknownUserException)
+ {
+ test(e.Item2.Equals("user"));
+ }
+ catch(Ice.ObjectNotExistException)
+ {
+ test(e.Item2.Equals("notExist"));
+ }
+ catch(Ice.UnknownException)
+ {
+ test(e.Item2.Equals("system")); // non-collocated
+ }
+ catch(MySystemException)
+ {
+ test(e.Item2.Equals("system")); // collocated
+ }
+ {
+ Ice.ObjectPrx batch = prx.ice_batchOneway();
+ batch.ice_ping(ctx);
+ batch.ice_ping();
+ batch.ice_flushBatchRequests();
+ }
+ }
+ // Force the last batch request to be dispatched by the server thread using invocation timeouts
+ prx.ice_invocationTimeout(10000).ice_ping();
+ }
}
}
}
diff --git a/csharp/test/Ice/interceptor/InterceptorI.cs b/csharp/test/Ice/interceptor/InterceptorI.cs
index 19d33bbbb58..522d5059cb5 100644
--- a/csharp/test/Ice/interceptor/InterceptorI.cs
+++ b/csharp/test/Ice/interceptor/InterceptorI.cs
@@ -29,6 +29,24 @@ namespace Ice
dispatch(Ice.Request request)
{
Ice.Current current = request.getCurrent();
+
+ string context;
+ if(current.ctx.TryGetValue("raiseBeforeDispatch", out context))
+ {
+ if(context.Equals("user"))
+ {
+ throw new Test.InvalidInputException();
+ }
+ else if(context.Equals("notExist"))
+ {
+ throw new Ice.ObjectNotExistException();
+ }
+ else if(context.Equals("system"))
+ {
+ throw new MySystemException();
+ }
+ }
+
lastOperation_ = current.operation;
if(lastOperation_.Equals("addWithRetry") || lastOperation_.Equals("amdAddWithRetry"))
@@ -60,6 +78,23 @@ namespace Ice
var task = servant_.ice_dispatch(request);
lastStatus_ = task != null;
+
+ if(current.ctx.TryGetValue("raiseAfterDispatch", out context))
+ {
+ if(context.Equals("user"))
+ {
+ throw new Test.InvalidInputException();
+ }
+ else if(context.Equals("notExist"))
+ {
+ throw new Ice.ObjectNotExistException();
+ }
+ else if(context.Equals("system"))
+ {
+ throw new MySystemException();
+ }
+ }
+
return task;
}
diff --git a/java-compat/src/Ice/src/main/java/Ice/DispatchInterceptor.java b/java-compat/src/Ice/src/main/java/Ice/DispatchInterceptor.java
index 8735ff7eea6..3935de43b3e 100644
--- a/java-compat/src/Ice/src/main/java/Ice/DispatchInterceptor.java
+++ b/java-compat/src/Ice/src/main/java/Ice/DispatchInterceptor.java
@@ -43,5 +43,18 @@ public abstract class DispatchInterceptor extends ObjectImpl
{
return false;
}
+ catch(java.lang.Throwable ex)
+ {
+ //
+ // If the input parameters weren't read, make sure we skip them here. It's needed to read the
+ // encoding version used by the client to eventually marshal the user exception. It's also needed
+ // if we are dispatch a batch oneway request to read the next batch request.
+ //
+ if(current.encoding == null || (current.encoding.major == 0 && current.encoding.minor == 0))
+ {
+ in.skipReadParams();
+ }
+ throw ex;
+ }
}
}
diff --git a/java-compat/test/src/main/java/test/Ice/interceptor/AMDInterceptorI.java b/java-compat/test/src/main/java/test/Ice/interceptor/AMDInterceptorI.java
index ffade5fbac4..a6a855b0595 100644
--- a/java-compat/test/src/main/java/test/Ice/interceptor/AMDInterceptorI.java
+++ b/java-compat/test/src/main/java/test/Ice/interceptor/AMDInterceptorI.java
@@ -5,6 +5,7 @@
package test.Ice.interceptor;
import test.Ice.interceptor.Test.RetryException;
+import test.Ice.interceptor.Test.InvalidInputException;
//
// A dispatch interceptor with special handling for AMD requests
@@ -23,6 +24,24 @@ class AMDInterceptorI extends InterceptorI implements Ice.DispatchInterceptorAsy
throws Ice.UserException
{
Ice.Current current = request.getCurrent();
+
+ String context = current.ctx.get("raiseBeforeDispatch");
+ if(context != null)
+ {
+ if(context.equals("user"))
+ {
+ throw new InvalidInputException();
+ }
+ else if(context.equals("notExist"))
+ {
+ throw new Ice.ObjectNotExistException();
+ }
+ else if(context.equals("system"))
+ {
+ throw new MySystemException();
+ }
+ }
+
_lastOperation = current.operation;
if(_lastOperation.equals("amdAddWithRetry"))
@@ -53,6 +72,24 @@ class AMDInterceptorI extends InterceptorI implements Ice.DispatchInterceptorAsy
}
_lastStatus = _servant.ice_dispatch(request, this);
+
+ context = current.ctx.get("raiseAfterDispatch");
+ if(context != null)
+ {
+ if(context.equals("user"))
+ {
+ throw new InvalidInputException();
+ }
+ else if(context.equals("notExist"))
+ {
+ throw new Ice.ObjectNotExistException();
+ }
+ else if(context.equals("system"))
+ {
+ throw new MySystemException();
+ }
+ }
+
return _lastStatus;
}
diff --git a/java-compat/test/src/main/java/test/Ice/interceptor/Client.java b/java-compat/test/src/main/java/test/Ice/interceptor/Client.java
index d029404145e..a4e5c436947 100644
--- a/java-compat/test/src/main/java/test/Ice/interceptor/Client.java
+++ b/java-compat/test/src/main/java/test/Ice/interceptor/Client.java
@@ -96,6 +96,11 @@ public class Client extends test.TestHelper
test(interceptor.getLastOperation().equals("amdAdd"));
test(!interceptor.getLastStatus());
out.println("ok");
+
+ out.print("testing exceptions raised by the interceptor... ");
+ out.flush();
+ testInterceptorExceptions(prx);
+ out.println("ok");
}
private void
@@ -169,6 +174,11 @@ public class Client extends test.TestHelper
test(!interceptor.getLastStatus());
test(interceptor.getException() instanceof MySystemException);
out.println("ok");
+
+ out.print("testing exceptions raised by the interceptor... ");
+ out.flush();
+ testInterceptorExceptions(prx);
+ out.println("ok");
}
public void run(String[] args)
@@ -210,4 +220,60 @@ public class Client extends test.TestHelper
runAmdTest(prxForAMD, amdInterceptor, out);
}
}
+
+ private class ExceptionPoint
+ {
+ public ExceptionPoint(String point, String exception)
+ {
+ this.point = point;
+ this.exception = exception;
+ }
+ public String point;
+ public String exception;
+ };
+
+ private void testInterceptorExceptions(MyObjectPrx prx)
+ {
+ java.util.List<ExceptionPoint> exceptions = new java.util.ArrayList<ExceptionPoint>();
+ exceptions.add(new ExceptionPoint("raiseBeforeDispatch", "user"));
+ exceptions.add(new ExceptionPoint("raiseBeforeDispatch", "notExist"));
+ exceptions.add(new ExceptionPoint("raiseBeforeDispatch", "system"));
+ exceptions.add(new ExceptionPoint("raiseAfterDispatch", "user"));
+ exceptions.add(new ExceptionPoint("raiseAfterDispatch", "notExist"));
+ exceptions.add(new ExceptionPoint("raiseAfterDispatch", "system"));
+ for(ExceptionPoint e : exceptions)
+ {
+ java.util.Map<String, String> ctx = new java.util.HashMap<String, String>();
+ ctx.put(e.point, e.exception);
+ try
+ {
+ prx.ice_ping(ctx);
+ test(false);
+ }
+ catch(Ice.UnknownUserException ex)
+ {
+ test(e.exception.equals("user"));
+ }
+ catch(Ice.ObjectNotExistException ex)
+ {
+ test(e.exception.equals("notExist"));
+ }
+ catch(Ice.UnknownException ex)
+ {
+ test(e.exception.equals("system")); // non-collocated
+ }
+ catch(MySystemException ex)
+ {
+ test(e.exception.equals("system")); // collocated
+ }
+ {
+ Ice.ObjectPrx batch = prx.ice_batchOneway();
+ batch.ice_ping(ctx);
+ batch.ice_ping();
+ batch.ice_flushBatchRequests();
+ }
+ }
+ // Force the last batch request to be dispatched by the server thread using invocation timeouts
+ prx.ice_invocationTimeout(10000).ice_ping();
+ }
}
diff --git a/java-compat/test/src/main/java/test/Ice/interceptor/InterceptorI.java b/java-compat/test/src/main/java/test/Ice/interceptor/InterceptorI.java
index 547234e705b..0c067d65d66 100644
--- a/java-compat/test/src/main/java/test/Ice/interceptor/InterceptorI.java
+++ b/java-compat/test/src/main/java/test/Ice/interceptor/InterceptorI.java
@@ -5,6 +5,7 @@
package test.Ice.interceptor;
import test.Ice.interceptor.Test.RetryException;
+import test.Ice.interceptor.Test.InvalidInputException;
class InterceptorI extends Ice.DispatchInterceptor
{
@@ -28,6 +29,24 @@ class InterceptorI extends Ice.DispatchInterceptor
throws Ice.UserException
{
Ice.Current current = request.getCurrent();
+
+ String context = current.ctx.get("raiseBeforeDispatch");
+ if(context != null)
+ {
+ if(context.equals("user"))
+ {
+ throw new InvalidInputException();
+ }
+ else if(context.equals("notExist"))
+ {
+ throw new Ice.ObjectNotExistException();
+ }
+ else if(context.equals("system"))
+ {
+ throw new MySystemException();
+ }
+ }
+
_lastOperation = current.operation;
if(_lastOperation.equals("addWithRetry"))
@@ -51,6 +70,24 @@ class InterceptorI extends Ice.DispatchInterceptor
}
_lastStatus = _servant.ice_dispatch(request);
+
+ context = current.ctx.get("raiseAfterDispatch");
+ if(context != null)
+ {
+ if(context.equals("user"))
+ {
+ throw new InvalidInputException();
+ }
+ else if(context.equals("notExist"))
+ {
+ throw new Ice.ObjectNotExistException();
+ }
+ else if(context.equals("system"))
+ {
+ throw new MySystemException();
+ }
+ }
+
return _lastStatus;
}
diff --git a/java/src/Ice/src/main/java/com/zeroc/Ice/DispatchInterceptor.java b/java/src/Ice/src/main/java/com/zeroc/Ice/DispatchInterceptor.java
index d825707630e..b5f23bb9c27 100644
--- a/java/src/Ice/src/main/java/com/zeroc/Ice/DispatchInterceptor.java
+++ b/java/src/Ice/src/main/java/com/zeroc/Ice/DispatchInterceptor.java
@@ -36,6 +36,22 @@ public abstract class DispatchInterceptor implements com.zeroc.Ice.Object
public CompletionStage<OutputStream> _iceDispatch(com.zeroc.IceInternal.Incoming in, Current current)
throws UserException
{
- return dispatch(in);
+ try
+ {
+ return dispatch(in);
+ }
+ catch(java.lang.Throwable ex)
+ {
+ //
+ // If the input parameters weren't read, make sure we skip them here. It's needed to read the
+ // encoding version used by the client to eventually marshal the user exception. It's also needed
+ // if we are dispatch a batch oneway request to read the next batch request.
+ //
+ if(current.encoding == null || (current.encoding.major == 0 && current.encoding.minor == 0))
+ {
+ in.skipReadParams();
+ }
+ throw ex;
+ }
}
}
diff --git a/java/test/src/main/java/test/Ice/interceptor/Client.java b/java/test/src/main/java/test/Ice/interceptor/Client.java
index 9bd89a14661..b45f9eec748 100644
--- a/java/test/src/main/java/test/Ice/interceptor/Client.java
+++ b/java/test/src/main/java/test/Ice/interceptor/Client.java
@@ -89,6 +89,11 @@ public class Client extends test.TestHelper
test(interceptor.getLastOperation().equals("badSystemAdd"));
test(!interceptor.getLastStatus());
out.println("ok");
+
+ out.print("testing exceptions raised by the interceptor... ");
+ out.flush();
+ testInterceptorExceptions(prx);
+ out.println("ok");
}
private void runAmdTest(MyObjectPrx prx, InterceptorI interceptor, PrintWriter out)
@@ -159,6 +164,11 @@ public class Client extends test.TestHelper
test(interceptor.getLastOperation().equals("amdBadSystemAdd"));
test(interceptor.getLastStatus());
out.println("ok");
+
+ out.print("testing exceptions raised by the interceptor... ");
+ out.flush();
+ testInterceptorExceptions(prx);
+ out.println("ok");
}
public void run(String[] args)
@@ -197,4 +207,60 @@ public class Client extends test.TestHelper
runAmdTest(prx, interceptor, out);
}
}
+
+ private class ExceptionPoint
+ {
+ public ExceptionPoint(String point, String exception)
+ {
+ this.point = point;
+ this.exception = exception;
+ }
+ public String point;
+ public String exception;
+ };
+
+ private void testInterceptorExceptions(MyObjectPrx prx)
+ {
+ java.util.List<ExceptionPoint> exceptions = new java.util.ArrayList<>();
+ exceptions.add(new ExceptionPoint("raiseBeforeDispatch", "user"));
+ exceptions.add(new ExceptionPoint("raiseBeforeDispatch", "notExist"));
+ exceptions.add(new ExceptionPoint("raiseBeforeDispatch", "system"));
+ exceptions.add(new ExceptionPoint("raiseAfterDispatch", "user"));
+ exceptions.add(new ExceptionPoint("raiseAfterDispatch", "notExist"));
+ exceptions.add(new ExceptionPoint("raiseAfterDispatch", "system"));
+ for(ExceptionPoint e : exceptions)
+ {
+ java.util.Map<String, String> ctx = new java.util.HashMap<>();
+ ctx.put(e.point, e.exception);
+ try
+ {
+ prx.ice_ping(ctx);
+ test(false);
+ }
+ catch(com.zeroc.Ice.UnknownUserException ex)
+ {
+ test(e.exception.equals("user"));
+ }
+ catch(com.zeroc.Ice.ObjectNotExistException ex)
+ {
+ test(e.exception.equals("notExist"));
+ }
+ catch(com.zeroc.Ice.UnknownException ex)
+ {
+ test(e.exception.equals("system")); // non-collocated
+ }
+ catch(MySystemException ex)
+ {
+ test(e.exception.equals("system")); // collocated
+ }
+ {
+ com.zeroc.Ice.ObjectPrx batch = prx.ice_batchOneway();
+ batch.ice_ping(ctx);
+ batch.ice_ping();
+ batch.ice_flushBatchRequests();
+ }
+ }
+ // Force the last batch request to be dispatched by the server thread using invocation timeouts
+ prx.ice_invocationTimeout(10000).ice_ping();
+ }
}
diff --git a/java/test/src/main/java/test/Ice/interceptor/InterceptorI.java b/java/test/src/main/java/test/Ice/interceptor/InterceptorI.java
index 2437717ecb1..5ea248e1c43 100644
--- a/java/test/src/main/java/test/Ice/interceptor/InterceptorI.java
+++ b/java/test/src/main/java/test/Ice/interceptor/InterceptorI.java
@@ -9,6 +9,7 @@ import java.util.concurrent.CompletionStage;
import com.zeroc.Ice.OutputStream;
import test.Ice.interceptor.Test.RetryException;
+import test.Ice.interceptor.Test.InvalidInputException;
class InterceptorI extends com.zeroc.Ice.DispatchInterceptor
{
@@ -30,6 +31,24 @@ class InterceptorI extends com.zeroc.Ice.DispatchInterceptor
throws com.zeroc.Ice.UserException
{
com.zeroc.Ice.Current current = request.getCurrent();
+
+ String context = current.ctx.get("raiseBeforeDispatch");
+ if(context != null)
+ {
+ if(context.equals("user"))
+ {
+ throw new InvalidInputException();
+ }
+ else if(context.equals("notExist"))
+ {
+ throw new com.zeroc.Ice.ObjectNotExistException();
+ }
+ else if(context.equals("system"))
+ {
+ throw new MySystemException();
+ }
+ }
+
_lastOperation = current.operation;
if(_lastOperation.equals("addWithRetry") || _lastOperation.equals("amdAddWithRetry"))
@@ -54,6 +73,23 @@ class InterceptorI extends com.zeroc.Ice.DispatchInterceptor
CompletionStage<OutputStream> f = _servant.ice_dispatch(request);
_lastStatus = f != null;
+
+ context = current.ctx.get("raiseAfterDispatch");
+ if(context != null)
+ {
+ if(context.equals("user"))
+ {
+ throw new InvalidInputException();
+ }
+ else if(context.equals("notExist"))
+ {
+ throw new com.zeroc.Ice.ObjectNotExistException();
+ }
+ else if(context.equals("system"))
+ {
+ throw new MySystemException();
+ }
+ }
return f;
}