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函数调用确保其线程已初始化。
答案 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);
}
}