7

I am coming from this SO however my case is not on Tomcat, but JBoss EAP 6. So suppose I have two web apps app1 and app2 running on JBoss AS 6:

  • app1 on http://localhost:8080/app1
  • app2 on http://localhost:8080/app2

However I want to configure Tomcat so that they run in root context behind separate ports:

  • app1 on http://localhost:8081
  • app2 on http://localhost:8082

How can I make it on JBoss EAP 6? Note this answer doesn't work for me as it targets JBoss 5.

Community
  • 1
  • 1
Gelin Luo
  • 14,035
  • 27
  • 86
  • 139
  • 1
    What about running two JBoss copies starting the second with a port-offset=100 ? – Cirou Apr 08 '14 at 15:00
  • this will add to the memory footprint unnecessarily, and is not our option – Gelin Luo Apr 08 '14 at 19:25
  • Tomcat server.xml is also present in AS6 it's just in a different location. The syntax was not changed between 5 and 6. It was changed in 7 though. – anttix Apr 10 '14 at 19:52
  • Note if all you need to do is indicate to web applications that they are using a secure connection then just add `secure=true` to the JBoss http connector. This will "lie" to the apps and tell them that it's a secure connection and you can still use nginx to proxy the requests. http://docs.jboss.org/jbossweb/7.0.x/config/http.html – anttix Apr 11 '14 at 18:38
  • If apps need access to client information e.g. remote address etc. Then consider using ajp protocol between reverse proxy and Java server. – anttix Apr 11 '14 at 18:39
  • Please be aware JBoss AS 6 and JBoss EAP 6 are two completely different releases and AS / EAP can not be used interchangeably. – Darran L Apr 14 '14 at 07:56

3 Answers3

7

EDIT: These instructions are for JBoss AS6 as requested in the original question. AS7 has different configuration file syntax.

Your problem has two parts:

  1. Make JBoss listen on multiple ports
  2. Dispatch requests to 8081 to app1 and 8082 to app2

Getting JBoss to listen on multiple ports

This one is easy.

Add lines like these to $JBOSS_HOME/server/default/deploy/jbossweb.sar/server.xml

<!-- A HTTP/1.1 Connector on port 8081 -->
<Connector protocol="HTTP/1.1" port="8081" address="${jboss.bind.address}" 
   redirectPort="${jboss.web.https.port}" />

<!-- A HTTP/1.1 Connector on port 8082 -->
<Connector protocol="HTTP/1.1" port="8082" address="${jboss.bind.address}" 
   redirectPort="${jboss.web.https.port}" />

Observe the following messages in the log when server boots up:

11:56:23,639 INFO  [org.apache.coyote.http11.Http11Protocol] Starting Coyote HTTP/1.1 on http-127.0.0.1-8081
11:56:23,640 INFO  [org.apache.coyote.http11.Http11Protocol] Starting Coyote HTTP/1.1 on http-127.0.0.1-8082

Note: If you want to do it "properly" you should use placeholders instead of hardcoded numbers and edit $JBOSS_HOME/server/default/conf/bindingservice.beans/META-INF/bindings-jboss-beans.xml to define them. But, unless you need to manage ports via the management UI, it will be an overkill.

Dispatch requests to port 8081 to app1 and port 8082 to app2

This is much harder. JBoss uses its own Tomcat engine that does not support multiple webapp roots (appBase attribute does not work). Thus it is impossible to configure two different directories for your connectors. It is possible to add virtual hosts and use jboss-web.xml in each app to configure which vhost it responds to, but that means your have to use different names in client URL-s.

You have two options here.

Option 1: JBoss RewriteValve

Add this to Host configuration element (before other valve definitions) in $JBOSS_HOME/server/default/deploy/jbossweb.sar/server.xml

 <Valve className="org.jboss.web.rewrite.RewriteValve" />

Create a file $JBOSS_HOME/server/default/conf/jboss.web/localhost/rewrite.properties with the following contents:

RewriteCond %{SERVER_PORT}  =8081
RewriteRule ^/(.*)$  /app1/$1 [L]

RewriteCond %{SERVER_PORT}  =8082
RewriteRule ^/(.*)$  /app2/$1 [L]

Note: You may need to create the $JBOSS_HOME/server/default/conf/jboss.web/localhost/ directory, it does not exist by default.

Note2: Location of the rewrite.properties depends on the placement of the Valve tag in server.xml. The most intuitive placement is with other Valve elements. However it is valid directly under Engine as well. In this case rewrite.properties file needs to be moved up one directory.

Option 2: Servlet filter in ROOT context

Deploy a servlet filter to $JBOSS_HOME/server/default/deploy/ROOT.war/ that dispatches requests based on incoming port. You can either roll out your own custom filter implementation or use UrlRewriteFilter with a configuration that looks like this:

<rule>
  <condition type="port">8081</condition>
  <from>/(.*)</from>
  <to context="app1">/$1</to>
</rule>

<rule>
  <condition type="port">8082</condition>
  <from>/(.*)</from>
  <to context="app2">/$1</to>
</rule>

See also:

EDIT: Given the complexity of JBoss configuration you may also opt for an Apache based reverse proxy that sits in front of the app server.

Community
  • 1
  • 1
