/** * If thrown under the context of an active transaction the current transaction context will be * rolled back and a new retry will be initialized. * * @author Guy Korland * @since 1.0 */ @ExcludeInternal public class TransactionException extends RuntimeException { public static final String TRANSACTION_EXCEPTION_INTERNAL = Type.getInternalName(TransactionException.class); public static final TransactionException STATIC_TRANSACTION = new TransactionException(); public TransactionException() {} public TransactionException(String msg) { super(msg); } public TransactionException(Throwable cause) { super(cause); } @Override public Throwable fillInStackTrace() { return null; } // light exception with no stack trace @Override public Throwable initCause(Throwable cause) { throw new IllegalStateException("Can't set cause."); } }
@Override public void visitCode() { mv.visitCode(); if (!remote) return; mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, classInternalName, ITypeInternalName.$HY$_STATE, "I"); mv.visitInsn(ITypeInternalName.DEFAULT_STATE); Label l1 = new Label(); mv.visitJumpInsn(Opcodes.IF_ICMPEQ, l1); Type[] types = Type.getArgumentTypes(desc); mv.visitIntInsn(Opcodes.BIPUSH, types.length); mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object"); mv.visitInsn(Opcodes.DUP); int offset = types.length + 1; mv.visitVarInsn(Opcodes.ASTORE, offset); for (int i = 0; i < types.length; ++i) { mv.visitVarInsn(Opcodes.ALOAD, offset); mv.visitIntInsn(Opcodes.BIPUSH, i); switch (types[i].getSort()) { case Type.BOOLEAN: case Type.BYTE: case Type.CHAR: case Type.SHORT: case Type.INT: mv.visitVarInsn(Opcodes.ILOAD, i + 1); mv.visitMethodInsn( Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;"); break; case Type.LONG: mv.visitVarInsn(Opcodes.LLOAD, i + 1); mv.visitMethodInsn( Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;"); break; case Type.FLOAT: mv.visitVarInsn(Opcodes.FLOAD, i + 1); mv.visitMethodInsn( Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;"); break; case Type.DOUBLE: mv.visitVarInsn(Opcodes.DLOAD, i + 1); mv.visitMethodInsn( Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;"); break; default: mv.visitVarInsn(Opcodes.ALOAD, i + 1); break; } mv.visitInsn(Opcodes.AASTORE); } mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;"); // mv.visitMethodInsn(Opcodes.INVOKESTATIC, ITypeInternalName.HYFLOW, "getRemoteCaller", // "(Ljava/lang/Class;)L" + ITypeInternalName.REMOTE_CALLER + ";"); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, classInternalName, "id", "Ljava/lang/String;"); mv.visitLdcInsn(method); mv.visitVarInsn(Opcodes.ALOAD, offset); // mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, ITypeInternalName.REMOTE_CALLER, "execute", // "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;"); Type type = Type.getReturnType(desc); switch (type.getSort()) { case Type.VOID: mv.visitInsn(Opcodes.POP); mv.visitInsn(Opcodes.RETURN); break; case Type.BOOLEAN: mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Boolean"); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z"); mv.visitInsn(Opcodes.IRETURN); break; case Type.BYTE: mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Byte"); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B"); mv.visitInsn(Opcodes.IRETURN); break; case Type.CHAR: mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Char"); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Char", "charValue", "()C"); mv.visitInsn(Opcodes.IRETURN); break; case Type.SHORT: mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Short"); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S"); mv.visitInsn(Opcodes.IRETURN); break; case Type.INT: mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Integer"); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I"); mv.visitInsn(Opcodes.IRETURN); break; case Type.LONG: mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Long"); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J"); mv.visitInsn(Opcodes.LRETURN); break; case Type.FLOAT: mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Float"); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F"); mv.visitInsn(Opcodes.FRETURN); break; case Type.DOUBLE: mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Double"); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D"); mv.visitInsn(Opcodes.DRETURN); break; default: mv.visitTypeInsn(Opcodes.CHECKCAST, type.getInternalName()); mv.visitInsn(Opcodes.ARETURN); break; } mv.visitLabel(l1); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); }
@ExcludeTM public final class TribuDSTM { public static final String DESC = Type.getDescriptor(TribuDSTM.class); public static final String NAME = Type.getInternalName(TribuDSTM.class); private static final Locator locator = new SimpleLocator(); private static DistributedProtocol distProtocol; private static GroupCommunication groupComm; private static DataPartitioner dataPartitioner; private static GroupPartitioner groupPartitioner; private static boolean partial; private static Class<? extends Group> groupClass; private static Class<? extends DistributedContext> ctxClass; static { checkRuntimeMode("false"); initReplicationProtocol(); initTransactionContext(); if (partial) { initPartitioners(); } } /* * Defer the initialization of group communication until the actual * application is executing. Apparently, explicit class loading during the * execution of an agent is only supported in JDK 7. */ public static final String INIT_METHOD_NAME = "init"; public static final String INIT_METHOD_DESC = "()" + Type.VOID_TYPE.getDescriptor(); public static void init() { initGroupCommunication(); if (partial) { groupPartitioner.partitionGroups( groupComm.getMembers(), Integer.getInteger("tribu.groups", 1)); dataPartitioner.init(); } distProtocol.init(); } public static final String CLOSE_METHOD_NAME = "close"; public static final String CLOSE_METHOD_DESC = "()" + Type.VOID_TYPE.getDescriptor(); public static void close() { groupComm.close(); } private static void initGroupCommunication() { String className = System.getProperty( "tribu.groupcommunication.class", "org.deuce.distribution.groupcomm.jgroups.JGroupsGroupCommunication"); try { @SuppressWarnings("unchecked") Class<? extends GroupCommunication> groupCommClass = (Class<? extends GroupCommunication>) Class.forName(className); groupComm = groupCommClass.newInstance(); } catch (Exception e) { e.printStackTrace(); System.exit(-1); } } @SuppressWarnings("unchecked") private static void initTransactionContext() { String className = System.getProperty( "org.deuce.transaction.contextClass", "org.deuce.transaction.tl2.Context"); try { ctxClass = (Class<? extends DistributedContext>) Class.forName(className); } catch (Exception e) { e.printStackTrace(); System.exit(-1); } } private static void initReplicationProtocol() { String className = System.getProperty( "tribu.distributed.protocolClass", "org.deuce.distribution.replication.full.protocol.nonvoting.NonVoting"); try { @SuppressWarnings("unchecked") Class<? extends DistributedProtocol> distProtocolClass = (Class<? extends DistributedProtocol>) Class.forName(className); distProtocol = distProtocolClass.newInstance(); } catch (Exception e) { e.printStackTrace(); System.exit(-1); } } @SuppressWarnings("unchecked") private static void initPartitioners() { String groupPartClass = System.getProperty( "tribu.distributed.GroupPartitionerClass", "org.deuce.distribution.replication.partitioner.group.RandomGroupPartitioner"); String dataPartClass = System.getProperty( "tribu.distributed.DataPartitionerClass", "org.deuce.distribution.replication.partitioner.data.SimpleDataPartitioner"); String gClass = System.getProperty( "tribu.distributed.GroupClass", "org.deuce.distribution.replication.group.PartialReplicationGroup"); try { Class<? extends GroupPartitioner> groupPart = (Class<? extends GroupPartitioner>) Class.forName(groupPartClass); groupPartitioner = groupPart.newInstance(); Class<? extends DataPartitioner> dataPart = (Class<? extends DataPartitioner>) Class.forName(dataPartClass); dataPartitioner = dataPart.newInstance(); groupClass = (Class<? extends Group>) Class.forName(gClass); } catch (Exception e) { e.printStackTrace(); System.exit(-1); } } private static void checkRuntimeMode(String partialDefault) { partial = Boolean.parseBoolean( System.getProperty("tribu.distributed.PartialReplicationMode", partialDefault)); } public static final List<Address> getAllMembers() { return groupComm.getMembers(); } public static final Class<? extends DistributedContext> getContextClass() { return ctxClass; } public static final Class<? extends Group> getGroupClass() { return groupClass; } public static final Locator getLocator() { return locator; } public static final UniqueObject getObject(ObjectMetadata metadata) { return locator.get(metadata); } public static final void putObject(ObjectMetadata metadata, UniqueObject obj) { locator.put(metadata, obj); } public static final void onContextCreation(DistributedContext ctx) { distProtocol.onTxContextCreation(ctx); } public static final void onTxBegin(DistributedContext ctx) { distProtocol.onTxBegin(ctx); } public static final void onTxFinished(DistributedContext ctx, boolean committed) { distProtocol.onTxFinished(ctx, committed); } public static final void onTxCommit(DistributedContext ctx) { distProtocol.onTxCommit(ctx); } public static final Object onTxRead( DistributedContext ctx, ObjectMetadata metadata, Object value) { return distProtocol.onTxRead(ctx, metadata, value); } public static final void onTxWrite( DistributedContext ctx, ObjectMetadata metadata, UniqueObject obj) { distProtocol.onTxWrite(ctx, metadata, obj); } public static final String GETSERIALIZER_METHOD_NAME = "getObjectSerializer"; public static final String GETSERIALIZER_METHOD_DESC = "()" + ObjectSerializer.DESC; public static final ObjectSerializer getObjectSerializer() { return distProtocol.getObjectSerializer(); } public static final void sendTotalOrdered(byte[] payload) { groupComm.sendTotalOrdered(payload); } public static final void sendTotalOrdered(byte[] payload, Group groups) { groupComm.sendTotalOrdered(payload, groups); } public static final void sendReliably(byte[] payload) { groupComm.sendReliably(payload); } public static final void sendTo(byte[] payload, Address addr) { groupComm.sendTo(payload, addr); } public static final boolean isLocalAddress(Address addr) { return groupComm.isLocal(addr); } public static final void subscribeDeliveries(DeliverySubscriber subscriber) { groupComm.subscribeDelivery(subscriber); } public static final void subscribeOptimisticDeliveries(OptimisticDeliverySubscriber subscriber) { groupComm.subscribeOptimisticDelivery(subscriber); } public static final Address getLocalAddress() { return groupComm.getAddress(); } public static final Group getLocalGroup() { return groupPartitioner.getMyGroup(); } public static final List<Group> getAllGroups() { return groupPartitioner.getGroups(); } public static final Group publishObjectTo(UniqueObject obj) { return dataPartitioner.publishTo(obj); } public static final boolean isLocalGroup(Group group) { return getLocalGroup().equals(group); } }