Use Older "remoting" Protocol Instead of "http-remoting" with "http-upgrade" in JBoss EAP 7
Environment
- Red Hat JBoss Enterprise Application Platform (EAP)
- 7
- Remote-invoked / client-server / server-to-server Enterprise Java Beans (EJB), potentially with EJB hosted on JBoss EAP 6
- Remoting protocol
Issue
- Configure
remoteprotocol - Call Remote EJB on old version of JBoss EAP
-
Remote invokation fails with
TRACE [org.jboss.remoting.remote.connection] (default I/O-59) Connection error detail: java.io.IOException: XNIO000804: Received an invalid message length of 369296128 at org.xnio.channels.FramedMessageChannel.receive(FramedMessageChannel.java:108) at org.jboss.remoting3.remote.ServerConnectionOpenListener$Initial.handleEvent(ServerConnectionOpenListener.java:228) at org.jboss.remoting3.remote.ServerConnectionOpenListener$Initial.handleEvent(ServerConnectionOpenListener.java:139) at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92) at org.xnio.channels.TranslatingSuspendableChannel.handleReadable(TranslatingSuspendableChannel.java:199) at org.xnio.channels.TranslatingSuspendableChannel$1.handleEvent(TranslatingSuspendableChannel.java:113) at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92) at org.xnio.ChannelListeners$DelegatingChannelListener.handleEvent(ChannelListeners.java:1092) at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92) at org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66) at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:88) at org.xnio.nio.WorkerThread.run(WorkerThread.java:559) DEBUG [org.jboss.remoting.remote.connection] (default I/O-59) JBREM000200: Remote connection failed: java.io.IOException: XNIO000804: Received an invalid message length of 369296128 -
Our
remote-outbound-connectiongets errorjava.io.IOException: Invalid responseusing configuration:<remote-outbound-connection name="remote-ejb-connection" outbound-socket-binding-ref="remote-ejb" username="RemotingUser" security-realm="ejb-security-realm">Error in log
ERROR [org.jboss.as.ejb3.invocation] (default task-2) REQ-TRX= SESSION= WFLYEJB0034: EJB Invocation failed on component XXXXXService for method public abstract xx,xx.getMETHOD(java.lang.String): javax.ejb.NoSuchEJBException: EJBCLIENT000079: Unable to discover destination for request for EJB StatelessEJBLocator for "XXX/XXX-ejb/XXXXXService", view is interface XXXX, affinity is None at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:567) [jboss-ejb-client-4.0.10.Final-redhat-1.jar:4.0.10.Final-redhat-1] at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:503) [jboss-ejb-client-4.0.10.Final-redhat-1.jar:4.0.10.Final-redhat-1] ... Suppressed: java.io.IOException: Invalid response at org.xnio.http.HttpUpgradeParser.parseVersion(HttpUpgradeParser.java:164) at org.xnio.http.HttpUpgradeParser.parse(HttpUpgradeParser.java:55) at org.xnio.http.HttpUpgrade$HttpUpgradeState$UpgradeResultListener.handleEvent(HttpUpgrade.java:419) at org.xnio.http.HttpUpgrade$HttpUpgradeState.flushUpgradeChannel(HttpUpgrade.java:369) at org.xnio.http.HttpUpgrade$HttpUpgradeState.access$900(HttpUpgrade.java:165) ... at org.jboss.ejb.protocol.remote.RemotingEJBDiscoveryProvider.getConnectedIdentityUsingClusterEffective(RemotingEJBDiscoveryProvider.java:311) [jboss-ejb-client-4.0.10.Final-redhat-1.jar:4.0.10.Final-redhat-1] at org.jboss.ejb.protocol.remote.RemotingEJBDiscoveryProvider$DiscoveryAttempt.lambda$connectAndDiscover$0(RemotingEJBDiscoveryProvider.java:384) [jboss-ejb-client-4.0.10.Final-redhat-1.jar:4.0.10.Final-redhat-1] at java.security.AccessController.doPrivileged(Native Method) [rt.jar:1.8.0_144] at org.jboss.ejb.protocol.remote.RemotingEJBDiscoveryProvider$DiscoveryAttempt.connectAndDiscover(RemotingEJBDiscoveryProvider.java:384) [jboss-ejb-client-4.0.10.Final-redhat-1.jar:4.0.10.Final-redhat-1] at org.jboss.ejb.protocol.remote.RemotingEJBDiscoveryProvider.discover(RemotingEJBDiscoveryProvider.java:209) [jboss-ejb-client-4.0.10.Final-redhat-1.jar:4.0.10.Final-redhat-1] at org.jboss.ejb.protocol.remote.RemoteEJBDiscoveryConfigurator.lambda$configure$0(RemoteEJBDiscoveryConfigurator.java:42) [jboss-ejb-client-4.0.10.Final-redhat-1.jar:4.0.10.Final-redhat-1] at org.wildfly.discovery.impl.AggregateDiscoveryProvider.discover(AggregateDiscoveryProvider.java:58) at org.wildfly.discovery.Discovery.discover(Discovery.java:100)
Resolution
Set both sides of the connection to use the older remoting protocol. If the server, client running on a server, or client is running with JBoss EAP 6 or earlier, the step can be skipped because it will default to the older protocol.
-
Configure server-side the
ejb-serverapplication<subsystem xmlns="urn:jboss:domain:remoting:3.0"> <endpoint/> <!-- this is the default http-remoting connector configuration --> <http-connector name="http-remoting-connector" connector-ref="default" security-realm="ApplicationRealm"/> <!-- this is the native remoting connector, note that you need to add a socket-binding also! --> <connector name="remoting-connector" socket-binding="remoting" security-realm="ApplicationRealm"/> </subsystem> <socket-binding-group ...> ... <socket-binding name="remoting" port="4447" /> ... </socket-binding-group> -
Configure the
ejb-clientapplication running in on a JBoss EAP 7 serverAside from general configuration for the client like
jboss-ejb-client.xmlwith the references to the outbound connection the configuration profile must configure it and use the correct port and protocol.-
Add 'protocol' (
protocol="remote") will change the outbound protocol and the socket-binding point to the server socket forremoting(4447) instead ofhttp(8080).<subsystem xmlns="urn:jboss:domain:remoting:3.0"> ... <outbound-connections> <remote-outbound-connection name="remote-ejb-connection" outbound-socket-binding-ref="remote-socket-ejb" security-realm="ApplicationRealm" protocol="remote"> <properties ></properties> </remote-outbound-connection> </outbound-connections> </subsystem> ... <socket-binding-group ...> ... <outbound-socket-binding name="remote-socket-ejb"> <remote-destination host="remotHost" port="4447"/> </outbound-socket-binding> -
Put the following in
WEB-INF/jboss-ejb-client.xmlfor a WAR orMETA-INF/jboss-ejb-client.xmlif the deployment is not a WAR.outbound-connection-ref(outbound-connection-ref="remote-ejb-connection") must be corresponding to the name of<remote-outbound-connection>you defined insideremotingsubsystem in the previous step.<jboss-ejb-client xmlns="urn:jboss:ejb-client:1.0"> <client-context> <ejb-receivers> <remoting-ejb-receiver outbound-connection-ref="remote-ejb-connection"/> </ejb-receivers> </client-context> </jboss-ejb-client>
-
-
Standalone client configuration
The properties must change the protocol for each server as followed as the default is
http-remoting:remote.connections=one remote.connection.one.host=localhost remote.connection.one.port = 4447 remote.connection.one.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false remote.connection.one.protocol=remote
Root Cause
The default for EJB connections for JBoss EAP 7 is the http port which use http2 / http-upgrade to choose the right protocol. This is to minimize the number of open ports for the server. Clients and servers using code from JBoss EAP 7 will use this never http-remoting protocol by default.
The binary remoting protocol, which defaults to port 4447, can still be configured, but it must be done on both ends of the connection.
Connections between JBoss EAP 7 and JBoss EAP 6 are supported, but there have been some issues in certain patch versions and version combinations. Make sure to run the latest patch version of JBoss EAP 6.4 and JBoss EAP 7.
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.