Java RMI上的事务对象

Java RMI上的事务对象,java,rmi,Java,Rmi,我试图用Java做一些不可能的事情,但也许有一个解决方案 下面的代码试图通过RMI传递事务对象 public class FileRepositoryImpl extends UnicastRemoteObject implements FileRepository { @Override public byte[] get(String appId, String filePath) throws RemoteException, NotBoundException {

我试图用Java做一些不可能的事情,但也许有一个解决方案

下面的代码试图通过RMI传递事务对象

public class FileRepositoryImpl extends UnicastRemoteObject
    implements FileRepository {

  @Override
  public byte[] get(String appId, String filePath) throws RemoteException, NotBoundException {
    Registry registry = LocateRegistry.getRegistry();
    XodusRepository repository = (XodusRepository) registry.lookup(XodusRepository.class.getName());
    final byte[][] bytes = {null};
    repository.transact(appId, true, new Command<byte[]>() {
      @Override public byte[] execute(jetbrains.exodus.entitystore.StoreTransaction txn) {
         Entity entity = txn.findWithBlob(Constants.ENTITYSTORE_FILE, filePath).getLast();
         if (entity != null) {
          InputStream blobStream = entity.getBlob(filePath);
          bytes[0] = Try.of(() -> ByteStreams.toByteArray(blobStream)).getOrNull();
         }
         return bytes[0];
      }
    });
    return bytes[0];
  }

}
另一方面,它拥有的另一个Java进程:

  @Override public <T> T transact(String appId, boolean isReadOnly, Command<T> command)
      throws NotBoundException, RemoteException {
    AtomicReference<T> result = null;
    manager.transactPersistentEntityStore(xodusRoot, appId, isReadOnly, txn -> {
      result.set(command.execute(txn));
    });
    return Try.of(() -> result.get()).getOrNull();
  }
@Override public T transact(字符串appId、布尔值isReadOnly、命令)
抛出NotBoundException、RemoteException{
原子参考结果=null;
manager.TransactionPersistentEntityStore(xodusRoot、appId、isReadOnly、txn->{
result.set(command.execute(txn));
});
返回Try.of(()->result.get()).getOrNull();
}

有没有办法在RMI上使用事务对象?

对于
FileRepositoryImpl$1
类,根异常似乎是
ClassNotFoundException
。当注册中心无法访问我们的业务类时,我们也有类似的症状。我们必须使用“代码库”属性使我们的类对rmiregistry.exe可见(现在还不记得详细信息)。@RalfKleberhoff您的意思是您可以这样做吗?这似乎不可能,我们做到了。对我们来说,有效的方法是在初始化的早期阶段,使用rmiregistry.exe可以找到相关类定义的URL
System.setProperty(“java.rmi.server.codebase”,codebaseUrl)
。作为一种特殊的攻击,我们将HTTP服务器集成到我们的应用程序中,该应用程序基于
getResourceAsStream()
,提供类文件服务,因此rmiregistry看到的类版本始终是最新的。作为一种安全措施,我们仅以这种方式发布了有限的类列表。“事务性”与此无关。该类必须在接收JVM的类路径上可用,如果必须的话,也可以通过代码库功能来访问。@从代码中可以看出,“bytes”变量驻留在RMI的“客户端”,同时它在传递到RMI的“服务器端”的“Command object”中被访问,因此,
bytes
位于客户端,并且在服务器上也在更新。因此,“服务器端”RMI如何能够从频谱的另一端为该变量赋值?RMI能否跨不同的进程访问对象?
  @Override public <T> T transact(String appId, boolean isReadOnly, Command<T> command)
      throws NotBoundException, RemoteException {
    AtomicReference<T> result = null;
    manager.transactPersistentEntityStore(xodusRoot, appId, isReadOnly, txn -> {
      result.set(command.execute(txn));
    });
    return Try.of(() -> result.get()).getOrNull();
  }