Java

Integer Cache in Java

There is an integer caching introduced in java which is similar to String constant pool. this inetgere cache by default cache all the numbers from -128 to 127. That means, if you try to use any number between -128 to 127, it will be fetched from cache and you will see the same integer instance. Having said that, here is the small program to demonstarate the same and observer the out put of this program after 127.

Apart from this we can even increase this limit by using, –XXAutoBoxCacheMax=1024. But this will also consume equal amount of memory though you use these numbers or not.

/**
* @author prabhu kvn
*
*/
public class IntegerCacheDemoInHotSpot {</code>

/**
*
*/
public IntegerCacheDemoInHotSpot() {
}

/**
* @param args
*/
public static void main(String[] args) {
System.out.println("Integer Testing");
for (int i = 0; i &lt; 255; i++) {
Integer firstInt = i;
Integer secondInt = i;
System.out.println(firstInt + &quot; == &quot; + secondInt + &quot; : &quot; + (firstInt == secondInt));

}

}

}

Out Put:

Integer Testing
0 == 0 : true
1 == 1 : true
2 == 2 : true
3 == 3 : true
4 == 4 : true
5 == 5 : true
6 == 6 : true
7 == 7 : true
8 == 8 : true
9 == 9 : true
10 == 10 : true
11 == 11 : true
12 == 12 : true
13 == 13 : true
14 == 14 : true
15 == 15 : true
16 == 16 : true
17 == 17 : true
18 == 18 : true
19 == 19 : true
20 == 20 : true
21 == 21 : true
22 == 22 : true
23 == 23 : true
24 == 24 : true
25 == 25 : true
26 == 26 : true
27 == 27 : true
28 == 28 : true
29 == 29 : true
30 == 30 : true
31 == 31 : true
32 == 32 : true
33 == 33 : true
34 == 34 : true
35 == 35 : true
36 == 36 : true
37 == 37 : true
38 == 38 : true
39 == 39 : true
40 == 40 : true
41 == 41 : true
42 == 42 : true
43 == 43 : true
44 == 44 : true
45 == 45 : true
46 == 46 : true
47 == 47 : true
48 == 48 : true
49 == 49 : true
50 == 50 : true
51 == 51 : true
52 == 52 : true
53 == 53 : true
54 == 54 : true
55 == 55 : true
56 == 56 : true
57 == 57 : true
58 == 58 : true
59 == 59 : true
60 == 60 : true
61 == 61 : true
62 == 62 : true
63 == 63 : true
64 == 64 : true
65 == 65 : true
66 == 66 : true
67 == 67 : true
68 == 68 : true
69 == 69 : true
70 == 70 : true
71 == 71 : true
72 == 72 : true
73 == 73 : true
74 == 74 : true
75 == 75 : true
76 == 76 : true
77 == 77 : true
78 == 78 : true
79 == 79 : true
80 == 80 : true
81 == 81 : true
82 == 82 : true
83 == 83 : true
84 == 84 : true
85 == 85 : true
86 == 86 : true
87 == 87 : true
88 == 88 : true
89 == 89 : true
90 == 90 : true
91 == 91 : true
92 == 92 : true
93 == 93 : true
94 == 94 : true
95 == 95 : true
96 == 96 : true
97 == 97 : true
98 == 98 : true
99 == 99 : true
100 == 100 : true
101 == 101 : true
102 == 102 : true
103 == 103 : true
104 == 104 : true
105 == 105 : true
106 == 106 : true
107 == 107 : true
108 == 108 : true
109 == 109 : true
110 == 110 : true
111 == 111 : true
112 == 112 : true
113 == 113 : true
114 == 114 : true
115 == 115 : true
116 == 116 : true
117 == 117 : true
118 == 118 : true
119 == 119 : true
120 == 120 : true
121 == 121 : true
122 == 122 : true
123 == 123 : true
124 == 124 : true
125 == 125 : true
126 == 126 : true
127 == 127 : true
128 == 128 : false
129 == 129 : false
130 == 130 : false
131 == 131 : false
132 == 132 : false
133 == 133 : false
134 == 134 : false
135 == 135 : false
136 == 136 : false
137 == 137 : false
138 == 138 : false
139 == 139 : false
140 == 140 : false
141 == 141 : false
142 == 142 : false
143 == 143 : false
144 == 144 : false
145 == 145 : false
146 == 146 : false
147 == 147 : false
148 == 148 : false
149 == 149 : false
150 == 150 : false
151 == 151 : false
152 == 152 : false
153 == 153 : false
154 == 154 : false
155 == 155 : false
156 == 156 : false
157 == 157 : false
158 == 158 : false
159 == 159 : false
160 == 160 : false
161 == 161 : false
162 == 162 : false
163 == 163 : false
164 == 164 : false
165 == 165 : false
166 == 166 : false
167 == 167 : false
168 == 168 : false
169 == 169 : false
170 == 170 : false
171 == 171 : false
172 == 172 : false
173 == 173 : false
174 == 174 : false
175 == 175 : false
176 == 176 : false
177 == 177 : false
178 == 178 : false
179 == 179 : false
180 == 180 : false
181 == 181 : false
182 == 182 : false
183 == 183 : false
184 == 184 : false
185 == 185 : false
186 == 186 : false
187 == 187 : false
188 == 188 : false
189 == 189 : false
190 == 190 : false
191 == 191 : false
192 == 192 : false
193 == 193 : false
194 == 194 : false
195 == 195 : false
196 == 196 : false
197 == 197 : false
198 == 198 : false
199 == 199 : false
200 == 200 : false
201 == 201 : false
202 == 202 : false
203 == 203 : false
204 == 204 : false
205 == 205 : false
206 == 206 : false
207 == 207 : false
208 == 208 : false
209 == 209 : false
210 == 210 : false
211 == 211 : false
212 == 212 : false
213 == 213 : false
214 == 214 : false
215 == 215 : false
216 == 216 : false
217 == 217 : false
218 == 218 : false
219 == 219 : false
220 == 220 : false
221 == 221 : false
222 == 222 : false
223 == 223 : false
224 == 224 : false
225 == 225 : false
226 == 226 : false
227 == 227 : false
228 == 228 : false
229 == 229 : false
230 == 230 : false
231 == 231 : false
232 == 232 : false
233 == 233 : false
234 == 234 : false
235 == 235 : false
236 == 236 : false
237 == 237 : false
238 == 238 : false
239 == 239 : false
240 == 240 : false
241 == 241 : false
242 == 242 : false
243 == 243 : false
244 == 244 : false
245 == 245 : false
246 == 246 : false
247 == 247 : false
248 == 248 : false
249 == 249 : false
250 == 250 : false
251 == 251 : false
252 == 252 : false
253 == 253 : false
254 == 254 : false

