Java单线程RMI或替代方案

时间:2012-12-18 18:52:06

标签: java rmi rpc

Lotus Notes Java库只能在32位JVM中运行,我需要从我的64位JVM应用程序中调用它,所以我编写了一个RMI桥:64位应用程序运行32位RMI服务器,并与32位服务器通话以进行Lotus Notes调用。

Lotus Notes要求每个线程(将调用任何Lotus Notes函数)调用lotus.domino.NotesThread.sinitThread();在调用任何其他Lotus Notes函数之前,以及通过调用un-init函数在最后进行清理,这些调用可能很昂贵。

由于RMI不保证单线程执行,我如何将所有请求传递给已为Lotus Notes初始化的单个线程?我也对其他RPC /“桥接”方法开放(更喜欢使用Java)。目前,我必须确保我已定义的每个RMI函数调用确保其线程已初始化。

2 个答案:

答案 0 :(得分:1)

使用single thread executor service,每次要调用lotus notes方法时,向执行程序提交任务,获取返回的Future,并从Future获取方法调用的结果。

例如,要调用方法Bar getFoo(),您将使用以下代码:

Callable<Bar> getFoo = new Callable<Bar>() {
    @Override
    public Bar call() {
        return lotuNotes.getFoo();
    }
};
Future<Bar> future = executor.submit(getFoo);
return future.get();

答案 1 :(得分:0)

getName()是一个简单的例子,因此每个代码都会得到这种处理方式(这会极大地破坏代码,但它可以工作!)

    @Override
    public String getName() throws RemoteException, NotesException {
        java.util.concurrent.Callable<String> callableRoutine =
                new java.util.concurrent.Callable<String>() {

                    @Override
                    public String call() throws java.rmi.RemoteException, NotesException {
                        return lnView.getName();
                    }
                };
        try {
            return executor.submit(callableRoutine).get();
        } catch (Exception ex) {
            handleExceptions(ex);
            return null; // not used
        }
    }


/**
 * Handle exceptions from serializing to a thread.
 *
 * This routine always throws an exception, does not return normally.
 *
 * @param ex
 * @throws java.rmi.RemoteException
 * @throws NotesException
 */
private void handleExceptions(Throwable ex) throws java.rmi.RemoteException, NotesException {
    if (ex instanceof ExecutionException) {
        Throwable t = ex.getCause();
        if (t instanceof java.rmi.RemoteException) {
            throw (java.rmi.RemoteException) ex.getCause();
        } else if (t instanceof NotesException) {
            throw (NotesException) ex.getCause();
        } else {
            throw new NotesException(LnRemote.lnErrorRmi, utMisc.getExceptionMessageClean(t), t);
        }
    } else {
        throw new NotesException(LnRemote.lnErrorRmi, utMisc.getExceptionMessageClean(ex), ex);
    }
}