Archive

Archive for March, 2009

Do not use taglibs, use tagfiles!

March 22nd, 2009 Nicolas Frankel No comments

Taglibs are wonderful components available since J2EE 1.3. They enable you, as developer:

  • to refrain from using too much scriptlets (free-form Java code) in your Java Server Pages,
  • to have a library of reusable components that can be distributed to all your projects.

Both are very important in the enterprise as of now. For example, as an architect, you can disallow the use of scriptlets altogether and then provide taglibs to restrain what can be done on the page. Such policies are not uncommon and can be enforced by quality code checkers. It prevents fresh-out-of-school developers to call JDBC code in the JSP, thus destroying your precicous Model View Controller model.

Taglibs have a big drawback, though: they are standard Java classes that inherit the right class (javax.servlet.jsp.tagext.Tag or javax.servlet.jsp.tagext.SimpleTag). Thus, their content must be written to the JspWriter. In that, they are very similar to Servlets: they cannot be designed by a graphist and you must provide an servlet engine to see their output. Servlet have JSP to serve as view, taglibs have tagfiles!

What is a tagfile, anyway? Just put a file with a *.tag extension in your /WEB-INF/tags directory, and bingo, you have a tagfile. In order to test the creation of tagfiles, create a hello.tag with the following content: “Hello world”. Then create a JSP and paste the following snippet:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="tag" tagdir="/WEB-INF/tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Tag files example</title>
</head>
<body>
<tag:hello />
</body>
</html>

You can already guess the output. The little magic comes in referencing the tagfile. We do not use the uri attribute of the taglib directive but the tagdir attribute that tells the application server where we stored our tagfiles. To call the tagfile, use the prefix as usual and then the name of the file. No need to use a TLD. Easy, isn’t it?

To easy… In fact, this use of tagfiles does not enable reuse. It is done in the context of a single web application and has not many advantages over use of JSP includes. To package tagfiles for reuse, you’ll have to move the files from /WEB-INF/tags to /META-INF/tags and create a full fledged TLD under /META-INF:

<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd ">
    <tlib-version>1.0</tlib-version>
    <short-name>tf</short-name>
    <uri>http://blog.frankel.ch/examples/tagfiles</uri>
    <!-- don't use tagclass -->
    <tag-file>
        <name>hello</name>
        <path>/META-INF/tags/hello.tag</path>
    </tag-file>
</taglib>

Now use the taglib in a JSP (don’t forget to use the uri attribute now). The result should be the same, but now you have a reusable component per-se. Of course, writing a string in the output is not very useful. Like taglibs, tagfiles can accept variables. It is very easy to do this, because many attributes which are found under the TLD with taglibs are found in the tagfile itself. Let’s write a tagfile that write today’s date with the format given by the developer:

<%@ tag body-content="empty" %>
<%@ attribute name="format" required="true" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<jsp:useBean id="date" class="java.util.Date" />
<fmt:formatDate value="${date}" pattern="${format}" />

Notice the attribute syntax.
Eclipse project for these examples can be found here.
If you wih to go further in your understanding of Tag Files:

Categories: JEE Tags: , , ,

Simplest Java decoupling without 3rd party frameworks

March 21st, 2009 Nicolas Frankel 1 comment

“[...] coupling (or dependency) is the degree to which each program module relies on each one of the other modules.”

From Wikipedia

In object-oriented programming, removing dependencies is done by using interface. Thus, if class A is dependent on class B, we introduce interface C, which is implemented by B. Now A depends on C  (see below).

This first step in decoupling is called programming by interface. Read more…

Decrease your pages load time

March 17th, 2009 Nicolas Frankel No comments

1. Generalities

Web applications have several advantages over traditional client server applications: since business code comes from a unique server (forget clustering here), they are always up-to-date. Moreover, deployment of a new version is only a matter of minutes.

They have one big drawback, though. Since HTML code is sent through the network, responsiveness is generally much less than that of traditional applications.

The responsiveness of an interactive system describes how quickly it responds to user input (i.e. the rate of communication with the system).

From Wikipedia

Ajax overcomes some of this in proposing to load the entire page at start and the modifiying pertinent chuncks of it. Yet, it is only part of the solution, since initial loading of the page will be the hardest on the user. Users don’t like waiting for a page to load. As a user, you don’t like waiting. As a good rule of thumb, you must make every effort to achieve a initial page load time of less than 1 second (you can find additional informations on load time steps in this very interesting article). This load time doesn’t cover the time for the entire page and style sheets and scripts to finish downloading, but only the time for the user to have pertinent informations displayed and to begin interacting with the screen. This is of cours very context dependent but conclusion is: the less time your page takes to display, the better it is.

2. Decreasing load time

Yahoo provides 34 best practices to speed up your site. If you use Mozilla Firefox, and you already use the fantastic FireBug plug-in, you should add the YSlow plugin to it (if not, download FireBug beforehand). YSlow checks the web page you’re browsing with Firefox for 13 of these rules. The important rules for the matter at hand are:

  1. Make JS and CSS external,
  2. Make fewer HTTP requests,
  3. Minify JS (and CSS).

