Propagate unchecked exceptions in UnknownExceptionInfo service contexts
diff --git a/pom.xml b/pom.xml
index 304fa7c..cec4645 100644
--- a/pom.xml
+++ b/pom.xml
@@ -287,4 +287,11 @@
<url>http://svn.apache.org/viewvc/geronimo/yoko/trunk</url>
</scm>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.servicemix.bundles</groupId>
+ <artifactId>org.apache.servicemix.bundles.bcel</artifactId>
+ <version>5.2_2</version>
+ </dependency>
+ </dependencies>
</project>
diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/Downcall.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/Downcall.java
index 541a63c..eef3adb 100644
--- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/Downcall.java
+++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/Downcall.java
@@ -17,7 +17,15 @@
package org.apache.yoko.orb.OB;
-import java.util.logging.Level;
+import java.util.Vector;
+
+import org.apache.yoko.orb.OCI.Buffer;
+import org.omg.CORBA.MARSHAL;
+import org.omg.CORBA.SystemException;
+import org.omg.CORBA.UNKNOWN;
+import org.omg.CORBA.portable.UnknownException;
+import org.omg.IOP.ServiceContext;
+import org.omg.IOP.UnknownExceptionInfo;
public class Downcall {
//
@@ -118,9 +126,9 @@
//
// The request and reply service contexts
//
- protected java.util.Vector requestSCL_ = new java.util.Vector();
+ protected Vector<ServiceContext> requestSCL_ = new Vector<>();
- protected java.util.Vector replySCL_ = new java.util.Vector();
+ protected Vector<ServiceContext> replySCL_ = new Vector<>();
// ----------------------------------------------------------------------
// Downcall private and protected member implementations
@@ -547,10 +555,32 @@
Assert._OB_assert(responseExpected_);
Assert._OB_assert(ex_ == null);
state_ = DowncallStateSystemException;
- ex_ = ex;
+ ex_ = convertToUnknownExceptionIfAppropriate(ex);
logger_.debug("Received system exception", ex);
}
+ private SystemException convertToUnknownExceptionIfAppropriate(org.omg.CORBA.SystemException ex) {
+ if (ex instanceof UNKNOWN) {
+ for (ServiceContext sc : replySCL_) {
+ if (sc.context_id == UnknownExceptionInfo.value) {
+ final byte[] data = sc.context_data;
+ Buffer buf = new Buffer(data, data.length);
+ try (org.apache.yoko.orb.CORBA.InputStream in =
+ new org.apache.yoko.orb.CORBA.InputStream(buf, 0, false)) {
+ Throwable t = (Throwable) in.read_value();
+ UnknownException x = new UnknownException(t);
+ x.completed = ex.completed;
+ x.minor = ex.minor;
+ return x;
+ } catch (Exception e) {
+ throw (MARSHAL)(new MARSHAL(e.getMessage())).initCause(e);
+ }
+ }
+ }
+ }
+ return ex;
+ }
+
public void setSystemException(org.omg.CORBA.SystemException ex) {
if (stateMonitor_ != null) {
synchronized (stateMonitor_) {
diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/Upcall.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/Upcall.java
index 9ffb3a7..3f2e343 100644
--- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/Upcall.java
+++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/Upcall.java
@@ -17,11 +17,20 @@
package org.apache.yoko.orb.OB;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
+import org.apache.yoko.orb.CORBA.OutputStream;
import org.apache.yoko.orb.OB.DispatchRequest;
import org.apache.yoko.orb.OB.DispatchStrategy;
+import org.apache.yoko.orb.OCI.Buffer;
+import org.omg.CORBA.INTERNAL;
+import org.omg.CORBA.portable.UnknownException;
+import org.omg.IOP.ServiceContext;
+import org.omg.IOP.UnknownExceptionInfo;
public class Upcall {
static final Logger logger = Logger.getLogger(Upcall.class.getName());
@@ -76,7 +85,7 @@
// The reply service context list
// (Must be a Vector because it can be modified by interceptors)
//
- protected java.util.Vector replySCL_ = new java.util.Vector();
+ protected Vector<ServiceContext> replySCL_ = new Vector<>();
//
// The dispatch request
@@ -294,8 +303,24 @@
// OutputStream to make the skeleton happy and avoid a crash.
//
if (upcallReturn_ != null) {
- if (!upcallReturn_.replySent() && (profileInfo_.major > 1 || profileInfo_.minor >= 1)) {
- initServiceContexts();
+ addUnsentConnectionServiceContexts();
+ org.omg.IOP.ServiceContext[] scl = new org.omg.IOP.ServiceContext[replySCL_
+ .size()];
+ replySCL_.copyInto(scl);
+ upcallReturn_.upcallBeginReply(this, scl);
+ } else {
+ org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer();
+ out_ = new org.apache.yoko.orb.CORBA.OutputStream(buf, in_
+ ._OB_codeConverters(), (profileInfo_.major << 8)
+ | profileInfo_.minor);
+ }
+ out_._OB_ORBInstance(this.orbInstance());
+ return out_;
+ }
+
+ private void addUnsentConnectionServiceContexts() {
+ if (!upcallReturn_.replySent() && (profileInfo_.major > 1 || profileInfo_.minor >= 1)) {
+ initServiceContexts();
// CoreTraceLevels coreTraceLevels = orbInstance_
// .getCoreTraceLevels();
// if (coreTraceLevels.traceConnections() >= 2) {
@@ -323,21 +348,9 @@
// Assert._OB_assert(codeSetSC_ != null);
// replySCL_.add(codeSetSC_);
- Assert._OB_assert(codeBaseSC_ != null);
- replySCL_.add(codeBaseSC_);
- }
- org.omg.IOP.ServiceContext[] scl = new org.omg.IOP.ServiceContext[replySCL_
- .size()];
- replySCL_.copyInto(scl);
- upcallReturn_.upcallBeginReply(this, scl);
- } else {
- org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer();
- out_ = new org.apache.yoko.orb.CORBA.OutputStream(buf, in_
- ._OB_codeConverters(), (profileInfo_.major << 8)
- | profileInfo_.minor);
+ Assert._OB_assert(codeBaseSC_ != null);
+ replySCL_.add(codeBaseSC_);
}
- out_._OB_ORBInstance(this.orbInstance());
- return out_;
}
public void marshalEx(org.omg.CORBA.SystemException ex)
@@ -423,14 +436,30 @@
public void setSystemException(org.omg.CORBA.SystemException ex) {
if (upcallReturn_ != null) {
- userEx_ = false; // Java only
- org.omg.IOP.ServiceContext[] scl = new org.omg.IOP.ServiceContext[replySCL_
- .size()];
+ addUnsentConnectionServiceContexts();
+ userEx_ = false;
+ if (ex instanceof UnknownException) {
+ // need to create an exception info service context
+ replySCL_.add(createUnknownExceptionInfoServiceContext((UnknownException)ex));
+ }
+ ServiceContext[] scl = new ServiceContext[replySCL_.size()];
replySCL_.copyInto(scl);
upcallReturn_.upcallSystemException(this, ex, scl);
}
}
+ private static ServiceContext createUnknownExceptionInfoServiceContext(UnknownException ex) {
+ Throwable t = ex.originalEx;
+ Buffer buf = new Buffer();
+ try (OutputStream os = new OutputStream(buf)) {
+ os.write_value(t, Throwable.class);
+ ServiceContext sc = new ServiceContext(UnknownExceptionInfo.value, Arrays.copyOf(buf.data(), buf.length()));
+ return sc;
+ } catch (IOException e) {
+ throw (INTERNAL)(new INTERNAL(e.getMessage())).initCause(e);
+ }
+ }
+
public void setLocationForward(org.omg.IOP.IOR ior, boolean perm) {
if (upcallReturn_ != null) {
userEx_ = false; // Java only
diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/ValueReader.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/ValueReader.java
index bf05680..bcaf2aa 100644
--- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/ValueReader.java
+++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/ValueReader.java
@@ -269,6 +269,9 @@
}
private BoxedValueHelper getBoxedHelper(String id) {
+ if (WStringValueHelper.id().equals(id))
+ return new WStringValueHelper();
+
final Class helperClass = Util.idToClass(id, "Helper");
if (helperClass != null) {
diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/cmsf/CmsfVersion.java b/yoko-core/src/main/java/org/apache/yoko/orb/cmsf/CmsfVersion.java
index b8bc632..552c942 100644
--- a/yoko-core/src/main/java/org/apache/yoko/orb/cmsf/CmsfVersion.java
+++ b/yoko-core/src/main/java/org/apache/yoko/orb/cmsf/CmsfVersion.java
@@ -1,6 +1,7 @@
package org.apache.yoko.orb.cmsf;
import java.io.IOException;
+import java.util.Arrays;
import org.apache.yoko.orb.OCI.Buffer;
import org.omg.CORBA.Any;
@@ -69,12 +70,12 @@
}
private static byte[] genData(byte value) {
- Buffer buf = new Buffer();
+ Buffer buf = new Buffer(2);
try (org.apache.yoko.orb.CORBA.OutputStream out =
new org.apache.yoko.orb.CORBA.OutputStream(buf)) {
out._OB_writeEndian();
out.write_octet(value);
- return buf.data();
+ return Arrays.copyOf(buf.data(), buf.length());
} catch (IOException e) {
throw (INTERNAL)(new INTERNAL(e.getMessage())).initCause(e);
}
diff --git a/yoko-core/src/test/java/org/apache/yoko/RMIExceptionHandlingTest.java b/yoko-core/src/test/java/org/apache/yoko/RMIExceptionHandlingTest.java
new file mode 100644
index 0000000..17e8916
--- /dev/null
+++ b/yoko-core/src/test/java/org/apache/yoko/RMIExceptionHandlingTest.java
@@ -0,0 +1,86 @@
+package org.apache.yoko;
+
+import java.rmi.RemoteException;
+import java.util.Properties;
+
+import javax.rmi.PortableRemoteObject;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.omg.CORBA.ORB;
+import org.omg.PortableServer.POA;
+import org.omg.PortableServer.POAHelper;
+
+import test.rmi.exceptionhandling.MyAppException;
+import test.rmi.exceptionhandling.MyClientRequestInterceptor;
+import test.rmi.exceptionhandling.MyRuntimeException;
+import test.rmi.exceptionhandling.MyServerRequestInterceptor;
+import test.rmi.exceptionhandling.Thrower;
+import test.rmi.exceptionhandling.ThrowerImpl;
+import test.rmi.exceptionhandling._ThrowerImpl_Tie;
+
+@SuppressWarnings("serial")
+public class RMIExceptionHandlingTest {
+ private static ORB serverOrb;
+ private static ORB clientOrb;
+ private static String ior;
+
+ private static ORB initOrb(Properties props, String... args) {
+ return ORB.init(args, props);
+ }
+
+ @BeforeClass
+ public static void createServerORB() throws Exception {
+ serverOrb = initOrb(new Properties() {{
+ put("org.omg.PortableInterceptor.ORBInitializerClass." + MyClientRequestInterceptor.class.getName(),"");
+ put("org.omg.PortableInterceptor.ORBInitializerClass." + MyServerRequestInterceptor.class.getName(),"");
+ }});
+ POA poa = POAHelper.narrow(serverOrb.resolve_initial_references("RootPOA"));
+ poa.the_POAManager().activate();
+
+ _ThrowerImpl_Tie tie = new _ThrowerImpl_Tie();
+ tie.setTarget(new ThrowerImpl());
+
+ poa.activate_object(tie);
+ ior = serverOrb.object_to_string(tie.thisObject());
+ System.out.println(ior);
+ }
+
+ @BeforeClass
+ public static void createClientORB() {
+ clientOrb = initOrb(new Properties() {{
+ put("org.omg.PortableInterceptor.ORBInitializerClass." + MyClientRequestInterceptor.class.getName(),"");
+ }});
+ }
+
+ @AfterClass
+ public static void shutdownServerORB() {
+ serverOrb.shutdown(true);
+ serverOrb.destroy();
+ ior = null;
+ }
+
+ @AfterClass
+ public static void shutdownClientORB() {
+ clientOrb.shutdown(true);
+ clientOrb.destroy();
+ }
+
+ @Test(expected=MyRuntimeException.class)
+ public void testRuntimeException() throws RemoteException {
+ getThrower(clientOrb).throwRuntimeException();
+ }
+
+ @Test(expected=MyAppException.class)
+ public void testAppException() throws RemoteException, MyAppException {
+ getThrower(clientOrb).throwAppException();
+ }
+
+ private Thrower getThrower(ORB orb) {
+ Object o = orb.string_to_object(ior);
+ Thrower thrower = (Thrower) PortableRemoteObject.narrow(o, Thrower.class);
+ return thrower;
+ }
+}
diff --git a/yoko-core/src/test/java/test/rmi/exceptionhandling/MyAppException.java b/yoko-core/src/test/java/test/rmi/exceptionhandling/MyAppException.java
new file mode 100644
index 0000000..662705b
--- /dev/null
+++ b/yoko-core/src/test/java/test/rmi/exceptionhandling/MyAppException.java
@@ -0,0 +1,3 @@
+package test.rmi.exceptionhandling;
+
+public class MyAppException extends Exception {}
\ No newline at end of file
diff --git a/yoko-core/src/test/java/test/rmi/exceptionhandling/MyClientRequestInterceptor.java b/yoko-core/src/test/java/test/rmi/exceptionhandling/MyClientRequestInterceptor.java
new file mode 100644
index 0000000..1f05ee5
--- /dev/null
+++ b/yoko-core/src/test/java/test/rmi/exceptionhandling/MyClientRequestInterceptor.java
@@ -0,0 +1,64 @@
+package test.rmi.exceptionhandling;
+
+import org.omg.CORBA.LocalObject;
+import org.omg.PortableInterceptor.ClientRequestInfo;
+import org.omg.PortableInterceptor.ClientRequestInterceptor;
+import org.omg.PortableInterceptor.ForwardRequest;
+import org.omg.PortableInterceptor.ORBInitInfo;
+import org.omg.PortableInterceptor.ORBInitializer;
+import org.omg.PortableInterceptor.ORBInitInfoPackage.DuplicateName;
+
+public class MyClientRequestInterceptor extends LocalObject implements ClientRequestInterceptor, ORBInitializer {
+
+ @Override
+ public void receive_exception(ClientRequestInfo arg0) throws ForwardRequest {
+ System.out.printf("%08x: ", Thread.currentThread().getId());
+ System.out.println("receive_exception(" + arg0.operation() + ")");
+ }
+
+ @Override
+ public void receive_other(ClientRequestInfo arg0) throws ForwardRequest {
+ System.out.printf("%08x: ", Thread.currentThread().getId());
+ System.out.println("receive_other(" + arg0.operation() + ")");
+ }
+
+ @Override
+ public void receive_reply(ClientRequestInfo arg0) {
+ System.out.printf("%08x: ", Thread.currentThread().getId());
+ System.out.println("receive_reply(" + arg0.operation() + ")");
+ }
+
+ @Override
+ public void send_poll(ClientRequestInfo arg0) {
+ System.out.printf("%08x: ", Thread.currentThread().getId());
+ System.out.println("send_poll(" + arg0.operation() + ")");
+ }
+
+ @Override
+ public void send_request(ClientRequestInfo arg0) throws ForwardRequest {
+ System.out.printf("%08x: ", Thread.currentThread().getId());
+ System.out.println("send_request(" + arg0.operation() + ")");
+ }
+
+ @Override
+ public void destroy() {
+ }
+
+ @Override
+ public String name() {
+ return this.getClass().getName();
+ }
+
+ @Override
+ public void post_init(ORBInitInfo arg0) {
+ try {
+ arg0.add_client_request_interceptor(this);
+ } catch (DuplicateName e) {
+ throw new Error(e);
+ }
+ }
+
+ @Override
+ public void pre_init(ORBInitInfo arg0) {
+ }
+}
\ No newline at end of file
diff --git a/yoko-core/src/test/java/test/rmi/exceptionhandling/MyRuntimeException.java b/yoko-core/src/test/java/test/rmi/exceptionhandling/MyRuntimeException.java
new file mode 100644
index 0000000..cf1de8c
--- /dev/null
+++ b/yoko-core/src/test/java/test/rmi/exceptionhandling/MyRuntimeException.java
@@ -0,0 +1,3 @@
+package test.rmi.exceptionhandling;
+
+public class MyRuntimeException extends RuntimeException {}
\ No newline at end of file
diff --git a/yoko-core/src/test/java/test/rmi/exceptionhandling/MyServerRequestInterceptor.java b/yoko-core/src/test/java/test/rmi/exceptionhandling/MyServerRequestInterceptor.java
new file mode 100644
index 0000000..56ceaaf
--- /dev/null
+++ b/yoko-core/src/test/java/test/rmi/exceptionhandling/MyServerRequestInterceptor.java
@@ -0,0 +1,64 @@
+package test.rmi.exceptionhandling;
+
+import org.omg.CORBA.LocalObject;
+import org.omg.PortableInterceptor.ForwardRequest;
+import org.omg.PortableInterceptor.ORBInitInfo;
+import org.omg.PortableInterceptor.ORBInitializer;
+import org.omg.PortableInterceptor.ServerRequestInfo;
+import org.omg.PortableInterceptor.ServerRequestInterceptor;
+import org.omg.PortableInterceptor.ORBInitInfoPackage.DuplicateName;
+
+public class MyServerRequestInterceptor extends LocalObject implements ServerRequestInterceptor, ORBInitializer {
+
+ @Override
+ public void receive_request(ServerRequestInfo arg0) throws ForwardRequest {
+ System.out.printf("%08x: ", Thread.currentThread().getId());
+ System.out.println("receive_request(" + arg0.operation() + ")");
+ }
+
+ @Override
+ public void receive_request_service_contexts(ServerRequestInfo arg0) throws ForwardRequest {
+ System.out.printf("%08x: ", Thread.currentThread().getId());
+ System.out.println("receive_request_service_contexts(" + arg0.operation() + ")");
+ }
+
+ @Override
+ public void send_exception(ServerRequestInfo arg0) throws ForwardRequest {
+ System.out.printf("%08x: ", Thread.currentThread().getId());
+ System.out.println("send_exception(" + arg0.operation() + ")");
+ }
+
+ @Override
+ public void send_other(ServerRequestInfo arg0) throws ForwardRequest {
+ System.out.printf("%08x: ", Thread.currentThread().getId());
+ System.out.println("send_other(" + arg0.operation() + ")");
+ }
+
+ @Override
+ public void send_reply(ServerRequestInfo arg0) {
+ System.out.printf("%08x: ", Thread.currentThread().getId());
+ System.out.println("send_reply(" + arg0.operation() + ")");
+ }
+
+ @Override
+ public void destroy() {
+ }
+
+ @Override
+ public String name() {
+ return this.getClass().getName();
+ }
+
+ @Override
+ public void post_init(ORBInitInfo arg0) {
+ try {
+ arg0.add_server_request_interceptor(this);
+ } catch (DuplicateName e) {
+ throw new Error(e);
+ }
+ }
+
+ @Override
+ public void pre_init(ORBInitInfo arg0) {
+ }
+}
diff --git a/yoko-core/src/test/java/test/rmi/exceptionhandling/Thrower.java b/yoko-core/src/test/java/test/rmi/exceptionhandling/Thrower.java
new file mode 100644
index 0000000..b8b9a02
--- /dev/null
+++ b/yoko-core/src/test/java/test/rmi/exceptionhandling/Thrower.java
@@ -0,0 +1,9 @@
+package test.rmi.exceptionhandling;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+public interface Thrower extends Remote {
+ void throwAppException() throws RemoteException, MyAppException;
+ void throwRuntimeException() throws RemoteException;
+}
\ No newline at end of file
diff --git a/yoko-core/src/test/java/test/rmi/exceptionhandling/ThrowerImpl.java b/yoko-core/src/test/java/test/rmi/exceptionhandling/ThrowerImpl.java
new file mode 100644
index 0000000..63c1cb8
--- /dev/null
+++ b/yoko-core/src/test/java/test/rmi/exceptionhandling/ThrowerImpl.java
@@ -0,0 +1,15 @@
+package test.rmi.exceptionhandling;
+
+import java.rmi.RemoteException;
+
+public class ThrowerImpl implements Thrower {
+ @Override
+ public void throwAppException() throws RemoteException, MyAppException {
+ throw new MyAppException();
+ }
+
+ @Override
+ public void throwRuntimeException() throws RemoteException {
+ throw new MyRuntimeException();
+ }
+}
\ No newline at end of file
diff --git a/yoko-core/src/test/java/test/rmi/exceptionhandling/_ThrowerImpl_Tie.java b/yoko-core/src/test/java/test/rmi/exceptionhandling/_ThrowerImpl_Tie.java
new file mode 100644
index 0000000..434e16a
--- /dev/null
+++ b/yoko-core/src/test/java/test/rmi/exceptionhandling/_ThrowerImpl_Tie.java
@@ -0,0 +1,113 @@
+// POA Tie class generated by rmic, do not edit.
+// Contents subject to change without notice.
+
+package test.rmi.exceptionhandling;
+
+import java.lang.ClassCastException;
+import java.lang.String;
+import java.lang.Throwable;
+import java.rmi.Remote;
+import javax.rmi.CORBA.Tie;
+import org.omg.CORBA.BAD_OPERATION;
+import org.omg.CORBA.BAD_PARAM;
+import org.omg.CORBA.ORB;
+import org.omg.CORBA.Object;
+import org.omg.CORBA.SystemException;
+import org.omg.CORBA.portable.InputStream;
+import org.omg.CORBA.portable.OutputStream;
+import org.omg.CORBA.portable.ResponseHandler;
+import org.omg.CORBA.portable.UnknownException;
+import org.omg.PortableServer.POA;
+import org.omg.PortableServer.POAPackage.ObjectNotActive;
+import org.omg.PortableServer.POAPackage.ServantNotActive;
+import org.omg.PortableServer.POAPackage.WrongPolicy;
+
+public class _ThrowerImpl_Tie extends org.omg.PortableServer.Servant implements Tie {
+
+ private ThrowerImpl target = null;
+
+ private static final String[] _type_ids = {
+ "RMI:test.rmi.exceptionhandling.Thrower:0000000000000000"
+ };
+
+ public void setTarget(Remote target) {
+ this.target = (ThrowerImpl) target;
+ }
+
+ public Remote getTarget() {
+ return target;
+ }
+
+ public Object thisObject() {
+ return _this_object();
+ }
+
+ public void deactivate() {
+ try {
+ _poa().deactivate_object(_poa().servant_to_id(this));
+ }
+ catch(WrongPolicy e) { }
+ catch(ObjectNotActive e) { }
+ catch(ServantNotActive e) { }
+ }
+
+ public ORB orb() {
+ return _orb();
+ }
+
+ public void orb(ORB orb) {
+ try {
+ ((org.omg.CORBA_2_3.ORB)orb).set_delegate(this);
+ }
+ catch(ClassCastException e) {
+ throw new BAD_PARAM("POA Servant needs an org.omg.CORBA_2_3.ORB");
+ }
+ }
+
+ public String[] _all_interfaces(POA poa, byte[] objectId) {
+ return (String [] ) _type_ids.clone();
+ }
+
+ public OutputStream _invoke(String method, InputStream _in, ResponseHandler reply) throws SystemException {
+ try {
+ org.omg.CORBA_2_3.portable.InputStream in =
+ (org.omg.CORBA_2_3.portable.InputStream) _in;
+ switch (method.length()) {
+ case 17:
+ if (method.equals("throwAppException")) {
+ return throwAppException(in, reply);
+ }
+ case 21:
+ if (method.equals("throwRuntimeException")) {
+ return throwRuntimeException(in, reply);
+ }
+ }
+ throw new BAD_OPERATION();
+ } catch (SystemException ex) {
+ throw ex;
+ } catch (Throwable ex) {
+ throw new UnknownException(ex);
+ }
+ }
+
+ private OutputStream throwAppException(org.omg.CORBA_2_3.portable.InputStream in , ResponseHandler reply) throws Throwable {
+ try {
+ target.throwAppException();
+ } catch (MyAppException ex) {
+ String id = "IDL:test/rmi/exceptionhandling/MyAppEx:1.0";
+ org.omg.CORBA_2_3.portable.OutputStream out =
+ (org.omg.CORBA_2_3.portable.OutputStream) reply.createExceptionReply();
+ out.write_string(id);
+ out.write_value(ex,MyAppException.class);
+ return out;
+ }
+ OutputStream out = reply.createReply();
+ return out;
+ }
+
+ private OutputStream throwRuntimeException(org.omg.CORBA_2_3.portable.InputStream in , ResponseHandler reply) throws Throwable {
+ target.throwRuntimeException();
+ OutputStream out = reply.createReply();
+ return out;
+ }
+}
diff --git a/yoko-core/src/test/java/test/rmi/exceptionhandling/_Thrower_Stub.java b/yoko-core/src/test/java/test/rmi/exceptionhandling/_Thrower_Stub.java
new file mode 100644
index 0000000..884897e
--- /dev/null
+++ b/yoko-core/src/test/java/test/rmi/exceptionhandling/_Thrower_Stub.java
@@ -0,0 +1,112 @@
+// Stub class generated by rmic, do not edit.
+// Contents subject to change without notice.
+
+package test.rmi.exceptionhandling;
+
+import java.lang.String;
+import java.lang.Throwable;
+import java.rmi.RemoteException;
+import java.rmi.UnexpectedException;
+import javax.rmi.CORBA.Stub;
+import javax.rmi.CORBA.Util;
+import org.omg.CORBA.SystemException;
+import org.omg.CORBA.portable.ApplicationException;
+import org.omg.CORBA.portable.InputStream;
+import org.omg.CORBA.portable.OutputStream;
+import org.omg.CORBA.portable.RemarshalException;
+import org.omg.CORBA.portable.ServantObject;
+
+public class _Thrower_Stub extends Stub implements Thrower {
+
+ private static final String[] _type_ids = {
+ "RMI:test.rmi.exceptionhandling.Thrower:0000000000000000"
+ };
+
+ public String[] _ids() {
+ return (String [] ) _type_ids.clone();
+ }
+
+ public void throwAppException() throws RemoteException, MyAppException {
+ while(true) {
+ if (!Util.isLocal(this)) {
+ org.omg.CORBA_2_3.portable.InputStream in = null;
+ try {
+ try {
+ OutputStream out = _request("throwAppException", true);
+ _invoke(out);
+ return;
+ } catch (ApplicationException ex) {
+ in = (org.omg.CORBA_2_3.portable.InputStream) ex.getInputStream();
+ String id = in.read_string();
+ if (id.equals("IDL:test/rmi/exceptionhandling/MyAppEx:1.0")) {
+ throw (MyAppException) in.read_value(MyAppException.class);
+ }
+ throw new UnexpectedException(id);
+ } catch (RemarshalException ex) {
+ continue;
+ }
+ } catch (SystemException ex) {
+ throw Util.mapSystemException(ex);
+ } finally {
+ _releaseReply(in);
+ }
+ } else {
+ ServantObject so = _servant_preinvoke("throwAppException",test.rmi.exceptionhandling.Thrower.class);
+ if (so == null) {
+ continue;
+ }
+ try {
+ ((test.rmi.exceptionhandling.Thrower)so.servant).throwAppException();
+ return;
+ } catch (Throwable ex) {
+ Throwable exCopy = (Throwable)Util.copyObject(ex,_orb());
+ if (exCopy instanceof MyAppException) {
+ throw (MyAppException)exCopy;
+ }
+ throw Util.wrapException(exCopy);
+ } finally {
+ _servant_postinvoke(so);
+ }
+ }
+ }
+ }
+
+ public void throwRuntimeException() throws RemoteException {
+ while(true) {
+ if (!Util.isLocal(this)) {
+ InputStream in = null;
+ try {
+ try {
+ OutputStream out = _request("throwRuntimeException", true);
+ _invoke(out);
+ return;
+ } catch (ApplicationException ex) {
+ in = ex.getInputStream();
+ String id = in.read_string();
+ throw new UnexpectedException(id);
+ } catch (RemarshalException ex) {
+ continue;
+ }
+ } catch (SystemException ex) {
+ throw Util.mapSystemException(ex);
+ } finally {
+ _releaseReply(in);
+ }
+ } else {
+ ServantObject so = _servant_preinvoke("throwRuntimeException",test.rmi.exceptionhandling.Thrower.class);
+ if (so == null) {
+ continue;
+ }
+ try {
+ ((test.rmi.exceptionhandling.Thrower)so.servant).throwRuntimeException();
+ return;
+ } catch (Throwable ex) {
+ Throwable exCopy = (Throwable)Util.copyObject(ex,_orb());
+ throw Util.wrapException(exCopy);
+ } finally {
+ _servant_postinvoke(so);
+ }
+ }
+ }
+ }
+}