Tag Archive | java ee

Analysing the performance degradation/improvements of a Java EE application with interceptors

When you are developing a Java EE application with certain performance requirements, you have to verify that these requirements are fulfilled before each release. An Hudson job that nightly executes a bunch of test measurements on some specific hardware platform is what you may think about.

You can check the achieved timings and compare them with the given requirements. If the measured values deviate from the requirements too much, you can either break the build or at least send an email to the team.

But how do you measure the execution time of your code? The very first thought might be to add thousands of insertions of time measuring code into your code base. But this is not only a lot of work, but also has an impact on the performance of your code, as now the time measurements are also executed in production. To get rid of the many insertions you might want to leverage an aspect oriented framework (AOP) that introduces the code for time measurements at compile time. Using this way you have at least two versions of your application: the one with and the one without the additional overhead. To measure performance at some production site still requires a redeployment of your code. And you have to decide which methods you want to observe already at compile time.

Java EE comes therefore with an easy to use alternative: Interceptors. This is were the inversion of control pattern plays out its advantages. As the Application Server invokes your bean methods/web service calls, it is easy for it to intercept these invocations and provide you a way of adding code before and after each invocation.

Using interceptors is then fairly easy. You can either add an annotation to your target method or class that references your interceptor implementation or you can add the interceptor using the deployment descriptor:

@Interceptors(PerformanceInterceptor.class)
public class CustomerService {
...
}

The same information supplied in the deployment descriptor looks like this:

<interceptor-binding>
    <target-name>myapp.CustomerService</target-name>
    <interceptor-class>myapp.PerformanceInterceptor.class</interceptor-class>
</interceptor-binding>

The interceptor itself can be a simple POJO class with a method that is annotated with @AroundInvoke and one argument:

@AroundInvoke
public Object measureExecutionTime(InvocationContext ctx) throws Exception {
	long start = System.currentTimeMillis();
	try {
		return ctx.proceed();
	} finally {
		long time = System.currentTimeMillis() - start;
		Method method = ctx.getMethod();
		RingStorage ringStorage = RingStorageFactory.getRingStorage(method);
		ringStorage.addMeasurement(time);
	}
}

Before the try block and in the finally block we add our code for the time measurement. As can be seen from the code above, we also need some in-memory location where we can store the last measurement values in order to compute for example a mean value and the deviation from the mean value. In this example we have a simple ring storage implementation that overrides old values after some time.

But how to expose these values to the world outside? As many other values of the Application Server are exposed over the JMX interface, we can implement a simple MXBean interface like shown in the following code snippet:

public interface PerformanceResourceMXBean {
    long getMeanValue();
}

public class RingStorage implements PerformanceResourceMXBean {
	private String id;

	public RingStorage(String id) {
		this.id = id;
		registerMBean();
		...
	}
	
	private void registerMBean() {
        try {
            ObjectName objectName = new ObjectName("performance" + id + ":type=" + this.getClass().getName());
            MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
            try {
                platformMBeanServer.unregisterMBean(objectName);
            } catch (Exception e) {
            }
            platformMBeanServer.registerMBean(this, objectName);
        } catch (Exception e) {
            throw new IllegalStateException("Problem during registration:" + e);
        }
    }
	
	@Override
    public long getMeanValue() {
        ...
    }
	...
}

Now we can start the jconsole and query the exposed MXBean for the mean value:

jconsole

Writing a small JMX client application that writes the sampled values for example into a CSV file, enables you to later on process these values and compare them with later measurements. This gives you an overview of the evolution of your application’s performance.

Conclusion: Adding dynamically through the deployment descriptor performance measurement capabilities to an existing Java EE application is with the use of interceptors easy. If you expose the measured values over JMX, you can apply further processing of the values afterwards.

JSON Processing (JSON-P)

JSON (JavaScript Object Notation) is a compact text file format that can be used to store and transfer data. It has become very popular over the years as it is very simple to read and parse. Beyond that each JSON construct should be valid JavaScript and it should be possible to evaluate it using JavaScript’s eval() function. The latter has made it popular in the web developer community as JSON data received from the server can be easily evaluated on the client side.
The popularity of JSON has created the demand to use it also on the server-side. Over the time different Java libraries have been developed that support reading and writing JSON data (e.g. google-gson, flexjson or Jackson). Hence it was only a question of time until JSON processing becomes a part of the Java EE specification.
In the last article I have thrown light on the new concurrency features of Java EE 7. In this article we want to explore the new feature JSON Processing.
After these introductory words it is time to put our hands on some code. The following code shows how to write a very simple JSON file:

JsonObject model = Json.createObjectBuilder()
		.add("firstName", "Martin")
		.add("phoneNumbers", Json.createArrayBuilder()
				.add(Json.createObjectBuilder()
						.add("mobile", "1234 56789"))
				.add(Json.createObjectBuilder()
						.add("home", "2345 67890")))
		.build();
