Skip to content
Permalink
Browse files
Merge branch 'unknown_exception_handling' into 'ibm-trunk'
Unknown exception info propagation

See merge request !44
  • Loading branch information
ngmr committed May 24, 2015
2 parents 06b73e2 + 4bec3e1 commit 6f3ff67ec018c963e991c35dc17be06f1652fb80
Showing 14 changed files with 565 additions and 26 deletions.
@@ -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>
@@ -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 @@ public class Downcall {
//
// 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 @@ private void setSystemExceptionImpl(org.omg.CORBA.SystemException ex) {
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_) {
@@ -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 @@ public class Upcall {
// 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 @@ public org.apache.yoko.orb.CORBA.OutputStream preMarshal()
// 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 @@ public org.apache.yoko.orb.CORBA.OutputStream preMarshal()
// 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 endUserException() {

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
@@ -269,6 +269,9 @@ private Serializable createWithFactory(Header h, ValueFactory factory) {
}

private BoxedValueHelper getBoxedHelper(String id) {
if (WStringValueHelper.id().equals(id))
return new WStringValueHelper();

final Class helperClass = Util.idToClass(id, "Helper");

if (helperClass != null) {
@@ -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 @@ static CmsfVersion readData(byte[] data) {
}

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);
}
@@ -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;
}
}
@@ -0,0 +1,3 @@
package test.rmi.exceptionhandling;

public class MyAppException extends Exception {}
@@ -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) {
}
}
@@ -0,0 +1,3 @@
package test.rmi.exceptionhandling;

public class MyRuntimeException extends RuntimeException {}

0 comments on commit 6f3ff67

Please sign in to comment.