![](/img/trans.png)
[英]WildFly - EJB invocations from a remote client - Operation failed with status WAITING
[英]WildFly: EJB invocations from a remote client
我试图查找并调用在WildFly中部署为EAR的EJB。 我尝试了不同的方法。
Properties properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
properties.put(Context.PROVIDER_URL, "remote://localhost:4447");
properties.put(Context.SECURITY_PRINCIPAL, myUser);
properties.put(Context.SECURITY_CREDENTIALS, myPassword);
properties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
InitialContext context = new InitialContext(properties);
Object object = context.lookup(jndi);
MyService service = (MyService)object;
System.out.println(service.echo("JYM"));
它抛出了:
javax.naming.NamingException: Failed to connect to any server. Servers tried: [remote://localhost:4447]
at org.jboss.naming.remote.client.HaRemoteNamingStore.failOverSequence(HaRemoteNamingStore.java:213)
at org.jboss.naming.remote.client.HaRemoteNamingStore.namingStore(HaRemoteNamingStore.java:144)
at org.jboss.naming.remote.client.HaRemoteNamingStore.namingOperation(HaRemoteNamingStore.java:125)
at org.jboss.naming.remote.client.HaRemoteNamingStore.lookup(HaRemoteNamingStore.java:241)
at org.jboss.naming.remote.client.RemoteContext.lookup(RemoteContext.java:79)
at org.jboss.naming.remote.client.RemoteContext.lookup(RemoteContext.java:83)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at com.app.test.service.MyServiceTest.echo(MyServiceTest.java:60)
如果我添加以下属性:
properties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
properties.put("jboss.ejb.client.scoped.context", "true");
我收到了:
java.lang.IllegalStateException: EJBCLIENT000025: No EJB receiver available for handling [appName:roolafic, moduleName:usermanagement, distinctName:] combination for invocation context org.jboss.ejb.client.EJBClientInvocationContext@3c0f93f1
at org.jboss.ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:749)
at org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:116)
at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:183)
at org.jboss.ejb.client.EJBInvocationHandler.sendRequestWithPossibleRetries(EJBInvocationHandler.java:253)
at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:198)
at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:181)
at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:144)
at com.sun.proxy.$Proxy4.echo(Unknown Source)
at com.app.test.service.MyServiceTest.echo(MyServiceTest.java:62)
然后,我看到了一个Jboss论坛帖子 ,其中说使用http-remoting
而不是remote
。 但这也不起作用。 即使使用端口8080。
我已经尝试过这里提到的方法。 但是看来这不适用于我的情况。 尽管我已将jboss-ejb-client.properties
放在我从Eclipse运行客户端方法的目录中。
花了将近半天后,我找到了解决方案。 这里是:
public static <T> T connectEJB(String jndi) throws NamingException {
Properties clientProperties = new Properties();
clientProperties.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");
clientProperties.put("remote.connections", "default");
clientProperties.put("remote.connection.default.port", myPort);
clientProperties.put("remote.connection.default.host", myHost);
clientProperties.put("remote.connection.default.username", myUser);
clientProperties.put("remote.connection.default.password", myPassword);
clientProperties.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", "false");
EJBClientConfiguration ejbClientConfiguration = new PropertiesBasedEJBClientConfiguration(clientProperties);
ContextSelector<EJBClientContext> contextSelector = new ConfigBasedEJBClientContextSelector(ejbClientConfiguration);
EJBClientContext.setSelector(contextSelector);
Properties properties = new Properties();
properties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
Context context = new InitialContext(properties);
return (T) context.lookup(jndi);
}
有关更多信息,请参见此处 。 希望对其他人有帮助。
我在Wildfly 10上遇到了相同的异常。
在遵循一些重要参考文献的同时:
即有关在以下位置建立远程EJB连接的文档: https : //docs.jboss.org/author/display/WFLY10/EJB+invocations+from+a+remote+client+using+JNDI
java.lang.IllegalStateException:EJBCLIENT000025:
没有可用的EJB接收器来处理org.jboss.ejb.client.EJBClientContext上的调用上下文org.jboss.ejb.client.EJBClientInvocationContext@1b26f7b2的[appName :, moduleName:wildfly10-test-client-remote-ejb,distinctName:]组合org.org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:186)处org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:128)处的.requireEJBReceiver(EJBClientContext.java:798)。 org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:200)处的org.jboss.ejb.client.EJBInvocationHandler.doInvoke(jboss.ejb.client.EJBInvocationHandler.sendRequestWithPossibleRetries(EJBInvocationHandler.java:255) java:183)位于org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:146)位于com.sun.proxy。$ Proxy6.doWork(未知源)位于ejb.InvokeRemoteEjbTest.testThatFailsWithEJBCLIENT000025(InvokeRemote90eEjabTest.java )
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
位于org.junit的java.lang.reflect.Method.invoke(Method.java:498)处的sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)处的sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)的org.junit.runners.model.FrameworkMethod.invokeExplosively(.runners.model.FrameworkMethod $ 1.runReflectiveCall(FrameworkMethod.java:50) org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)处的org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)处的FrameworkMethod.java:47) org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)上的.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)在org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)上org.junit.runners.ParentRunner $ 3.run(ParentRunner.java:290)at org.junit.runners.ParentRunner $ 1.schedule(ParentRunne r.java:71)org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)org.junit.runners.ParentRunner.access $ 000(ParentRunner.java:58)org.junit.runners.ParentRunner $ 2在org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)在org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)在org.junit.runners.ParentRunner.run(ParentRunner.java:363)处.evaluate(ParentRunner.java:268) org.eclipse上的org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)上的org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)上的org.eclipse.jdt.internal的jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
但是这个测试异常并不是唯一的,我在控制台上也有以下异常:
NFO:XNIO版本3.3.4.2017年2月13日最终于org.xnio.nio.NioXnio信息:XNIO NIO实现版本3.3.4.2017年2月13日最终于12:42:28 org.jboss .remoting3.EndpointImpl INFO:JBoss Remoting版本4.0.18.Final Feb 13,2017 12:42:28 PM org.jboss.ejb.client.EJBClient INFO:JBoss EJB Client版本2.1.4.Final Feb 13,2017 12: 42:28 PM org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector setupEJBReceivers警告:无法注册EJB接收器以连接到本地主机:4447 java.io.EOFException:XNIO000812:org.xnio.http.HttpUpgrade $意外关闭连接org.xnio上的HttpUpgradeState $ UpgradeResultListener.handleEvent(HttpUpgrade.java:416).org.xnio上的http.HttpUpgrade $ HttpUpgradeState $ UpgradeResultListener.handleEvent(HttpUpgrade.java:400).orgListener上的ChannelListeners.invokeChannelListener(ChannelListeners.java:92) .xnio.conduits.ReadReadyHandler $ ChannelListenerHandler.readReady(ReadReadyHandler.java:66)在org.xnio.nio.NioSocketConduit.handleReady(NioSo org.xnio.nio.WorkerThread.run(WorkerThread.java:559)上的cketConduit.java:88)...异步调用...(org.jboss.remoting3.EndpointImpl.doConnect(EndpointImpl.java)上的(Unknown Source) :294),位于org.jboss.ejb的org.jboss.ejb.client.remoting.EndpointPool $ PooledEndpoint.connect(EndpointPool.java:192),位于org.jboss.remoting3.EndpointImpl.connect(EndpointImpl.java:416)。 org.jboss.ejb.client.remoting.NetworkUtil.connect(NetworkUtil.java:133)上的org.jboss.ejb.client.remoting.ConnectionPool.getConnection(上的client.remoting.NetworkUtil.connect(NetworkUtil.java:153) org.jboss.ejb.client.remoting.RemotingConnectionManager.getConnection(RemotingConnectionManager.java:51)上的ConnectionPool.java:78)
at org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector.setupEJBReceivers(ConfigBasedEJBClientContextSelector.java:161)
在org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector.getCurrent(ConfigBasedEJBClientContextSelector.java:118)在org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector.getCurrent(ConfigBasedEJBClientContextSelector.java:47)在org.jboss。 org.jboss.ejb.client.EJBClientContext.requireCurrent(EJBClientContext.java:291)位于org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:178)处的.EJBClientContext.getCurrent(EJBClientContext.java:281) org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:146)位于com.sun.proxy。$ Proxy6.doWork(未知源)位于ejb.InvokeRemoteEjbTest.testThatFailsWithEJBCLIENT000025(InvokeRemoteEjbTest.java:90)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
位于org.junit的java.lang.reflect.Method.invoke(Method.java:498)处的sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)处的sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)的org.junit.runners.model.FrameworkMethod.invokeExplosively(.runners.model.FrameworkMethod $ 1.runReflectiveCall(FrameworkMethod.java:50) org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)处的org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)处的FrameworkMethod.java:47) org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)上的.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)在org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)上org.junit.runners.ParentRunner $ 3.run(ParentRunner.java:290)at org.junit.runners.ParentRunner $ 1.schedule(ParentRunne r.java:71)org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)org.junit.runners.ParentRunner.access $ 000(ParentRunner.java:58)org.junit.runners.ParentRunner $ 2在org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)在org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)在org.junit.runners.ParentRunner.run(ParentRunner.java:363)处.evaluate(ParentRunner.java:268) org.eclipse上的org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)上的org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)上的org.eclipse.jdt.internal的jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
关键点如下。 (1)Jboss似乎具有行为不同的两个不同的代码层。 第一个是JNDI初始上下文,当您连接到“远程”端口(例如旧的传统端口4447)时,它可以正常工作。
因此,当您在代码中针对JNDI上下文执行以下操作时:
final Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, org.jboss.naming.remote.client.InitialContextFactory.class.getName());
env.put(Context.PROVIDER_URL, "remote://localhost:4447");
// why is this needed?
// This is an important property to set if you want to do EJB invocations via the remote-naming project
env.put("jboss.naming.client.ejb.context", true);
// Lookup optimization for @Stateless EJBs.
// https://docs.jboss.org/author/display/AS71/Remote+EJB+invocations+via+JNDI+-+EJB+client+API+or+remote-naming+project
// section: Why use the EJB client API approach then?
env.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
// authenticate
env.put(Context.SECURITY_PRINCIPAL, "adminUser");
env.put(Context.SECURITY_CREDENTIALS, "adminPassword");
initialContext = new InitialContext(env);
您可以将Remote EJB从服务器中移出,并且已经有了代理。 真正出错的地方是当您使用proxu并执行以下操作:
remoteEJB.doWorkg();
发生这种情况是因为代理上的Lookup逻辑和execute逻辑并不完全相同,也就是说,execute逻辑正在寻找这些逻辑:
“没有EJB接收器可用于处理”
基于配置文件:“ jboss-ejb-client.properties”
您应该在类路径中具有运行系统测试的权限。 或您的客户端应用程序。
现在,当您转到以下位置时:jboss-ejb-client.properties
您可以尝试配置您的“远程”端口4447,但这是非常错误的,因为您将无法使用现代远程EJB客户端。
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-ejb-client-bom</artifactId>
<version>10.0.0.Final</version>
<type>pom</type>
<scope>test</scope>
</dependency>
该客户端期望您的wildfly 10使用今天的默认配置进行配置,在该配置中,可以从常规HTTP套接字提供远程服务。 因此,它希望将HTTP套接字升级到TCP,就像Web套接字发生的事情一样。 这不适用于您的:4447套接字,从概念上讲从来没有一个http套接字。
因此,当我最终查看如何配置远程子系统时,我需要使用以下内容来增强它:
<subsystem xmlns="urn:jboss:domain:remoting:3.0">
<endpoint/>
<connector name="remoting-connector" socket-binding="remoting" security-realm="ApplicationRealm"/>
<http-connector name="http-remoting-connector" connector-ref="default" security-realm="ApplicationRealm"/>
</subsystem>
http连接器是新添加的。 现在,就JNDI初始上下文设置而言,我使用端口4447还是8080都没关系,两者都可以工作。 为了保持一致,我不使用仍打开的4447端口。我使用8080端口。 但是,对于8080罐,您的提供者URL必须进行如下修改:
env.put(Context.PROVIDER_URL, "http-remoting://localhost:8080");
我的建议是:为远程ejb子系统配置端口4447和8080。 但是对于客户端连接,请使用端口8080进行JNDI查找和EJB执行。
在这种情况下,wildfly异常是无用的边界,它对开发人员找出问题所在没有太大帮助。
解决此问题的关键是解决HTTP连接升级问题,并弄清楚套接字4447的行为显然是错误的。
最后,仅供参考。 您的ejb-client.proeprties文件应采用以下形式:
#QUOTE:
#First the endpoint.name property.
#We mentioned earlier that the EJB receivers will communicate with the server for EJB invocations.
#Internally, they use JBoss Remoting project to carry out the communication.
#The endpoint.name property represents the name that will be used to create the client side of the enpdoint.
# The endpoint.name property is optional and if not specified in the jboss-ejb-client.properties file, it will default to "config-based-ejb-client-endpoint" name.
# https://docs.jboss.org/author/display/WFLY10/EJB+invocations+from+a+remote+client+using+JNDI
endpoint.name=client-endpoint
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.host=localhost
remote.connection.default.port=8080
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
remote.connection.default.username=youAppServerAdmin
remote.connection.default.password=youAppServerAdminPass
要记住的关键是上面文件中的PORT应该是HTTP端口,而不是像4447这样的“远程”端口。至少在wildfly 10中,对于旧版本,我不确定。
祝好运。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.