简体   繁体   English

故障转移后在JSF Bean上进行@EJB注入

[英]@EJB injection on JSF Bean after failover

I'm using Weblogic 10.3.6, Mojarra 2.0.9 and EJB3. 我正在使用Weblogic 10.3.6,Mojarra 2.0.9和EJB3。 We have @ViewScoped and @SessionScoped JSF Managed beans and we require that in the event of a server failing the use can still continue. 我们拥有@ViewScoped和@SessionScoped JSF托管Bean,并且我们要求在服务器发生故障的情况下仍可以继续使用。 I had just about cracked it until I hit upon a problem using EJB injection on the JSF Beans. 我刚刚破解了它,直到遇到在JSF Bean上使用EJB注入的问题。 Here are the simplifed beans 这是豆类

EJB Interface EJB接口

@JNDIName("our.ejb.jndiname")
@Remote
public interface OurEJBInterface {

    some methods...

}

EJB Bean EJB Bean

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class ourBean implements OurEJBInterface {

    the methods...
}

JSF Backing Bean JSF支持豆

@ManagedBean
@ViewScoped
public class OurBackingBean  {


    @EJB
    private OurBeanBeanInterface ourBeanBeanInterface ;


    public void submit()
    {
        ourBeanBeanInterface.doSomethingFromBean(); 
    }

}

When we simulate a failover the session is correctly retrieved from the new server however the reference to the EJB still points to the old server and we get this error: 当我们模拟故障转移时,可以从新服务器正确检索会话,但是对EJB的引用仍然指向旧服务器,并且出现以下错误:

javax.ejb.EJBException: Could not establish a connection with -1977369784351278190S:MCPVMWLS01:[7030,7030,-1,-1,-1,-1,-1]:Destin8ShowCase:JVM01, java.rmi.ConnectException: Destination unreachable; nested exception is: 
    java.io.IOException: Empty server reply; No available router to destination; nested exception is: 
    java.rmi.ConnectException: Destination unreachable; nested exception is: 
    java.io.IOException: Empty server reply; No available router to destination; nested exception is: java.rmi.ConnectException: Destination unreachable; nested exception is: 
    java.io.IOException: Empty server reply; No available router to destination
