2017-05-15 32 views
0

他のejb接続を開いたり閉じたりしている間は、接続を維持してejb接続を開いたり、クライアントが終了するとすぐに接続を閉じるその後の作業のために新しいものが開かれましたか?EJB接続を開いたままにして後続の接続を開いたり閉じたりするアプリケーションでの問題

私は現在、EJB(JBoss AS 7.1.1.final)を使用するSwingアプリケーションを開発中です。アプリケーションは、ejb接続をオープンし(すなわち、InitialContextインスタンスを生成する)、そのアプリケーションが実行されたままである限り、そのInitialContextを共通タスクに使用する。追加のejb接続(およびInitialContext)が作成されるいくつかの長期実行操作があります。この接続は、1つの長時間実行されるプロセスに使用され、その後閉じられます。

JBossでは、約40回目の接続を開いて閉じた後、以下の例外が発生します。

2017 May 15, 16:29:03 INFO - (JBossEJBClient.java:121) initialize - JNDI context initialized. 
java.lang.IllegalStateException: No EJB receiver available for handling [appName:dtsjboss,modulename:dtsserverejb,distinctname:] combination for invocation context [email protected] 
    at org.jboss.ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:584) 
    at org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:119) 
    at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:181) 
    at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:136) 
    at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:121) 
    at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:104) 
    at com.sun.proxy.$Proxy4.getAuthorities(Unknown Source) 
    at com.apelon.dts.examples.errors.ejb.EjbConnectionNotClosedErrorExample.doTest(EjbConnectionNotClosedErrorExample.java:53) 
    at com.apelon.dts.examples.errors.ejb.EjbConnectionNotClosedErrorExample.bothCasesShouldSucceed(EjbConnectionNotClosedErrorExample.java:34) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 

私は以下のコード、EJBの接続が使用されている場合を実行して、作品を閉じたが、単一の接続が開いたままになっている場合は、上記のスタックトレースに失敗した場合。

package com.myCompany.myApp.examples.errors.ejb; 

import java.util.List; 
import java.util.Properties; 

import javax.naming.Context; 
import javax.naming.InitialContext; 

import org.apache.log4j.Logger; 
import org.junit.Test; 

import com.myCompany.myApp.client.jboss.JBossEJBClient; 
import com.myCompany.myApp.dao.client.myAppServiceClient; 
import com.myCompany.myApp.dao.client.myAppServiceClientParams; 
import com.myCompany.myApp.testing.util.logging.LoggerForIntegrationTests; 
import com.myCompany.myAppserver.dao.remote.AuthorityDao; 
import com.myCompany.myAppserver.types.TAuthority; 
import com.myCompany.install.util.ejb.ejbclient.myAppServiceClientFactory; 

public class EjbConnectionNotClosedErrorExample { 

    private static Logger logger = LoggerForIntegrationTests.get(); 

    private static final int COUNT = 100; 

    @Test 
    public void bothCasesShouldSucceed() { 
     try { 
      logger.debug("Doing case that works"); 
      doTest(true); 
      logger.debug("Done with case that works."); 
      logger.debug("\n\n\n"); 
      logger.debug("********************* DOING CASE THAT FAILS *********************"); 
      doTest(false); 
      logger.debug("Done with use case that didn't work."); 
     } catch (Exception exp) { 
      exp.printStackTrace(); 
      throw new RuntimeException(exp); 
     } 
    } 

    private void doTest(boolean closeConnection) { 
     myAppServiceClientParams params = myAppServiceClientFactory.getDefaultClientParams(); 
     JBossEJBClient blocker = new JBossEJBClient(); 
     blocker.initialize(params); 
     if (closeConnection == true) { 
      blocker.close(); 
     } 
     int max = COUNT; 
     for (int i = 0; i < max; i++) { 
      myAppServiceClient client = myAppServiceClientFactory.getDefaultClient(); 
      AuthorityDao dao = client.createAuthorityDao(); 
      List<TAuthority> list = dao.getAuthorities(); 
      logger.debug("CONNECTION " + (i + 1) + " ------------------------------------------------"); 
      logger.debug("Got " + list.size() + " authorities."); 
      client.close(); 
     } 
     System.out.println(""); 
    } 

    public void initialize(myAppServiceClientParams params) { 
     this.initialize(params.getHost(), params.getPort(), params.getInstance(), params.getUid(), params.getPwd()); 
    } 

    public void initialize(String host, int port, String instance, String user, String password) { 
     final Properties jndiProperties = new Properties(); 
     String providerURL = "remote://" + host + ":" + port; 
     jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, org.jboss.naming.remote.client.InitialContextFactory.class.getName()); 
     jndiProperties.put(Context.PROVIDER_URL, providerURL); 
     jndiProperties.put("jboss.naming.client.ejb.context", true); 
     jndiProperties.put("jboss.naming.client.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false"); 
     // Explicitly specify STARTTLS = false for connecting to Wildfly v10 
     jndiProperties.put("jboss.naming.client.connect.options.org.xnio.Options.SSL_STARTTLS", "false"); 
     jndiProperties.put(Context.SECURITY_PRINCIPAL, user); 
     jndiProperties.put(Context.SECURITY_CREDENTIALS, password); 
     try { 
      InitialContext ctx = new InitialContext(jndiProperties); 
      ctx.getEnvironment(); 
     } catch (Exception e) { 
      throw new RuntimeException(e); 
     } 
    } 

} 

これはJBoss AS 7.1.1.finalに固有のバグですか?

+0

私は、一定期間後にファイアウォールがこのような接続を切断するのを見ました。 1#接続:欠落しているユーザー/パス無効 3#のEJB::接続が 2#セキュリティを破ら接続しますが、EJBが ではありません4つの#SSL JBossは、他のサーバーへの持続的接続を維持 –

+0

それはいくつかの問題を持つことができますクライアントがこのメッセージを見ると、呼び出ししようとしているejbを持つサーバに接続がないことを意味します。したがって、接続が他のサーバに失敗したときにメッセージが記録されます。 –

+0

@SteveC:JUnitテストが約1秒で実行されるので、ここでは起こっていないと思っています。 – John

答えて

0

ここでの問題は、アプリケーションのメインスレッドが単一の接続を開いてリソースとして使用していて、これが(何らかの理由で)JBossが他の接続を完全に割り当て解除しなかったことです。解決策は、開いたときにこの接続への参照を取得してから、この接続を閉じてから新しい接続を作成し、新しい接続が作成されるとすぐにメインスレッドが使用する接続を再オープンすることでした。

関連する問題