Web Application Lifecycle Listeners

ServletContainerInitializer

The ServletContainerInitializer is a special case that must be registered with the Service Provider Interface (SPI) loading mechanism. Please see the Javadocs for more details on its usage. That is a topic for a different post.

ServletContextListener

The ServletContextListener has been previously mentioned in another post as noted above. This listener is notified of lifecycle changes, e.g. context initialized and destroyed. This gives the developer the opportunity to perform application setup such as setting a logger, or enabling other listeners. It also provides a clean mechanism to handle application cleanup when an application is shutdown, or disabled.

ServletContextAttributeListener

The ServletContextAttributeListener listens for events that occur when attributes are added, modified, or removed from the ServletContext. This could be used to modify those attributes, or perhaps log them. Interestingly, the order in which the implementations are invoked is not specified.

HttpSessionListener

The HttpSessionListener listens for session creation, and destruction events. I have found this to be one of the most useful classes in a web application. This can be used to set up a persistent data connection while the session is valid, and close the connection when the session expires, or is invalidated.

The listener implementations are invoked in the order of declaration, and destroyed in reverse order. A way to think of this is like the layers of filo dough. If you go from top to bottom, then you must reverse order from bottom to top.

Keep in mind that the HttpSessionAttributeListener behaves like the ServletContextAttributeListener in that the order in which the implementations are invoked is unspecified. This means that you can not rely on a specified ordering to take place across containers. Usually, the ordering is consistent on a container basis, but the contract is explicit that the ordering is undefined.

HttpSessionIdListener

This is a new to Java EE 7. The HttpSessionBindingListener is used to handle when a HttpSession ID changes. This is usually the result of a HttpServletRequest.changeSessionId() command. This was added in Java EE 7 to help solve a security issue called Session Fixation. Typically, you would change the session id after the user successfully authenticates. This can help you with this transition. Otherwise, you need to do a lot of work to make it happen. In this case, it is just great to be able to let the API handle it.

This interface will allow you to modify your application based on the ID change. Please note that the order in which the implementations are invoked is not specified.

ServletRequestListener

The ServletRequestListener is another listener that I use. However its usage is not as frequent as the other aforementioned ones. I usually end up checking the ServletRequest with an instanceof for HttpServletRequest and casting it. This listener will allow you to modify an individual request.

Since it has every request pass through it, you should make sure that there is no excessive overhead in the listener such as database lookups, or excessive logging. Abuse of this listener can result in massive performance issues.

Like the other attribute listeners, this listener does not have a specific order in which they are invoked.

Code Examples

The code for this project was developed using NetBeans 7.4, Apache Maven, Mercurial, and is hosted on Bitbucket. The code in the examples is somewhat contrived, but does demonstrate the functionality of the listeners.I strongly recommend downloading the code, executing it, and looking at the output. It will give you a better picture of how the code works, and also show you some hidden "features" of your application that you may be unaware of.

ServletContextListenerImpl.java

ServletContextAttributeListenerImpl.java

HttpSessionListenerImpl.java

HttpSessionAttributeListenerImpl.java

ServletRequestListenerImpl.java

ServletRequstAttributeListenerImpl.java

Conclusion

Web application lifecycle listeners are essential tools for the web developer. If you are not using them, you should consider them to simplify your web development. Hopefully the explanations and code provided help you along your path to becoming a great developer.

Introduction

This article is not another diatribe to tell you the importance of unit testing. I think we can all agree that it is important. This is about solving an issue that comes up frequently in unit testing. How do I test static methods, and how do you test private methods.

Until PowerMock, most developers were told you can't really test a static method per se. I will show how to do it below.

A common mechanism for testing private methods is to change them to protected. This is not a good solution for a number of reasons. So how do we test them? Again, PowerMock has come to the rescue.
I want solutions. I use Arquillian, but I am not such a zealot that I will chant the mantra that mocking is evil and should not be done. It is a means to an end. That being said, we use Mockito which in my professional experience is the best current mocking framework available. It is easy to setup and use.
However, Mockito has its limitations. Two are mentioned above. The fine developers of PowerMock have come up with an additional framework to use in conjunction with Mockito to get around the limitations.

Solution

Since I am a Apache Maven user, I simply add the relevant frameworks to my pom.xml as shown below:
Once the test frameworks are in place, I can use the PowerMockRunner to help me with my testing. The following are some simple classes to demonstrate how to test. The first is a class to generate UUID values for IDs.

IdentityUtilities.java

Next, I need a class to represent a person. I am interested in testing the private method generateId.

Person.java

PersonTest.java

The @RunWith(PowerMockRunner.class) annotation tells jUnit that we are using an extension to handle testing of this class. This tells jUnit to use this test runner instead of its own test runner.
The @PrepareForTest({IdentityUtilities.class, Person.class}) serves multiple purposes here. The first is to tell PowerMock that we need to do some preparation of the classes to instrument them for our testing. Classes defined using this annotation are typically those that needs to be byte-code manipulated. This includes final classes, classes with final, private, static or native methods that should be mocked and also classes that should be return a mock object upon instantiation. IdentityUtilities.class is our class with a static method, and Person.class contains our private method.

