0

私は Weblogic 10.3.6、Mojarra 2.0.9、および EJB3 を使用しています。@ViewScoped および @SessionScoped JSF Managed 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 バッキング Bean

@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)

管理対象 Bean に、新しいサーバーを指す新しい EJB ref を再初期化させる方法はありますか?

submit メソッドに init を配置してサービス ロケーターを使用できることはわかっていますが、可能であれば @EJB を使用したいと考えています。

前もって感謝します。

4

2 に答える 2

0

私はJBossの世界から来たので、それについて完全にはわかりません。しかし、本当にその方法でリモート インターフェイスを挿入できますか? ルックアップが定義されている必要があると思います。ただし、ローカル インターフェイスの場合、呼び出しは機能するはずです。また、リモートインターフェイスを使用する場合は、使用する必要があります

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

また、DNS がネットワークを両方のマシンに向ける必要があります。

別の可能な回避策は、 @Produce-method および @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");
}

2番目の編集:

AspectJ を使用できる場合は、次のようなハックを作成できます。

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

しかし、どちらも単なるハックです

于 2013-04-09T14:09:38.867 に答える