ThreadLocal usage

The ThreadLocal is very helpful to keep some information available from anywhere in the application but it is very important to release it when the process ends, otherwise, the resource will never be free and can cause a memory leak.

Here is an example of using TheadLocal to store data in a web application. I define a filter to setup the content of the ThreadLocal and I use it later in a servlet.

First of all, I create a class to store the ThreadLocal:

package net.classnotfound.threadlocal.handler;

public class ThreadLocalHandler {
    private static ThreadLocal myThreadLocal = new ThreadLocal<>();
    
    public static void setData(final String value) {
        myThreadLocal.set(value);
    }
    
    public static String getValue() {
        return myThreadLocal.get();
    }

    public static void remove() {
        myThreadLocal.remove();
    }
}

Now, the filter which is responsible of initialization of the ThreadLocal content:

package net.classnotfound.threadlocal.filter;

import java.io.IOException;
[...]

@WebFilter(urlPatterns = "*")
public class ThreadLocalFilter implements Filter {

    @Override
    public void init(final FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
        long time = new Date().getTime();
        ThreadLocalHandler.setData("this is the value: "+time);
        chain.doFilter(request, response);
        ThreadLocalHandler.remove();

    }

    @Override
    public void destroy() {
        ThreadLocalHandler.remove();
    }
} 

Note that the Threadlocal is initialized before calling the next filter (via the filterChain) and released after.

Now, when I want to use the value, I just need to do:

String value = ThreadLocalHandler.getValue();

My Eclipse shortcuts

Here is a list of my favorite shortcuts I use with Eclipse:
[Ctrl]+[D]: Delete row
[Ctrl]+[F]: Search in file
[Ctrl]+[H]: Search->search…
[Ctrl]+[O]: Navigation->Quick outline
[Ctrl]+[Q]: Last edit location
[Ctrl]+[S]: save the current tab
[Ctrl]+[T]: Navigation->Quick type hierarchy

[Alt]+[left/right]: Back/next to tab
[Alt]+[up/down]: Move row

[Ctrl]+[Shift]+[C]: Comment selection/uncomment commented selection
[Ctrl]+[Shift]+[G]: Search->references->workspace
[Ctrl]+[Shift]+[R]: Navigation->Open resource
[Ctrl]+[Shift]+[S]: save all tabs
[Ctrl]+[Shift]+[T]: Navigation->Open type
[Ctrl]+[Shift]+[Y]: Lowercase selection
[Ctrl]+[Shift]+[X]: Uppercase selection

[Alt]+[Shift]+[L]: Refactor->extract local variable…
[Alt]+[Shift]+[M]: Refactor->extract method…
[Alt]+[Shift]+[R]: Rename an element (variable/class/package, etc…)
[Alt]+[Shift]+[S]: Source
[Alt]+[Shift]+[T]: Refactor
[Alt]+[Shift]+[Z]: Source->surround with

[F5]: Step into (debug)
[F6]: Step over (debug)
[F7]: Step return (debug)
[F8]: Resume (debug)

I omitted the common undo, copy/paste and so on 😉

Display Maven release number in JSF page

In the web projects, it is often useful to see quickly the version of the deployed application. A simple solution is to get it from Maven and display it in our page, in footer or a “about” page.
The main idea is to use a property file as a JSF resource as we can use, for example, when we have a i18n requirement.
For that, I put a property file version.properties with content in the resource directory:

version=${version}
revision=${buildNumber}

The version is the version defined in our project pom and it is automatically provided by Maven.
The revision is the revision number of the last build provided by SVN, to get it, I will need another Maven plugins.

Now, I need to tell to JSF to use this file as resource file, I do it in my faces-config.xml:

<application>
	<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
	<resource-bundle>
	   <base-name>version</base-name>
	   <var>vers</var>
	</resource-bundle>
</application>

And to display it in our JSF pages, I add:

<body>
   [...]
	<div>classNotFound.net ©2014 -
		v#{vers.version} - #{vers.revision}</div>
</body>

If I try to access to this page, I will not see the version/revision, to do that, I have to ask Maven to filter the properties files and replace the variables.
In my pom.xml, I add:

<build>
	<resources>
		<resource>
			<directory>src/main/resources</directory>
			<filtering>true</filtering>
			<includes>
				<include>**/*</include>
			</includes>
		</resource>
	</resources>
</build>

To have the build number, I have to use 3 Maven plugins:

<pluginManagement>
        <plugins>
            <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>buildnumber-maven-plugin</artifactId>
            <executions>
                <execution>
                    <phase>validate</phase>
                    <goals>
                        <goal>create</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <doCheck>false</doCheck>
                <doUpdate>false</doUpdate>
                <providerImplementations>
                    <svn>javasvn</svn>
                </providerImplementations>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>com.google.code.maven-scm-provider-svnjava</groupId>
                    <artifactId>maven-scm-provider-svnjava</artifactId>
                    <version>2.0.2</version>
                </dependency>
                <dependency>
                    <groupId>org.tmatesoft.svnkit</groupId>
                    <artifactId>svnkit</artifactId>
                    <version>1.7.5-v1</version>
                </dependency>
            </dependencies>
        </plugin>
        </plugins>
    </pluginManagement>
  </build>
  
    <scm>
        <connection>scm:svn:https://forge.classnotfound.net/svn/version/trunk/project/project-web</connection>
        <developerConnection>scm:svn:https://forge.classnotfound.net/svn/project/trunk/project/project-web</developerConnection>
        <url>https://forge.classnotfound.net/svn/project/trunk/project/project-web</url>
    </scm>

Now, it works.