簡體   English   中英

故障轉移后在JSF Bean上進行@EJB注入

[英]@EJB injection on JSF Bean after failover

我正在使用Weblogic 10.3.6,Mojarra 2.0.9和EJB3。 我們擁有@ViewScoped和@SessionScoped JSF托管Bean,並且我們要求在服務器發生故障的情況下仍可以繼續使用。 我剛剛破解了它,直到遇到在JSF Bean上使用EJB注入的問題。 這是豆類

EJB接口

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

    some methods...

}

EJB Bean

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

    the methods...
}

JSF支持豆

@ManagedBean
@ViewScoped
public class OurBackingBean  {


    @EJB
    private OurBeanBeanInterface ourBeanBeanInterface ;


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

}

當我們模擬故障轉移時,可以從新服務器正確檢索會話,但是對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)

有什么方法可以使Managed Bean重新初始化指向新服務器的新EJB引用?

我知道我可以將服務定位器與init方法放在init中一起使用,但如果可能的話,我想使用@EJB。

提前致謝。

我來自JBoss世界,因此我不太確定。 但是您真的可以通過這種方式注入遠程接口嗎? 我認為必須定義一個查找。 但是,對於本地接口,您的呼叫應該可以工作。 如果使用遠程接口,則應使用

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

並且您的DNS必須將您的網絡指向兩台計算機。

另一個可能的解決方法是@Produce方法和@Inject,您可以在生產方法中進行查找。

編輯:

是的,很不幸的。 我也會不時面對這些駭客:(

也許還有其他解決方法或解決方案,但我對Weblogic的了解不夠堅定。 如果您想將其與源分離,還可以使用攔截器並在每次調用時注入一個slsb實例,這可能是因為您進行了故障轉移,它也可以與@PostConstruct一起使用。 我不知道:

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"); } 

第二編輯:

如果可以使用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"); } 

但這兩者都是駭客

經過反復嘗試后設法解決了這個問題。 簡(Jan)在我的設置中還只是注入一個本地的jndi名稱。 為了確保返回的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