我正在尝试从我在Tomcat 6下运行的Servlet中运行JBoss AS 7.1.1 final中的某些EJB进行远程调用。 EJB是封闭源,可以从一些给定的jar(封闭代码)访问,它使用Delegate-Pattern来包装对无状态Bean的访问。
经过几天的jndi-lookup正确配置后,我发现了不同的配置,这些都会产生不同的问题。
解决方案A:
由于Tomcat 6拥有自己的jndi,因此只需在类路径中放置一个jndi.properties(如果从一个简单的java应用程序访问EJB就可以正常工作),就不起作用了。相反,我将哈希表中的属性传递给委托的构造函数,如下所示:
Hashtable<String, String> jndiProperties = new Hashtable<String, String>();
jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.as.naming.interfaces:org.jboss.ejb.client.naming");
jndiProperties.put(Context.PROVIDER_URL, "remote://10.10.10.10:4447");
jndiProperties.put(Context.SECURITY_PRINCIPAL, "user");
jndiProperties.put(Context.SECURITY_CREDENTIALS, "password");
Delegate someDelegate = new DelegateImpl(jndiProperties);
这会导致以下异常(从简单的Java应用程序执行相同操作时不会发生这种情况):
java.lang.IllegalStateException: No EJB receiver available for handling [appName:eex,modulename:eex-ejb,distinctname:] combination for invocation context
一些研究建议我尝试......
解决方案B:
我添加了以下行:
jndiProperties.put("jboss.naming.client.ejb.context", "true");
现在查找和远程调用工作正常,但是在一些调用之后我得到以下异常(当从简单的java应用程序执行相同操作时也会发生这种情况):
org.jboss.remoting3.ProtocolException: Too many channels open
据我所知,在jboss.naming.client.ejb.context设置为true的情况下,为JBoss AS端的每次查找创建一个新的EJBClientContext,看起来,Delegate没有正确关闭它。有关如何正确关闭https://docs.jboss.org/author/display/WFLY8/Scoped+EJB+client+contexts下的所有上下文的详细说明。
由于我不拥有Delegate-source-code,因此无法正确关闭上下文。
所以我试过......
解决方案C:
执行查找有一种完全不同的方式:提供jboss-ejb-client.xml而不是jndi.properties。这与tomcat很好地配合使用,并且使用此配置查找很好:
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.port=4447
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
remote.connection.default.host=10.10.10.10
remote.connection.default.username=user
remote.connection.default.password=password
但是,使用此配置时,我会不时遇到以下异常(到目前为止我无法重现它,有时会发生异常):
ERROR: JBREM000200: Remote connection failed: the timeout for the connection expired
...and some lines later...
Caused by: java.io.IOException: Channel Channel ID 841ded9c (outbound) of Remoting connection 00dcc89a to null has been closed
非常感谢任何帮助...
答案 0 :(得分:2)
我仍然不知道解决方案A的问题的答案。
我描述了解决方案B的可能问题。
解决方案C的例外是由我们的防火墙引起的,它在几分钟不活动后丢弃了会话表条目。我通过添加
解决了这个问题remote.connection.default.connect.options.org.jboss.remoting3.RemotingOptions.HEARTBEAT_INTERVAL=60000
到jboss-ejb-client.properties。
这会导致每分钟从客户端到JBoss AS的“ping”,这会阻止防火墙丢弃会话条目。
答案 1 :(得分:0)
所以...我也有这个问题(和其他人),我会尝试在这里解释(我不知道是否用正确的术语)我打算做什么以及我如何解决,它对我有用。 我们进行了几次远程ejb调用,最终我们遇到了以下问题:
Caused by: java.io.IOException: Channel Channel ID fa8f69c7 (outbound) of Remoting connection 0196f4b5 to null has been closed
(https://developer.jboss.org/thread/198390)
这是由于没有管理上下文的远程调用,因此JBoss本身负责自动管理通信通道。 但随着时间的推移,这种联系随着时间的推移而无所事事,并最终发生在“失败”的情况下。此连接,由于已知或未知原因(防火墙,连接限制,上载新版本时)
因此,为了解决第一个问题,我查看了以下文档:
https://docs.jboss.org/author/display/WFLY8/Scoped+EJB+client+contexts
放置以下属性后:
props.put ("org.jboss.ejb.client.scoped.context", "true");
然后我们管理ejb范围,因此我们可以打开和关闭通信渠道。 所以我遇到了另一个问题:
Unrecognized SSL message, plaintext connection
理论上会发生这种情况,因为服务器默认不支持ssl通信。 要解决此问题,您必须输入以下属性:
props.put ("remote.connection." + ConnectionName "+ connect.options.org.xnio.Options.SSL_ENABLED", "false");
(你必须以同样的方式填写主机和端口)
然后我们陷入了另一个问题:
Invalid option 'org.xnio.Options.SSL_ENABLED' in property 'remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED': java.lang.IllegalArgumentException: Class 'org.xnio.Options' not found
这是由于缺乏对XNIO的依赖。你可以将jboss-ejb-client的依赖项放在你要解决的pom上(在我的例子中我使用了jboss-as-ejb-client-bom), 但它部分解决了我。当它处于不同的耳朵时,我遇到了同样的问题,直到最后我把这个配置放在jboss-deployment-structure.xml中 导出依赖:
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name = "org.jboss.xnio" export = "true" />
</dependencies>
</deployment>
</jboss-deployment-structure>
最后看到该类,它可以实例化并将SSL_ENABLED设置为false。 现在我手动管理ejb示波器,我可以打开和关闭通道,解决闭合连接问题。
希望它有所帮助。