![JAR search and dependency download from the Maven repository](/logo.png)
org.xadisk.bridge.server.conversation.RemoteMethodInvocationHandler Maven / Gradle / Ivy
/*
Copyright © 2010, Nitin Verma (project owner for XADisk https://xadisk.dev.java.net/). All rights reserved.
This source code is being made available to the public under the terms specified in the license
"Eclipse Public License 1.0" located at http://www.opensource.org/licenses/eclipse-1.0.php.
*/
package org.xadisk.bridge.server.conversation;
import org.xadisk.filesystem.pools.PooledSelector;
import org.xadisk.filesystem.pools.SelectorPool;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Set;
import javax.resource.spi.endpoint.MessageEndpoint;
import javax.resource.spi.work.Work;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
import org.xadisk.filesystem.NativeXAFileSystem;
import org.xadisk.bridge.proxies.facilitators.ByteArrayRemoteReference;
import org.xadisk.bridge.proxies.facilitators.MethodSerializabler;
import org.xadisk.bridge.proxies.facilitators.OptimizedRemoteReference;
import org.xadisk.bridge.proxies.facilitators.SerializedMethod;
public class RemoteMethodInvocationHandler implements Work {
private ConversationContext context;
private static final String UTF8CharsetName = "UTF-8";
private final PooledSelector pooledWriteSelector;
private final Selector writeSelector;
private volatile boolean enabled = true;
private final SelectorPool selectorPool;
private final NativeXAFileSystem xaFileSystem;
public RemoteMethodInvocationHandler(ConversationContext context, NativeXAFileSystem xaFileSystem) throws IOException {
this.xaFileSystem = xaFileSystem;
this.context = context;
this.selectorPool = xaFileSystem.getSelectorPool();
this.pooledWriteSelector = selectorPool.checkOut();
if (pooledWriteSelector == null) {
System.err.println("No more Selectors could be created.");
throw new IOException("Could not get a Selector from the SelectorPool.");
}
this.writeSelector = pooledWriteSelector.getSelector();
}
public void run() {
byte[] methodInvocationResponse;
try {
context.reAssociatedTransactionThreadWithSessions(Thread.currentThread());
methodInvocationResponse = handleRemoteInvocation(context.getCurrentMethodInvocation());
} catch (Throwable t) {
methodInvocationResponse = handleInvocationFailedSystemError(t);
}
try {
SocketChannel channel = context.getConversationChannel();
channel.register(writeSelector, SelectionKey.OP_WRITE);
ByteBuffer toSend = ByteBuffer.wrap(methodInvocationResponse);
while (toSend.remaining() > 0 && enabled) {
int n = writeSelector.select();
if (n == 0) {
//release() got called...thats the only possibility.
break;
}
Set selectionKeys = writeSelector.selectedKeys();
//this will be only one key always, the above one.
channel.write(toSend);
selectionKeys.clear();
}
} catch (Throwable t) {
t.printStackTrace();
//can't do anything here...can't even send the "t" to the remote client itself, as the error
//above is related to sending (though something else) only.
} finally {
try {
selectorPool.checkIn(pooledWriteSelector);
} catch (Throwable t) {
//no-op.
}
}
}
private byte[] handleInvocationFailedSystemError(Throwable t) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeBoolean(true);
oos.writeInt(1);
oos.writeObject(t);
return baos.toByteArray();
} catch (Throwable th) {
throw new AssertionError(th);
}
}
byte[] handleRemoteInvocation(byte[] invocation) throws IOException,
ClassNotFoundException,
NoSuchMethodException,
IllegalAccessException,
ContextOutOfSyncException {
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(invocation));
long targetObjectId = ois.readLong();
Object targetObject = context.getInvocationTarget(targetObjectId);
if (targetObject == null) {
throw new ContextOutOfSyncException("No object with id " + targetObjectId);
}
byte[] methodNameBytes = new byte[ois.readInt()];
ois.read(methodNameBytes);
String methodName = new String(methodNameBytes, UTF8CharsetName);
int numOfArgs = ois.readInt();
Object args[] = new Object[numOfArgs];
Class argTypes[] = new Class[numOfArgs];
ArrayList remoteReferences = new ArrayList();
ArrayList
© 2015 - 2025 Weber Informatics LLC | Privacy Policy