anttix
  • 7,709
  • 1
  • 24
  • 25
  • There is also 3rd option, doing IP based virtual hosts. in this case connectors need to be bound to two different IP addresses and need useIPVHosts="true" From there on everything is the same as with ordinary virtual hosts with exception that you need to add with ip address of the connector as well. – Tomaz Cerar Apr 10 '14 at 22:04
  • There is no `server` folder under my `$JBOSS_HOME` at all. Here are the content in my `$JBOSS_HOME`: `appclient docs jboss-modules.jar standalone bin domain LICENSE.txt version.txt bundles JBossEULA.txt modules welcome-content` – Gelin Luo Apr 11 '14 at 03:04
  • That directory structure looks like it comes from AS7. What exactly did you install? AS 6 or EAP 6? If it is EAP then it's based on JBoss AS 7 not AS 6. https://access.redhat.com/site/articles/112673 I'll leave it up to you to convert the detailed instructions I provided to the new configuration file format. Same ideas, different config file locations and format. – anttix Apr 11 '14 at 07:55
  • Configuration for AS7 is in `standalone/configuration/standalone.xml` – anttix Apr 11 '14 at 08:08
3

JBoss AS7 version of the configuration discussed in the answer for AS6 with multiple http connectors and a rewrite valve.

--- standalone/configuration/standalone.xml.orig    1970-01-01 00:00:00.000000000 -0100
+++ standalone/configuration/standalone.xml 1970-01-01 00:00:00.000000000 -0100
@@ -257,9 +257,17 @@
         </subsystem>
         <subsystem xmlns="urn:jboss:domain:web:1.1" default-virtual-server="default-host" native="false">
             <connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http"/>
+            <connector name="http1" protocol="HTTP/1.1" scheme="http" socket-binding="http1"/>
+            <connector name="http2" protocol="HTTP/1.1" scheme="http" socket-binding="http2"/>
             <virtual-server name="default-host" enable-welcome-root="true">
                 <alias name="localhost"/>
                 <alias name="example.com"/>
+                <rewrite pattern="^/(.*)$" substitution="/app1/$1" flags="L">
+                    <condition test="%{SERVER_PORT}" pattern="=8081" flags=","/>
+                </rewrite>
+                <rewrite pattern="^/(.*)$" substitution="/app2/$1" flags="L">
+                    <condition test="%{SERVER_PORT}" pattern="=8082" flags=","/>
+                </rewrite>
             </virtual-server>
         </subsystem>
         <subsystem xmlns="urn:jboss:domain:webservices:1.1">
@@ -293,6 +301,8 @@
         <socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9443}"/>
         <socket-binding name="ajp" port="8009"/>
         <socket-binding name="http" port="8080"/>
+        <socket-binding name="http1" port="8081"/>
+        <socket-binding name="http2" port="8082"/>
         <socket-binding name="https" port="8443"/>
         <socket-binding name="osgi-http" interface="management" port="8090"/>
         <socket-binding name="remoting" port="4447"/>

See also:

anttix
  • 7,709
  • 1
  • 24
  • 25
  • I've already switch from JBoss EAP to JBoss web, which is literally a tomcat server. I will accept your first answer anyway. I have a concern with this answer however. Since I already have nginx as front end proxy the domain name resolution should be done at nginx, instead of jboss, right? – Gelin Luo Apr 14 '14 at 12:08
  • DNS resolution of client IP-s? AFAIK it's not performed for performance reasons. At least by default log files have client IP-s and not names. Can you share a little bit more details what is the specific problem you need to address. E.g. what does not work with your current JBoss behind nginx setup. – anttix Apr 14 '14 at 16:48
  • @green thanx for accepting the answer. Can I get the bounty as well? – anttix Apr 15 '14 at 21:08
  • absolutely it's yours ;-) – Gelin Luo Apr 15 '14 at 22:34
  • I wish you explained what was going here a bit more. I don't fully understand what this is doing. – Sam Orozco Aug 08 '16 at 21:22
  • @SamOrozco the configuration presented in this answer is functionally identical to the AS6 version that is explained in detail above. – anttix Sep 07 '16 at 00:36
0

Following way worked out for me. Have a look.

First go the server location and copy the default folder with new name. In my scenario will name it, server_uat.

Copy conf, lib, and server folder from default into server_uat folder.

Direct to jboss-service.xml (which is in server_uat)

Uncomment the ServiceBindingManager mbean and change the ServerName to ports-01.

You can even use ports-02 or ports-03. The required configurations are already done by JBoss in the docs/examples/binding-manager.xml file.

Once the change is made after adding ports-01 to mbean code fragment. It should lool like the following.

 <mbean code="org.jboss.services.binding.ServiceBindingManager"
     name="jboss.system:service=ServiceBindingManager">
     <attribute name="ServerName">ports-01</attribute>
     <attribute name="StoreURL">${jboss.home.url}/docs/examples/binding-manager/sample-bindings.xml</attribute>
     <attribute name="StoreFactoryClassName">
       org.jboss.services.binding.XMLServicesStoreFactory
     </attribute>
   </mbean>

Using the command prompt, direct to the bin folder and run the server_uat server instance with the following command.

Windows:

run.bat -c server_uat

Linux:

./run.sh -c server_uat

FYI:

ports-01 refers 8180

ports-02 refers 8280

ports-03 refers 8380
Du-Lacoste
  • 11,530
  • 2
  • 71
  • 51