We have similar kind of cache for long values too,check below


Long j= 0L;

for(;j<4000;j++){
Long firstLong=Long.valueOf(j);
Long secondLong=Long.valueOf(j);
System.out.println(firstLong+" == "+secondLong+" : "+(firstLong==secondLong));

}

Java · WebSocket

A Simple WebSocket in Java

WebSocket is  a protocol to send full-duplex messages over a single TCP connection.

Once the connection is established between client and server, the same connection will be used to communicate for multiple times by both client and server.

Here client and server acts as two end points and they will exchange the data over a single connection.

Note: In order to run these programs, one should have web socket enables server like jetty 9.2.X, Firefox 47 and JDK7 and above.

WebSocket Server End point:

Server will just print the received message and send an ACK back.

/**
 *
 */
package com.websocket;

import java.io.IOException;

import javax.enterprise.context.ApplicationScoped;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

/**
 * @author prabhu kvn
 *
 */
@ApplicationScoped
@ServerEndpoint("/server")
public class WebSocketSimpleServer {

	/**
	 *
	 */
	public WebSocketSimpleServer() {
		// TODO Auto-generated constructor stub
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see javax.websocket.Endpoint#onOpen(javax.websocket.Session,
	 * javax.websocket.EndpointConfig)
	 */
	@OnOpen
	public void onOpen(Session session, EndpointConfig ednpointConfig) {
		System.out.println("--- On Open Call ---Session ID---"
				+ session.getId());

	}

	@OnClose
	public void onClose(Session session) {
		System.out.println("--- On Close Call--");
	}

	@OnMessage
	public void onMessage(String message, Session session) {
		try {

			System.out.println("Server Received:" + message);
			session.getBasicRemote().sendText(
					"(-- Server ACK --"+message+")");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

A Client End Point:

This will establish a connection and reuse same connection for sending messages:

/**
 *
 */
package com.websocket;

import java.io.IOException;
import java.net.URI;

import javax.websocket.ClientEndpoint;
import javax.websocket.ContainerProvider;
import javax.websocket.DeploymentException;
import javax.websocket.OnMessage;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;

/**
 * @author prabhu kvn
 *
 */
@ClientEndpoint
public class WSSimpleClient {

	/**
	 *
	 */
	public WSSimpleClient() {
		// TODO Auto-generated constructor stub
	}

	private static Object waitLock = new Object();

	@OnMessage
	public void onMessage(String message) {
		System.out.println("Client Received:" + message);
	}

	public static void main(String[] args) {
		for (int i = 0; i < 1; i++) {
			connectAndSend();
		}
	}

	/**
	 *
	 */
	private static void connectAndSend() {
		WebSocketContainer container = null;//

		Session session = null;

		try {
			long startTime = System.currentTimeMillis();

			container = ContainerProvider.getWebSocketContainer();
			session = container
					.connectToServer(
							WSSimpleClient.class,
							URI.create("ws://localhost:8888/websockethome/server"));
			// send multiple data sets on same connection
			for(int j=0;j<100;j++){
			session.getBasicRemote().sendText("Client text...."+j);
			}
			System.out.println("Total Time:" + (System.currentTimeMillis() - startTime)+" ms");
			wait4TerminateSignal();

		} catch (DeploymentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private static void wait4TerminateSignal()

	{

		synchronized (waitLock)

		{
			try {

				waitLock.wait(100);

			} catch (InterruptedException e) {

			}
		}
	}

}

Play with I and j values in above program to under stand working of websockets.

Scenario 1: i=1 and j=100 , This will establish a connection once and reuse the same connection to send 100 messages.

Scenario 2: i=10 and j=1,  This will try to establish the connection 10 times, but it will get same connection for all the request. Observe the first connection against consecutive connection times.

Maven Pom Entries:

<!-- Java ee dependency -->

			javax
			javaee-api
			7.0

			org.apache.httpcomponents
			httpclient
			4.5.1

		<!-- Jetty Dependencies -->

			jetty
			jetty-plus
			6.0.2

			org.eclipse.jetty
			jetty-annotations
			9.3.8.v20160314

		<!-- Tyrus websoket client support -->

			org.glassfish.tyrus.bundles
			tyrus-standalone-client
			1.12

			org.glassfish.tyrus.bundles
			tyrus-standalone-client-jdk
			1.12

			org.glassfish
			javax.json
			1.0.4

		websockethome

				org.apache.maven.plugins
				maven-compiler-plugin
				2.0.2

					${java.version}
					${java.version}

				org.eclipse.jetty
				jetty-maven-plugin
				9.2.11.v20150529

					10

						/websockethome

						8888

>mvn jetty:run will start the server on 8888

Callback · Functional · Java

Callback Function in Java

                                                  The following program simulates the call back function feature in Java. This program has been written using functional interface and Callable feature in java. This can be understood by reading below code directly.

/**
 * The following program explains the mimicking of callback  function in java. 
 */
package java8pract;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author Prabhu KVN
 *
 */
public class CallBackFunction {

	ExecutorService executorservice = Executors.newFixedThreadPool(2);

	/**
	 * 
	 */
	public CallBackFunction() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		CallBackFunction fun = new CallBackFunction();
		double val = 100;

		// handleResult is the call back function
		fun.findRoot(val, new ResultHandler() {

			@Override
			public void handleResult(double n) {
				// TODO Auto-generated method stub
				System.out.println("Root of " + val + " is " + n);
			}
		});
		System.out.println("Finding root in progress...");

	}

	public void findRoot(double number, ResultHandler handler) {

		RootFinder finder = new RootFinder(number, handler);

		executorservice.submit(finder);
		executorservice.shutdown();

	};

}

@FunctionalInterface
interface ResultHandler {
	public void handleResult(double n);
}

/**
 * A callable function which will execute a login and will call handler to
 * propagate the logic to an handler.
 * 
 * @author prabhu kvn
 *
 */
class RootFinder implements Callable<Double> {
	double number;
	ResultHandler handler;

	public RootFinder(double number, ResultHandler handler) {
		// TODO Auto-generated constructor stub
		this.number = number;
		this.handler = handler;
	}

	@Override
	public Double call() throws Exception {
		// TODO Auto-generated method stub
		double sqrt = Math.sqrt(number);
		handler.handleResult(sqrt);

		return sqrt;
	}
}
Uncategorized

Closure in Java

A closure is an inner function that has access to the outer function even after the scope of outer function.This is a common programming concept in JavaScript, but we can achieve the same thing in java with the advent of JDK8 and functional programming.

here is a small java program which explains the closure concept in java,

/**
 * This program explains the closure in java. This is achieved by using functional programming in JDK 8.
 */
package lambdas;

/**
 * @author prabhu kvn
 *
 */
public class LambdaClosureConcept {

	public LambdaClosureConcept() {
	}

	public static void main(String[] args) {
		LambdaClosureConcept obj = new LambdaClosureConcept();
		obj.execute();
	}

	private void execute() {
		LambdaClosure fn = getFunction();
		System.out.println(fn.changeVal(10));

	}

	/**
	 * The "local" variable which got trapped in closure function.
	 * 
	 * @return
	 */
	private LambdaClosure getFunction() {
		int local = 89;
		LambdaClosure fn = (int i) -> {
			return i * local;
		};

		return fn;

	}

}

// Functional interface
@FunctionalInterface
interface LambdaClosure {

	int changeVal(int i);
}
ATG · Java · RESTFul · Servlet · Swagger

Swagger Documentation for ATG

A point of view – not a solution

The mechanism described in http://prabhukvn.com/2016/02/24/swagger-documentation-for-servlet/ works with any java web application as long as all the project class files reside in WEB-INF/classes. But this is not the case with ATG. ATG will read all class files from atglib, hence

Approach 1: Rewrite the Package scanner class so that it will scan the java packages listed in atglib. This package scanner class will be used by swagger servlet to scan classes for swagger specific annotations.

Approach 2: Use the same class loader in above package scanner component which is used by nucleus in ATG.

Java · RESTFul · Servlet · Swagger

Swagger Documentation for Servlet

                         Swagger is tool to document RESTFul services with some simple annotations. This mechanism can be applied even to servlets.

           Read more about the swagger at Swagger.

This document talks about writing swagger documentation for simple servlet.

Step1. Create a simple maven web-app and add following  dependencies in pom.xml

<dependency>
            <groupId>com.wordnik</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>1.3.11</version>
        </dependency>
        <dependency>
            <groupId>com.wordnik</groupId>
            <artifactId>swagger-servlet_2.10</artifactId>
            <version>1.3.13</version>
            <exclusions>
                <exclusion>
                    <groupId>com.google.guava</groupId>
                    <artifactId>guava</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-servlet</artifactId>
            <version>1.5.7</version>
            <exclusions>
                <exclusion>
                    <groupId>com.google.guava</groupId>
                    <artifactId>guava</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.wordnik</groupId>
            <artifactId>swagger-jersey-jaxrs_2.10</artifactId>
            <version>1.3.13</version>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>19.0</version>
        </dependency>
        <dependency>
            <groupId>com.wordnik</groupId>
            <artifactId>swagger-core_2.10</artifactId>
            <version>1.3.13</version>
            <scope>compile</scope>
        </dependency>

Step 2:  Register required servlets in web.xml for processing swagger annotations… as well as hosting swagger docs

a. swagger annotation scanner

<!– swagger servlet reader –>

    <servlet>
        <servlet-name>DefaultServletReaderConfig</servlet-name>
        <servlet-class>com.wordnik.swagger.servlet.config.DefaultServletReaderConfig</servlet-class>
        <init-param>
            <param-name>swagger.resource.package</param-name>
            <param-value>servlet.kvn</param-value>
        </init-param>
        <init-param>
            <param-name>swagger.api.basepath</param-name>
            <param-value>http://localhost:8180/swaggerservlet</param-value>
        </init-param>
        <init-param>
            <param-name>api.version</param-name>
            <param-value>1.0.0</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

b. swagger servlet for hosting documents

<!– swagger api declaration servlet for accessing swagger docs –>
    <servlet>
        <servlet-name>ApiDeclarationServlet</servlet-name>
        <servlet-class>com.wordnik.swagger.servlet.listing.ApiDeclarationServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ApiDeclarationServlet</servlet-name>
        <url-pattern>/api-docs/*</url-pattern>
    </servlet-mapping>

c. and A simple servlet with swagger documentation

<servlet>
        <servlet-name>MyServlet</servlet-name>
        <display-name>MyServlet</display-name>
        <description></description>
        <servlet-class>servlet.kvn.MyServlet</servlet-class>
    </servlet>

<servlet-mapping>
        <servlet-name>MyServlet</servlet-name>
        <url-pattern>/MyServlet</url-pattern>
    </servlet-mapping>

Step 3: A simple custom servlet with swagger annotations

@Api(value = “/MyServlet”, description = “My Simple Servlet”,produces=”application/json”)
public class MyServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
      
    /**
     * @see HttpServlet#HttpServlet()
     */
    public MyServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    @ApiOperation(
            value = “A get operation”,
            notes = “A Simple get operation”,
            httpMethod = “GET”,nickname=”myservlet”)
         public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        System.out.println(“Do Get Method Called.”);
        response.getWriter().write(“{status:Sucess fully called get method}”);
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        response.getWriter().write(“{status:Sucess fully called post method}”);
    }

}

Step 4: build and deploy the war file on any server and access the swagger documentation at http://localhost:port/api-docs/

Java · RESTFul · Swagger

Swagger Documentation for RESTFul Services

Swagger has come with an easy way to Document and Test RESTFul services with an ease. Swagger has come up with a bunch of Annotations which will be simply used to document and test web services.

Here, I described how to document rest services with Swagger in simple steps.

For mode details on swagger, please visit Swagger.

Visit Swagger Annotations for complete understanding of various annotations.

What we used,

  1. JDK 6 or Above
  2. Rest Services using Jersey 1.19
  3. Maven for dependency management.
  4. Jboss 6.1 eap. we can use any server.
  5. Eclipse Luna, an optional. can be any latest version.

Step1 :

Create java web project (dynamic web project in eclipse)  Or use any webapp archives in maven.

Step2

Go to web.xml to define jersey and swagger servlets,

<!-- Jersey Servlt -->
  <servlet>
    <servlet-name>rest</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>jersey.config.server.provider.packages</param-name>
      <param-value>     
             io.swagger.jaxrs.json,io.swagger.jaxrs.listing,com.wordnik.swagger.jersey.listing,jersey.swagger.restswagger
        </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

And Swagger Servlet

<!--  Swagger Servlet -->
<servlet>
<servlet-name>Jersey2Config</servlet-name>
<servlet-class>io.swagger.jaxrs.config.DefaultJaxrsConfig</servlet-class>
<init-param>
<param-name>api.version</param-name>
<param-value>1.0.0</param-value>
</init-param>
<init-param>
<param-name>swagger.api.basepath</param-name>
<param-value>http://localhost:8180/RestSwagger/rest</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>

Step 3.

Create a RestFul services according to Jersey notations,

@Path("/company")
@Api(value="/company")
@Produces({"application/json"})
public class MyResource {

/**
* An In Memory Map to hold employee data
*/
public static Map<String, User> employeeList = new HashMap<String, User>();

/** Method processing HTTP GET requests, producing "application/json" MIME media
* type.
* @return String that will be send back as a response of type "application/json".
*/
@GET
@Path("/")
@Produces("application/json")
public String getIt() {

Gson gson = new Gson();
User user = new User();
user.setEmail("prabhukvn@gmail.com");
user.setName("prabhu");
employeeList.put("prabhu", user);
return gson.toJson(user);
}

 

Step 4.

Use Swagger annotations like @Api, @ApiOperation as described above

Step 5.

Copy the “dist” folder from swagger-UI into webapps

step 6.

Change the swagger.jsson url in index.html which is residing in “dist” folder

<script type="text/javascript">
$(function () {
var url = window.location.search.match(/url=([^&]+)/);
if (url && url.length > 1) {
url = decodeURIComponent(url[1]);
} else {
url = "http://localhost:8180/RestSwagger/rest/swagger.json";
} …

Step 7.

Deploy the code in a server. This code tested on jbosseap6.1 development version.

Step 8.Access the swagger UI with following link

http://localhost:8180/RestSwagger/dist/index.html

Here, how it will look like in swagger

 

Rest-swaggerUI

 

 

 

 

 

Rest-swaggerUI2

 

 

Download Reference Code

https://drive.google.com/open?id=0B42U3eIWbBK6UEtqUE9xZWd4eTA

Check the Running Site with above code

http://jboss7thoughts-mias.rhcloud.com/RestSwagger/dist/index.html

Java

Java Rarely used Operators

“&=” and “|=” are some of the less frequently used operators in java. These operators works same as “+=” and “-=” operators which we use regularly.

“&=” example

public static void main(String[] args) {
    boolean a = true;
    boolean b = false;
    boolean r1 = a&=b;
    boolean r2 = (a&b);
    // so a&=b –> a= (a&b)
    System.out.println(r1);
    System.out.println(r2);
}

similarly != works on the same way. Similarly we have “^=” also (XOR).

result:

false

false

ATG

ATG Nucleus loading multiple times (3 times approximately)

ATG Version: 11.1

Jboss: Jboss 6.1 EAP

In some scenarios, ATG will load nucleus application multiple time due some configuration problem in generated ear.

Add following lines in application.xml, which is in ATG generated ear file.

<initialize-in-order>true</initialize-in-order>

Just before the </application>

This will solve repeated nucleus initialization

And also note that, without the above settings ATG ear deployment will throw following errors,

21:55:11,407 ERROR [stderr] (ServerService Thread Pool — 59) java.lang.NoSuchFieldException: policy

Uncategorized

Auto Deploy Or Hot Deploy of JSP’s in JBOSS EAP 6.1

Jboss EAP 6.1 is not by default detect or deploy latest changes to JSP pages at runtime.

We need to place following settings in order to enable auto deployment or hot deployment of JSP pages.

Add following settings in standalone/configurations/standalone.xml file or In your server specific config file.

    <subsystem xmlns="urn:jboss:domain:web:1.4" default-virtual-server="default-host" native="false">
            <connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http"/>
            <configuration>
                <jsp-configuration development="true"/>
            </configuration>
            <virtual-server name="default-host" enable-welcome-root="true">
                <alias name="localhost"/>
                <alias name="example.com"/>
            </virtual-server>
        </subsystem>