First point is pretty self-explanatory. Instead of putting JS code and CSS information in your HTML, you put both in external files and reference these from your page: no big deal, everybody does it nowadays. The second point is contrary to the first: for each file you have, you must make a separate HTTP request. So, the best solution is your main HTML plus a single JavaScript file and a single CSS file. The 3rd point is to minify those files, that is to remove comments, extra spaces and linebreaks, so as to make those files lighter. Options also include renaming the variables to make their names shorter (which can obsfuscate, deliberately or not).

3. Minification at build time

Among all the tools avalaible, a good one for minifying JS and CSS (starting from v2.0) is Yahoo UI Library Compressor. It is developed in Java and can be runned from the command line. Such command can take place during the build process. The following Ant task executes the minifying process on simple.js :

<!-- Executes YUI compressor on simple JS file -->
<target name="simplest">
  <java jar="tools/yuicompressor-2.4.2.jar" fork="true">
    <arg value="-v" />
    <arg value="web/script/simple.js" /&>
  </java>
</target>

The main drawback of this solution is that you lose your original script in favor of the minified one. YUI compressor enables to output the minified script in a new script, hence the following Ant target :

<!-- Executes YUI compressor on simple JS file -->
<target name="simple">
  <java jar="tools/yuicompressor-2.4.2.jar" fork="true">
    <arg value="-v" />
    <arg value="web/script/simple.js" />
    <arg value="-o" />
    <arg value="${build.dir}/web/script/simple.js" />
  </java>
</target>

This makes the process slightly better. Yet, I cannot test the minified script under my favourite IDE because the script is only correct in the WAR creation scope, not in the deploy-in-IDE scope.

4. Minification at runtime

In order to prevent this drawback, we could make the minifying a runtime process. In order to do this, we create a filter that is associated with .js extensions :

package ch.frankel.blog.jawr.web;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringWriter;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import com.yahoo.platform.yui.compressor.JavaScriptCompressor;

/**
 * Filter that minifies JavaScript files. Can be used with CSS files with less configuration.
 *
 * @author Nicolas Fränkel
 * @since 17 mars 2009
 */
public class YuiCompressorFilter implements Filter {

    /** Configuration object. */
    private FilterConfig config;

    /** Number of kept linebreaks. */
    private int linebreak;

    /** Munge. */
    private boolean munge;

    /** Verbose. */
    private boolean verbose;

    /** Should all semicolons be kept. */
    private boolean preserveAllSemiColons;

    /** Should optimization be disabled. */
    private boolean disableOptimizations;

    /**
     * This implementation does nothing.
     *
     * @see javax.servlet.Filter#destroy()
     */
    @Override
    public void destroy() {}

    /**
     * Compress JS and CSS output.
     *
     * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
     *      javax.servlet.ServletResponse, javax.servlet.FilterChain)
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
	    ServletException {

	StringWriter stringWriter = new StringWriter();

	final PrintWriter printWriter = new PrintWriter(stringWriter);

	HttpServletRequest httpRequest = (HttpServletRequest) request;

	String path = httpRequest.getServletPath();

	InputStream stream = config.getServletContext().getResourceAsStream(path);

	Reader source = new InputStreamReader(stream);

	stream.close();

	JavaScriptCompressor compressor = new JavaScriptCompressor(source, new BasicErrorReporter());

	compressor.compress(printWriter, linebreak, munge, verbose, preserveAllSemiColons, disableOptimizations);

	response.getWriter().write(stringWriter.getBuffer().toString());

	printWriter.close();
    }

    /**
     * Reads filter parameters.
     *
     * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
     */
    @Override
    public void init(FilterConfig config) throws ServletException {

	this.config = config;

	String linebreakString = config.getInitParameter("linebreak");
	String mungeString = config.getInitParameter("munge");
	String verboseString = config.getInitParameter("verbose");
	String preserveAllSemiColonsString = config.getInitParameter("preserveAllSemiColons");
	String disableOptimizationsString = config.getInitParameter("disableOptimizations");

	munge = Boolean.parseBoolean(mungeString);
	verbose = Boolean.parseBoolean(verboseString);
	preserveAllSemiColons = Boolean.parseBoolean(preserveAllSemiColonsString);
	disableOptimizations = Boolean.parseBoolean(disableOptimizationsString);

	try {

	    if (linebreakString != null) {

		linebreak = Integer.parseInt(linebreakString);
	    }

	} catch (NumberFormatException e) {

	    throw new ServletException(e);
	}
    }
}

Now our compressor works both in and out of our favorite IDE. But the drawback is the performance lost in applying the filter each time the resource is needed. In order to lessen this cost, we could:

  • implement a cache that maps paths to minified scripts (as strings) in memory,
  • rely on the browser cache by using HTTP headers related to expiration values.