try (JsonWriter jsonWriter = Json.createWriter(new FileWriter(Paths.get(System.getProperty("user.dir"), "target/myData.json").toString()))) {
	jsonWriter.write(model);
} catch (IOException e) {
	LOGGER.severe("Failed to create file: " + e.getMessage());
}

The builder API makes it easy to append the next call to the previous one. I still need to get used to the fact that you have to call createArrayBuilder() or createObjectBuilder() everytime you want to create an array or an object.
When reading a JSON file you have to determine the type you are currently reading by calling getValueType():

try (JsonReader jsonReader = Json.createReader(new FileReader(Paths.get(System.getProperty("user.dir"), "target/myData.json").toString()))) {
	JsonStructure jsonStructure = jsonReader.read();
	JsonValue.ValueType valueType = jsonStructure.getValueType();
	if (valueType == JsonValue.ValueType.OBJECT) {
		JsonObject jsonObject = (JsonObject) jsonStructure;
		JsonValue firstName = jsonObject.get("firstName");
		...

Functionality to map a complete JSON file to an existing structure of Java classes (someting like JAX-B for XML files) is not part of the standard. But instead of that JSON-P offers a complete streaming API for reading huge amount of JSON data:

try (FileWriter writer = new FileWriter(Paths.get(System.getProperty("user.dir"), "target/myStream.json").toString())) {
	JsonGenerator gen = Json.createGenerator(writer);
	gen
	.writeStartObject()
		.write("firstName", "Martin")
		.writeStartArray("phoneNumbers")
			.writeStartObject()
				.write("mobile", 123456789)
				.write("home", "2345 67890")
			.writeEnd()
		.writeEnd()
	.writeEnd();
	gen.close();
} catch (IOException e) {
	LOGGER.severe("Failed to write to file: " + e.getMessage());
}

The code for the streaming API reads very similar to the normal API. The main difference is that you have to mark the end of an array or object with writeEnd().
Reading a JSON file looks very similar to the [Streaming API for XML (StAX)](http://stax.codehaus.org/Home):

try (FileReader fileReader = new FileReader(Paths.get(System.getProperty("user.dir"), "target/myStream.json").toString())) {
	JsonParser parser = Json.createParser(fileReader);
	while (parser.hasNext()) {
		JsonParser.Event event = parser.next();
		switch (event) {
			case START_OBJECT:
				LOGGER.info("{");
				break;
			case END_OBJECT:
				LOGGER.info("}");
				break;
...

Having just said that the above code looks very similar to StAX code, let’s try to compare both implementations by the means of file size and runtime. The following diagram shows the average execution times for writing and reading a JSON/XML file with 100.000 entries.
comparison_diagram
One entry consists of a simple object with a name and an array of two telephone numbers:

{"firstName":"Martin","phoneNumbers":[{"mobile":123456789,"home":"2345 67890"}]}

This is how it looks in XML:

<firstName>Martin</firstName><phoneNumbers><mobile>123456789</mobile><home>234567890</home></phoneNumbers>

It is surprising that the StAX implementation is this much slower when writing big files. When we take a closer look at the file size, we see that the XML file is about 1.31 times bigger than the JSON file, although it contains the same data.

Conclusion: JSON-P provides a standardized API for JSON processing together with a StAX like streaming API. Although it still lacks a binding to a Java class structure, it performs even better than the StAX implementation by a more compact file size.

Source code can be found on my github repository.

PS: The implementations used in the comparison are listed below:

	<dependency>
		<groupId>org.glassfish</groupId>
		<artifactId>javax.json</artifactId>
		<version>1.0</version>
	</dependency>
	<dependency>
		<groupId>stax</groupId>
		<artifactId>stax</artifactId>
		<version>1.2.0</version>
	</dependency>

Securing a JSF application with Java EE security and JBoss AS 7.x

A common requirement for enterprise applications is to have all JSF pages protected behind a login page. Sometimes you even want to have protected areas inside the application that are only accessible by users that own a specific role. The Java EE standards come with all the means you need to implement a web application that is protected by some security constraints. In this blog post we want to develop a simple application that demonstrates the usage of these means and shows how you can build a complete JSF application for two different roles. As the solution might look straight forward at first glance, there are a few pitfalls one has to pay attention to.

The first point we have to care about, is the folder layout of our application. We have three different kinds of pages:

  • The login page and the error page for the login should be accessible by all users.
  • We have a home page that should only be accessible for authenticated users.
  • We have a protected page that should only be visible for users of the role protected-role.

These three types of pages are therefore put into three different folders: the root folder src/main/webapp, the folder src/main/webapp/pages and the protected page resides in src/main/webapp/pages/protected:

security-web-ide

The web.xml file is the place to define which roles we want to use and how to map the accessibility of some URL pattern to these roles:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>pages</web-resource-name>
        <url-pattern>/pages/*</url-pattern>
        <http-method>PUT</http-method>
        <http-method>DELETE</http-method>
        <http-method>GET</http-method>
        <http-method>POST</http-method>
    </web-resource-collection>
    <auth-constraint>
        <role-name>security-role</role-name>
        <role-name>protected-role</role-name>
    </auth-constraint>
</security-constraint>
<security-constraint>
    <web-resource-collection>
        <web-resource-name>protected</web-resource-name>
        <url-pattern>/pages/protected/*</url-pattern>
        <http-method>PUT</http-method>
        <http-method>DELETE</http-method>
        <http-method>GET</http-method>
        <http-method>POST</http-method>
    </web-resource-collection>
    <auth-constraint>
        <role-name>protected-role</role-name>
    </auth-constraint>
</security-constraint>

<security-role>
    <role-name>security-role</role-name>
</security-role>
<security-role>
    <role-name>protected-role</role-name>
</security-role>

As you can see we define two roles: security-role and protected-role. URLs matching the pattern /pages/* are only accessible by users that own the roles security-role and protected-role, whereas the pages under /pages/protected/* are restricted to users with the role protected-role.

Another point you may stumble upon is the welcome page. At first guess you would want to the specify the login page as welcome page. But this does not work, as the login module of the servlet container automatically redirects all unauthorized accesses to the login page. Therefore we specify the home page of our application as welcome page. This is already a protected page, but the user will get redirected to the login page automatically when he calls its URL directly.

<welcome-file-list>
    <welcome-file>pages/home.xhtml</welcome-file>
</welcome-file-list>

Now we are nearly done with the web.xml page. All we to do is to define the authentication method as well as the login page and the error page, which is shown in case the user enters invalid credentials. One has to page attention that both pages don’t include protected URLs (e.g. CSS or JavaScript files), otherwise even the access to these two pages is forbidden and the user gets an Application Server specific error page to see.

<login-config>
    <auth-method>FORM</auth-method>
    <form-login-config>
        <form-login-page>/login.xhtml</form-login-page>
        <form-error-page>/error.xhtml</form-error-page>
    </form-login-config>
</login-config>

As we are going to deploy the application to the JBoss Application Server, we provide a file named jboss-web.xml that connects our application to a security-domain:

<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
    <security-domain>java:/jaas/other</security-domain>
</jboss-web>

The “other” security-domain is configured inside the standalone.xml. The default configuration requires that the user passes the “RealmUsersRoles” login module, which gets its user and role definitions from the two files application-users.properties and application-roles.properties inside the configuration folder. You can use the provided add-user script to add a new user to this realm:

What type of user do you wish to add?
 a) Management User (mgmt-users.properties)
 b) Application User (application-users.properties)
(a): b

Enter the details of the new user to add.
Realm (ApplicationRealm) :
Username : bart
Password :
Re-enter Password :
What roles do you want this user to belong to? (Please enter a comma separated list, or leave blank for none) : security-role,protected-role
About to add user 'bart' for realm 'ApplicationRealm'
Is this correct yes/no? yes

Here it is important to choose the correct realm (ApplicationRealm), as this realm is configured by default in the standalone.xml for the “other” login module. This is also the place where you provide the roles the user possesses as a comma separated list.

<form method="POST" action="j_security_check" id="">
	<h:panelGrid id="panel" columns="2" border="1" cellpadding="4" cellspacing="4">
		<h:outputLabel for="j_username" value="Username:" />
		<input type="text" name="j_username"/>
		<h:outputLabel for="j_password" value="Password:" />
		<input type="password" name="j_password"/>
		<h:panelGroup>
			<input type="submit" value="Login"/>
		</h:panelGroup>
	</h:panelGrid>
</form>

The next step is to implement a simple login form that submits its data to the login module. Note the ids of the input fields as well as the action of the form. This way the form is posted to the login module, which extracts the entered username and password from the request. JSF developers may wonder why we use a standard HTML form instead of the element. The reason for this is that the JSF form elements spans its own namespace and therefore the ids of the input fields are prefixed with the id of the form (and this form id cannot be empty).

If the user has passed the login form, we present him a home page. But the link to the protected page should only be accessible for users that own the role protected-role. This can be accomplished by the following rendered condition:

<h:link value="Protected page" outcome="protected/protected" rendered="#{facesContext.externalContext.isUserInRole('protected-role')}"/>

Last but not least we need the logout functionality. For this case we implement a simple backing bean like the following one that invalidates the user’s session and redirects him back to the login page:

@Named(value = "login")
public class Login {

    public String logout() {
        FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
        return "/login";
    }
}

As usual the complete source code can be found on github.