java.rmi.ConnectException: Destination unreachable; nested exception is: 
    java.io.IOException: Empty server reply; No available router to destination
    at weblogic.rjvm.ConnectionManager.bootstrap(ConnectionManager.java:470)
    at weblogic.rjvm.ConnectionManager.bootstrap(ConnectionManager.java:402)
    at weblogic.rjvm.RJVMImpl.ensureConnectionEstablished(RJVMImpl.java:306)
    at weblogic.rjvm.RJVMImpl.getOutputStream(RJVMImpl.java:350)
    at weblogic.rjvm.RJVMImpl.getRequestStreamInternal(RJVMImpl.java:612)
    at weblogic.rjvm.RJVMImpl.getRequestStream(RJVMImpl.java:563)
    at weblogic.rjvm.RJVMImpl.getOutboundRequest(RJVMImpl.java:789)
    at weblogic.rmi.internal.BasicRemoteRef.getOutboundRequest(BasicRemoteRef.java:159)
    at weblogic.rmi.internal.BasicRemoteRef.invoke(BasicRemoteRef.java:211)
    at com.mcpplc.destin8.ejbs.manifestenquiry.ManifestEnquiryFacadeBean_qzni2o_ManifestEnquiryFacadeBeanInterfaceImpl_1036_WLStub.doMEQ02(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at weblogic.ejb.container.internal.RemoteBusinessIntfProxy.invoke(RemoteBusinessIntfProxy.java:85)
    at $Proxy286.doMEQ02(Unknown Source)
    at com.mcpplc.destin8.web.jsf.backingbeans.imports.Meq02BackingBean.customProcessing(Meq02BackingBean.java:49)
    at com.mcpplc.destin8.web.jsf.backingbeans.BackingBean.submit(BackingBean.java:179)

Is there any way to get the Managed Bean to reinitialise a new EJB ref pointing to the new server? 有什么方法可以使Managed Bean重新初始化指向新服务器的新EJB引用?

I know I can use a service locator with the init placed in the submit method but would like to use @EJB if possible. 我知道我可以将服务定位器与init方法放在init中一起使用,但如果可能的话,我想使用@EJB。

Thanks in advance. 提前致谢。

I come from the JBoss world so I'm not completely sure about it. 我来自JBoss世界,因此我不太确定。 But can you really inject a remote interface in that way? 但是您真的可以通过这种方式注入远程接口吗? There must be a lookup defined, I think. 我认为必须定义一个查找。 However for a local-interface your call should work. 但是,对于本地接口,您的呼叫应该可以工作。 And if you use remote-interfaces you should use 如果使用远程接口,则应使用

@EJB(lookup="jnp://wholeclustername/YourBean/remote")

and your DNS must point your network to both machines. 并且您的DNS必须将您的网络指向两台计算机。

Another possible workaround can be a @Produce-method and an @Inject where you do the lookup in the producer-method. 另一个可能的解决方法是@Produce方法和@Inject,您可以在生产方法中进行查找。

Edit: 编辑:

Yes, unfortunately. 是的,很不幸的。 I face these hacks from time to time, too:( 我也会不时面对这些骇客:(

Maybe there's another workaround or a solution, I'm not firm enough in Weblogic. 也许还有其他解决方法或解决方案,但我对Weblogic的了解不够坚定。 If you wanna decouple it from your source you can also use an interceptor and inject a slsb instance each call, maybe because of your failover it work with a @PostConstruct, too. 如果您想将其与源分离,还可以使用拦截器并在每次调用时注入一个slsb实例,这可能是因为您进行了故障转移,它也可以与@PostConstruct一起使用。 I dont know: 我不知道:

public class LookUpEJBInterceptor {

 @AroundInvoke public Object around(InvocationContext ctx){ try { Class<?> clazzOfEJBImplementation = ctx.getTarget().getClass(); //look for your field, I just check for the EJB annotation but that's not enough for (Field f : clazzOfEJBImplementation.getDeclaredFields()){ if(f.isAnnotationPresent(EJB.class)){ f.setAccessible(true); f.set(ctx.getTarget(), lookupEJB()); } } return ctx.proceed(); } catch (Exception e) { e.printStackTrace(); throw new EJBException(); } } /** * get your ejb * * @return * @throws NamingException */ private Object lookupEJB() throws NamingException{ return new InitialContext().lookup("Your ejb lookup"); } 

Second edit: 第二编辑:

If you can use AspectJ you can construct a hack like this: 如果可以使用AspectJ,则可以构建如下所示的hack:

 pointcut checkEJB(OurEJBInterface r): call(void OurEJBInterface.yourVoid()) && target(r); void around (OurEJBInterface r) : yourVoid(r){ r = lookupYourEJB(); return proceed(r); } private Object lookupEJB() throws NamingException{ return new InitialContext().lookup("Your ejb lookup"); } 

But both are only hacks 但这两者都是骇客

Managed to resolve this after some trial and error. 经过反复尝试后设法解决了这个问题。 As Jan eluded to my set up was injecting only a local jndi name. 简(Jan)在我的设置中还只是注入一个本地的jndi名称。 To ensure the returned EJB proxy was global I needed to remove the @JNDIname annotation from the interface and provide a mappedName to the @stateless and @ejb annotations 为了确保返回的EJB代理是全局的,我需要从接口中删除@JNDIname批注,并为@stateless@ejb批注提供一个@stateless

@Stateless(mappedName = "MyFacadeBean")

@EJB(mappedName = "MyFacadeBean")
private MyFacadeBean myFacadeBean;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM