我有一个swing应用程序,它调用部署在 Weblogic 10.3.6 上的无状态EJB( EJB 2.1 )。无状态EJB通过JAAS保护。 Web应用程序客户端通过JNDI查找获取远程接口。 为了提高性能,我想缓存EJBHome,以便在客户端只创建一次EJBHome。出于同样的原因,我想在客户端缓存远程接口。
无状态EJB方法的第一次调用成功。之后,每个远程方法调用都会生成javax.ejb.EJBAccessException: [EJB:010160]Security Violation: User: '<anonymous>' has insufficient permission to access EJB
。
我的客户端实施:
public class ServiceLocatorUtil {
/**
* Cached remote home (EJBHome). Uses lazy loading to obtain its value
* (loaded by getHome() methods).
*/
private static MyEJBProxyHome cachedRemoteHome = null;
private static MyEJBProxy proxy = null;
/**
* Obtain remote home interface from default initial context
*/
private static MyEJBProxyHome getHome()
throws javax.naming.NamingException {
if (cachedRemoteHome == null) {
cachedRemoteHome = (MyEJBProxyHome) lookupHome(null,
MyEJBProxyHome.JNDI_NAME, MyEJBProxyHome.class);
}
return cachedRemoteHome;
}
public static Proxy getProxy() throws RemoteException, CreateException,
NamingException {
if (proxy == null) {
proxy = getHome().create();
}
return proxy;
}
/**
* Home interface lookup methods
*/
private static Object lookupHome(java.util.Hashtable environment,
String jndiName, Class narrowTo)
throws javax.naming.NamingException {
// Obtain initial context
javax.naming.InitialContext initialContext = null;
try {
Hashtable env = new Hashtable();
env.put(Context.PROVIDER_URL,props.getProperty("t3://localhost:6969"));
env.put(Context.SECURITY_PRINCIPAL,props.getProperty("weblogic"));
env.put(Context.SECURITY_CREDENTIALS,props.getProperty("welcome"));
env.put(Context.INITIAL_CONTEXT_FACTORY, props
.getProperty("weblogic.jndi.WLInitialContextFactory"));
initialContext = new javax.naming.InitialContext(env);
Object objRef = initialContext.lookup(jndiName);
// only narrow if necessary
if (java.rmi.Remote.class.isAssignableFrom(narrowTo))
return javax.rmi.PortableRemoteObject.narrow(objRef,
narrowTo);
else
return objRef;
} catch (Exception e) {
getLogger().error(
"Remote EJB cannot be found. " + e.getMessage());
return null;
}
}
}
我的用法:
public class MyTransactionService {
...
public String getEJBRemoteData(String xmlTransaction) {
String xmlData = null;
try {
synchronized ("A STRING")) {
xmlData = ServiceLocatorUtil.getProxy().getDataByXMLFormat(xmlTransaction);
}
} catch (Exception ex) {
getLogger().error("Cannot send transaction data to EJB remote: Exception: "+ ex);
}
return xmlData;
}
....
}
我认为这不是因为远程接口的缓存,因为如果我在每次调用无状态EJB方法之前创建initialContext,则不会发生异常。
这是它的日志:
15/12/17 11:31:02 Executing thread : RMICallHandler-6
15/12/17 11:31:05 Initialized thread name :RMICallHandler-6
15/12/17 11:31:28 Executing thread : RMICallHandler-5
ERROR [RMICallHandler-5] (MyTransactionService.java:707) - Cannot send transaction data to EJB remote: Exception: java.rmi.AccessException: [EJB:010160]Security Violation: User: '<anonymous>' has insufficient permission to access EJB: type=<ejb>, application=RemoteEJB, module=integration-proxy-ejb.jar, ejb=MyEJBProxy, method=getDataByXMLFormat, methodInterface=Remote, signature={java.lang.String}.
15/12/17 11:31:29 Executing thread : HTTPThreadGroup-4
ERROR [HTTPThreadGroup-4] (MyTransactionService.java:707) - Cannot send transaction data to EJB remote: Exception: java.rmi.AccessException: [EJB:010160]Security Violation: User: '<anonymous>' has insufficient permission to access EJB: type=<ejb>, application=RemoteEJB, module=integration-proxy-ejb.jar, ejb=MyEJBProxy, method=getDataByXMLFormat, methodInterface=Remote, signature={java.lang.String}.
15/12/17 11:31:29 Executing thread : HTTPThreadGroup-8
ERROR [HTTPThreadGroup-8] (MyTransactionService.java:707) - Cannot send transaction data to EJB remote: Exception: java.rmi.AccessException: [EJB:010160]Security Violation: User: '<anonymous>' has insufficient permission to access EJB: type=<ejb>, application=RemoteEJB, module=integration-proxy-ejb.jar, ejb=MyEJBProxy, method=getDataByXMLFormat, methodInterface=Remote, signature={java.lang.String}.
15/12/17 11:31:30 Executing thread : HTTPThreadGroup-7
ERROR [HTTPThreadGroup-7] (MyTransactionService.java:707) - Cannot send transaction data to EJB remote: Exception: java.rmi.AccessException: [EJB:010160]Security Violation: User: '<anonymous>' has insufficient permission to access EJB: type=<ejb>, application=RemoteEJB, module=integration-proxy-ejb.jar, ejb=MyEJBProxy, method=getDataByXMLFormat, methodInterface=Remote, signature={java.lang.String}.
15/12/17 11:31:30 Executing thread : RMICallHandler-5
ERROR [RMICallHandler-5] (MyTransactionService.java:707) - Cannot send transaction data to EJB remote: Exception: java.rmi.AccessException: [EJB:010160]Security Violation: User: '<anonymous>' has insufficient permission to access EJB: type=<ejb>, application=RemoteEJB, module=integration-proxy-ejb.jar, ejb=MyEJBProxy, method=getDataByXMLFormat, methodInterface=Remote, signature={java.lang.String}.
15/12/17 11:31:31 Executing thread : RMICallHandler-6
作为日志信息,我看到fisrt执行线程(RMICallHandler-6)将初始化EJBHome并将其缓存在ServiceLocatorUtil.cachedRemoteHome
中,并且该线程将成功完成其工作。但是当另一个像RMICallHandler-5或HTTPThreadGroup-4 ..将抛出一个匿名访问异常。
我的实施有什么问题吗? 任何建议都会有所帮助。