我们有两个Java应用程序通过两个不同服务器上的EJB相互通信。
EJB在Spring中定义,ejb名称设置为Web逻辑中的外部JNDI。
<bean id="codingRemote" class="org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean">
<property name="jndiName" value="ejb/myEjb" />
<property name="businessInterface" value="com.my.ej.binterface" />
<property name="refreshHomeOnConnectFailure" value="true" />
</bean>
我将refreshHomeOnConnectFailure设置为true并且我可以重新启动远程服务器并重新连接但是如果我重新部署到远程服务器(我们的部署过程完全删除了Web逻辑域,重新创建它并部署新工件) )它似乎尝试连接但存在安全问题。
在远程计算机上,我在“重新部署”过程之后得到以下异常并且从客户端进行调用 - 因此客户端正在尝试进行调用但远程计算机/ JVM不接受该调用:
<Aug 28, 2014 11:20:23 AM CAT> <Warning> <RMI> <WL-080003> <A RuntimeException was generated by the RMI server: weblogic.jndi.internal.AdminRoleBasedDispatchServerRef@9, implementation: 'weblogic.jndi.internal.RootNamingNode@ac24b13', oid: '9', implementationClassName: 'weblogic.jndi.internal.RootNamingNode'
java.lang.SecurityException: [Security:090398]Invalid Subject: principals=[weblogic, Administrators].
java.lang.SecurityException: [Security:090398]Invalid Subject: principals=[weblogic, Administrators]
at weblogic.security.service.SecurityServiceManager.seal(SecurityServiceManager.java:833)
at weblogic.security.service.SecurityServiceManager.getSealedSubjectFromWire(SecurityServiceManager.java:522)
at weblogic.rjvm.MsgAbbrevInputStream.getSubject(MsgAbbrevInputStream.java:355)
at weblogic.rmi.internal.BasicServerRef.acceptRequest(BasicServerRef.java:1022)
at weblogic.rmi.internal.BasicServerRef.dispatch(BasicServerRef.java:350)
Truncated. see log file for complete stacktrace
环境Java7 / Weblogic12 / Spring2.5
知道如何通过此操作以允许登录或用户凭据登录再次重新开始?
我找到了两种可能的解决方案,但我不完全确定哪种解决方案最好,如果有任何问题。
解决方案1: - 指定一个JNDI模板,但这样做会破坏在weblogic中定义它的目的,现在它就是它自己的应用程序的一部分。
<bean id="codingRemote" class="org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean">
<property name="jndiName" value="ejb/myEjb" />
<property name="businessInterface" value="com.my.ej.binterface" />
<property name="refreshHomeOnConnectFailure" value="true" />
<property name="jndiTemplate">
<ref local="myProcessJndiTemplate" />
</property>
</bean>
<bean id="myProcessJndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">${specify.the.context}</prop>
<prop key="java.naming.provider.url">${specify.the.url}</prop>
<prop key="java.naming.security.authentication">none</prop>
</props>
</property>
</bean>
解决方案2: - 我在此site发现,如果我们覆盖SimpleRemoteStatelessSessionProxyFactoryBean,我们可以再次实例化安全性。
public class WebLogicSimpleRemoteStatelessSessionProxyFactoryBean extends SimpleRemoteStatelessSessionProxyFactoryBean {
@Override protected Object create() throws NamingException, InvocationTargetException {
try {
return getJndiTemplate().execute(new JndiCallback() {
public Object doInContext(final Context context) throws NamingException {
try {
return WebLogicSimpleRemoteStatelessSessionProxyFactoryBean.super.create();
} catch (final InvocationTargetException ite) {
throw new RuntimeException(ite);
}
}
});
} catch (final RuntimeException re) {
throw (InvocationTargetException) re.getCause();
}
}
protected void removeSessionBeanInstance(final EJBObject ejbObject) {
try {
getJndiTemplate().execute(new JndiCallback() {
public Object doInContext(final Context context) throws NamingException {
WebLogicSimpleRemoteStatelessSessionProxyFactoryBean.super.removeSessionBeanInstance(ejbObject);
return null;
}
});
} catch (final NamingException e) {
throw new RuntimeException(e);
}
}
protected Object doInvoke(final MethodInvocation methodInvocation) throws Throwable {
try {
return getJndiTemplate().execute(new JndiCallback() {
public Object doInContext(final Context context) throws NamingException {
try {
return WebLogicSimpleRemoteStatelessSessionProxyFactoryBean.super.doInvoke(methodInvocation);
} catch (final Throwable t) {
if (t instanceof NamingException) {
throw (NamingException) t;
} else {
throw new RuntimeException(t);
}
}
}
});
} catch (final RuntimeException re) {
throw re.getCause();
}
}
}