The first test testInitialize() behaves like any other Mockito test with the exception that we mock it using PowerMockito.mockStatic(IdentityUtilities.class) to initialize it. This makes testing static methods as easy as any other Mockito test.

The second test requires a little more explanation. In this case, we spy on the object we are creating. This allows us to instrument it. Then using the "spied" instance we use PowerMockito.when(instance, "generateId").thenReturn("UNIT-1A") to tell the framework that when the private method "generateId" is called, we want to return a specific value. Then we initialize the instance, and check the value is what we expected. Finally, we can optionally check to make sure that the method was actually called by using verifyPrivate(instance).invoke("generateId").

Conclusion

Don't short change yourself, and don't modify your beautifully architected code just to satisfy a testing framework. Find a framework like PowerMock to help you test your code as written instead. You should only change the code because you want to do so, or because you discover flaws in it.

Friday, November 29, 2013

I am trying to put a bunch of my code on my Google Drive to back it up. I have had a couple of bad experiences lately around failed hardware, and needing some code that I could not get to from a remote machine. I copied all of the projects to the Google Drive in the interim. I am not sure if this is a good idea since the builds in the IDE seem cause it some issues, but until I have everything on Bitbucket, I will need to have it on the drive.

Anyway, I was looking for a way to make sure all of the projects were clean so that I could conserve space, save money, and keep the scanning to a more minimal level. So how do you step through each directory and issue commands to clean the projects. Here are my examples:

Maven

Ant

Please note that I set the maxdepth to 1 so that it would not recursively keep digging down directory levels invoking the command. The -type d option is to only examine directories starting from the current directory. The cd{} shell command tells the script to go into the directory that was found and execute the following command.

Monday, November 25, 2013

Have you ever had a developer modify a web.xml file to change session configuration? Have they forgotten to change it back from "developer mode" back to "deployment mode"? I am sure all of you have done something like that at some point in time. I am no exception. This tip of the day comes from that very issue.

The issue here is that we want to control session tracking. In the web.xml file you may have something that looks like:

OK, let me re-phrase that. You were expecting that, but instead you have:
This is a problem. You see we are trying to be more secure around our session and having the JSESSIONID in the URL is not helping much with that. Well, we can perhaps keep our application safe, and frustrate our developer slightly if he doesn't figure out this little bit of magic. We can control the session tracking programmatically in an "obvious" well-known location. We can enlist a ServletContextListener to help us.

The ServletContextListener can help us by listening for when our application is being initialized, and set the session tracking back to COOKIE for us. The implementation is simple, and will help foil the "developer mode-itis" that sometimes infects the code.

ServletContextListenerImpl.java

Note: Even if you didn't have a value set in the web.xml file, this would set it to COOKIE.

Friday, November 22, 2013

Introduction

We had a technical discussion about updating an application on the fly in Java EE. There were a couple of issues that we were trying to resolve. One was a simple way to add functionality to a web application while deployed, and update the running application. It could be functionality like a new module, or service, or something like, the classic example for the ServiceLoader, codecs.

Additionally, we needed to be able to add the functionality without adding another framework to make it happen. It needed to be something that was available in the existing Java SE/EE APIs. Again, the ServiceLoader seemed to be a possible solution.

I did a Proof of Concept (POC) for using a ServiceLoader to accomplish adding additional services to our application. That worked, but required a restart of the server, or a reload of the application at a minimum. This assumes that the application was NOT auto-deployed. It turns out that worked, but really was only a half-measure. I wanted to see if I could solve the dynamic reloading part, and I did.

Solution

Before we see the code, how does it work in general. We use the ServiceLoader which is part of the Service Provider Interface (SPI) functionality of Java. It is a hidden gem for those who need it, and framework creators can take advantage of this simple, easy to use technology. The ServiceLoader is managed by a Singleton that returns an instance of the ServiceLoader that will return our SPI implementations. In my example, I create an interface that is packaged separately in its own jar and is shared between the deployed web application and the service implementations. The ServiceLoader loads this interface and makes the implementations available. The cool part is that our Singleton class also has some cool NIO and NIO.2 help with the ZipFileSystemProvider to load the implementations from newly added jars. It also has some demo of how to use a URLClassLoader to add our new implementations and update the ServiceLoader.

Log.java

Here is our interface that is common between the web service and the SPI implementations.

LogImpl.java

This simple interface will allow me to demonstrate the power of the SPI. Here is an implementation of the API.

LogService

This class is the magic behind the SPI and allows us to dyanmically reload the new implementations as we add them to the WEB-INF/lib directory.

com.bluelotussoftware.service.spi.Log

The SPI file located in the META-INF/services directory of your jar file. This is one version, but each implementation would have its own. The file name is the same as the interface, and the listings on each line are concrete implementations.

IndexBean.java

This bean has a cool NIO method of handling uploaded files. So I thought I would add it. Combined with PrimeFaces, it is functional and pretty.

Conclusion

If you need to add some additional functionality to a web application, and reload it on the fly, Give the ServiceLoader a try. You might just be impressed.