Still, I find this not very satisfying… First of all, YUI compressor was not supposed to be used in this fashion. This shows because you find no documentation, JavaDoc or else, regarding individual use of the methods. Then, the less I code, the better I feel. In this case, I had to code a whole filter, complete with initialization parameter. Last but not least, do you remember the 3 rules, at the top of the article? We adressed only the 3rd point, minifying the script, but in no way did we make fewer HTTP request by using YUI compressor. If we had 15 different source scripts, we would still have 15 minified scripts at the end and thus need 15 HTTP requests to get them all.

5. Jawr

Jawr is the solution to our problem: it enables to have different scripts during development (third-party scripts, enterprise framework scripts, applications scripts, etc.) and bundles them at application startup in one big script file. The process is completely transparent to the developer and is lightweight because all work is done at application startup.

Additional features include:

  • Bundling of any JavaScript or CSS file whatever the chosen directory structure,
  • Modifying those files dynamically, e.g. with ResourceBundle messages,
  • JavaScript and CSS minification (oh, what a surprise!) that can be done with either YUI Compressor or JSMin,
  • Caching enforcement through is a modification of sent HTTP headers,
  • GZip support for compatible browsers.

In order to do so, Jawr uses 3 kind of components:

  • a servlet to serve JavaScript and CSS content,
  • jawr taglibs that references JS and CSS,
  • a configuration file in Java properties format.

The configuration of the web deployment descriptor will look something like this:

<servlet>
    <servlet-name>JawrServlet</servlet-name>
    <servlet-class>net.jawr.web.servlet.JawrServlet</servlet-class>
    <init-param>
        <param-name>configLocation</param-name>
        <param-value>/jawr.properties</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>JawrServlet</servlet-name>
    <url-pattern>*.js</url-pattern>
</servlet-mapping>

An example properties file will look like this

#Turning on compression when possible
jawr.gzip.on=true
#Using YUI compressor
jawr.js.bundle.factory.bundlepostprocessors=YUI
#Bundling into all.js
jawr.js.bundle.all.id=/script/all.js
#Bundled scripts
jawr.js.bundle.all.mappings=/script/simple.js, /script/sub/b.js, /script/sub/subsub/a.js

The, you will use it like this in your page:

<%@ taglib prefix="jawr" uri="http://jawr.net/tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
        <titlegt;Jawr test welcome page</title>
    </head>
    <body onload="a();b()" />
<jawr:script src="/script/all.js" />
</html>

You will find there a Jawr example project made with Eclipse along with the previous YUI Compressor example. This example shows you the main uses of Jawr, mainly:

  • bundling JavaScript files,
  • minifying them,
  • compressing the bundled file (if you browser supports it).

As an example, it will only output two JavaScript alert boxes, but it will you the framework to build upon if you need to go further.

6. Conclusion

Minifying external files is not the only think of in order to decrease your web pages load time. You should also decrease to the maximum the number of these files. Jawr is an OpenSource component used to do both elegantly: I hope this article convinced you that Jawr is the right tool for this usage.

Categories: JEE Tags: , , , ,

Framework agnostic JPA

March 10th, 2009 Nicolas Frankel No comments

With new JEE 5 standard has come the EJB3 specifications. From an historical point of view, EJBs come into 3 different flavors: (i) Entity for persistence, (ii) Session for business logic and (iii) Message-Driven for listeners. Entity EJB are the most time-consuming to develop in their 2.1 version. Apart from the inherent complexity of EJB (local and remote interfaces, homes), developing an EJB 2 is error-prone because of the mapping mechanism. All in all, EJB 2 development really needs a very specialized IDE and expert developers. That’s the main reason why EJB 2 didn’t achieve a significant market share, and had to compete with JDO, Hibernate and other third-party frameworks.

Sun eventually realized this and did come with a much simpler solution with EJB 3. Using Java 5 annotations, developing Entity EJB 3 is a breeze. The part of EJB 3 specifications that deal with Entity is called Java Persistence API (JPA). It is a specification in its own right, and in the next specifications, it will have its own. Developing JPA applications is a two-step process. First, you have to create you model classes. Such classes will be the foundation of your persistence layer: it would be a good idea to use this layer throughout your entire organization, since these classes should closely map your database model. A simple JPA enhanced class would look like this: Read more…

Categories: Java Tags: , ,

WordPress 2.7.1 upgrade

March 8th, 2009 Nicolas Frankel No comments

Noticed anything different on this blog? No? Yet, I upgraded WordPress from version 2.5 to version 2.7.1. Since you had no problems viewing this post, we can safely admit the upgrade process was entirely successful.

The upgrade process is very simple since WordPress is developed in PHP. Just copy (and sometimes overwrite) the contents of the wordpress folder to your webserver and presto, you got the new version. I must admit I was a little afraid something would go wrong… And what to do in this case? Prior to the upgrade, I did a backup of WordPress database using WordPress Database Backup plugin.

Now everything is fine. And Mango theme is upgraded too.

Categories: Technical Tags: ,

Against french Hadopi

March 4th, 2009 Nicolas Frankel No comments

HADOPI - Le Net en France : black-out

Categories: Miscellaneous Tags: