Archive

Archive for the ‘JEE’ Category

Clustering Tomcat

February 24th, 2010 Nicolas Frankel No comments

In this article, I will show you how to use Apache/Tomcat in order to set up a load balancer. I know this has been done a zillion time before, but I will use this setup in my next article (teaser, teaser) so at least I will have it documented somewhere.

Apache Tomcat is the reference JSP/container since its inception. Despite a lack of full JEE support, it certainly has its appeal. The reasons behind using a full-featured commercial JEE application server are not always technical ones. With lightweight frameworks such as Spring being mainstream, it is not unusual to think using Tomcat in a production environment. Some companies did it even before that.

When thinking production, one usually think reliability and scalability. Luckily, both can be attained with Apache/Tomcat through the set up of a load-balancing cluster. Reliability is thus addressed so that if a Tomcat fails, following requests can be directed to a working Tomcat. Requests are dispatched to each Tomcat according to a predefined strategy. If the need be, more Tomcat can be added at will in order to scale.

In the following example, I will set up the simplest clustering topology possible: an Apache front-end that balances 2 Tomcat instance on the same physical machine.

Set up Apache

The first step is to configure Apache to forward your requests to Tomcat. There are basically 2 options in order to do this (I ruled out the pre-shipped load-balancer webapp):

  • use mod_jk, the classic Apache/Tomcat module
  • use mod_proxy, another Apache module

I’m not a system engineer, so I can’t decide on facts whether to use one or the other: I will use mod_jk since I’ve already used it before.

  • Download the mod_jk that is adapted to your Apache and Tomcat versions
  • Put it in the ‘modules’ folder of your Apache installation
  • Update your httpd.conf configuration to load it with Apache
    LoadModule jk_module modules/mod_jk-1.2.28-httpd-2.2.3.so
  • Configure Apache. Put these directive in the httpd.conf:
    JkWorkersFile	conf/worker.properties
    JkShmFile	logs/mod_jk.shm
    JkLogLevel	info
    JkLogFile logs/mod_jk.log
    JkMount		/servlets-examples/* lb

This configuration example is minimal but needs some comments:

Parameter Description
JkWorkersFile Where to look for the module configuration file (see below)
JkShmFile Where to put the shared memory file
JkLogLevel Module log level (debug/error/info)
JkLogFile Log file location. It is the default but declaring it avoid the Apache warning
JkMount Which url pattern will be forwarded to which worker

Since mod_jk can be used in non-clustered setups, there could be any JkMount, each forwarding to its own worker (see below). In our case, it means any request beginning with /servlets-examples/ (the trailing slash is needed) will be forwarded to the ‘lb’ worker .

Configure the workers

Workers are destination routes as viewed by Apache. They’re are referenced by an unique label in the httpd.conf and parameteirzed under the same label in the worker.properties file.
My workers.properties is the following:

worker.list=lb

worker.worker1.port=8010
worker.worker1.host=localhost
worker.worker1.type=ajp13

worker.worker2.port=8011
worker.worker2.host=localhost
worker.worker2.type=ajp13

worker.lb.type=lb
worker.lb.balance_workers=worker1,worker2

I define 3 workers in this file: lb, worker1 and worker2. The ‘lb’ worker is the load-balancing worker: it is virtual and it balances the latter two. Both are configured to point to a real Tomcat instance.

Now, with the Apache configuration in mind, we see that requests beginning with /servlets-examples/ will be managed by the load balancer worker which will in turn forward to a random worker.

Note: one can also put weight on workers hosted by more powerful machines so that these are more heavily loaded than less powerful ones. In our case, both are hosted on the same machine so it has no importance whatsoever.

Configure the Tomcat instances

The last step consist of the configuration of Tomcat instances. In order to do so, I shamelessly copied entire Tomcat installations (I’m on Windows). While editing the server.xml of the Tomcat instances, three points are worth mentioning:

  • The Engine tag has a jvmRoute attribute. It’s value should be the same as the worker’s name used in both httpd.conf and worker.properties. Otherwise, sessions will be recreated for each request
  • Look out for duplicated port numbers if all Tomcat instances are on the same machine. For example, use an incremental rule to configure every stream on a different port
  • Be sure that the tcpListenPort attribute of the Receiver is unique across all Tomcat instances

Use it!

With the previous set up, one can now start both Tomcat and Apache, then browse to the servlet-examples webapp, and more precisely to the Session page. Look there for Tomcat 5.5 and there for Tomcat 6. The servlet-example page page displays the associated session ID:

ID de Session: 324DAD12976045D197435033A67C025D.worker2
Crée le: Tue Feb 23 23:15:13 CET 2010
Dernier accès: Tue Feb 23 23:31:47 CET 2010

Notice that on my Tomcat instance, the worker’s name is part of the session ID.

If everything went fine, two interesting things should take place: first, when refreshing the page, the session ID should not change because of the sticky session (enabled by default). Morevoer, if I shutdown the Tomcat instance associated with the worker (the second in my case), and if I try to refresh the page, I still can access my application, but under a new session.

Thus, I lose all the information I stored under my session! In my following article, I will study how on can try to remedy to this.

To go further:

Categories: JEE Tags: ,

Context root tweaking

February 1st, 2010 Nicolas Frankel No comments

JEE never ceases to amaze me. Even when I think I’m on top and I know all there’s to know about webapps, I’m in for a surprise. Good news is, whatever you think you know about a subject, there’s still room for one more fact. Bad news is, I’m deeply disturbed by what I learned.

Fact is: web applications context root can contain the / characte, meaning an URL such as http://localhost/multipart/context can refer to the root of the multipart/context webapp as well as to the context servlet mapping of the http://localhost/multipart webapp. When I was told that, my first reaction was disbelief. I immediately hurried to run a few tests on the JOnAS and JBoss application servers and it confirmed that was entirely possible.

In fact, if you look at the application.xml XML Schema, you see that the context-root is of a type that extends string (with an id) :

This means the context root can effectively contains anything, including slashes, backslashes and what have you.

The J2EE 1.4 specifications does not enforce additional constraints (p 125) :

Each web module must be given a distinct and non-overlapping name for its context root. [...] See the servlet specification for detailed requirements of context root naming.

I did not see additional requirements in the Servlet 1.4 specifications for the context root.

Tomcat even takes this tweak into account when creating Context with individual XML files. It calls it “multi-level context paths” :

In individual files (with a “.xml” extension) in the $CATALINA_HOME/conf/[enginename]/[hostname]/ directory. The name of the file (less the .xml) extension will be used as the context path. Multi-level context paths may be defined using #, e.g. foo#bar.xml for a context path of /foo/bar.

So, in order to deploy the context.war under the multipart/context root, you’ll have to name the context XML file multipart#context.xml.

The content of the file is the following:

<?xml version='1.0' encoding='utf-8'?>
<Context docBase="${catalina.home}/context.war" />
<!-- this means the context.war should be available at the root of Tomcat -->

In the tests I’ve made, if the multi-level context path shadows a classic context-root with a servlet mapping, the former takes precedence. I do not advise using this since the case is not specified in the specification, it could be handled differently from product to product.

OK, now we’ve established these facts, what is the point in knowing this, aside from setting you as the übergeek in a JEE geek convention? Since http://localhost/multipart/context and http://localhost/multipart are clearly separated web applications, they do not even share context.

In my case, that was the solution for a simple use-case. Imagine monitoring web applications: you know the URL you have to monitor. Now a product, developped in-house for diagnostics purpose, is deployed side-by-side with each webapp in webapp form. It would be very nice if you could reach the diagnostics webapp without looking at the documentation to know its URL. Let’s say it is the business webapp’s URL appended with /diag.

So, if the main webapp’s URL is http://myserver.com/mywebapp and the person in charge of monitoring knows about it, he knows he has to access http://myserver.com/mywebapp/diag and he gets what he wants! On the development side, it means both webapps are different products, are developed by different teams and have different lifecycles.

Categories: JEE Tags: , , ,

HTML UI over a REST backend

December 26th, 2009 Nicolas Frankel No comments

In this article, I will show you that forms sent by browsers to a server can only use GET and POST HTTP methods and which workaround to apply in order to still use a REST backend.

REST web-services are becoming more and more common in today’s landscape. We can only imagine the reasons, but I guess that SOAP’s structured approach is only useful in the most complex use-cases and is overkill the rest of the time. On the contrary, REST is quite easy to setup.

In the Java world, REST has its own specification, JAX-RS with JSR 311, and is supported by all major frameworks :

In my humble opinion, it is not inconceivable that, given the adoption of REST, the next step would be the development of REST backends accessible by standard clients and browsers alike, in order to factorize code and thus decrease costs.

Traditionallly, making a resource accessible on the web is realized through a hyperlink. Hyperlinks use the GET method. Likewise, REST is based on using the HTTP methods where each has an associated verb:

HTTP method Verb
POST Create
GET Read
PUT Update
DELETE Delete

Unluckily, the real world comes into play. In order for this to work, the HTML 4 specification is a big obstacle in the way:

The FORM element [...]

Method: this attribute specifies which HTTP method will be used to submit the form data set. Possible (case-insensitive) values are “get” (the default) and “post”.

The implication is that HTML 4 compliant browsers will only let you read and create but not update nor delete. For example, the versions of Firefox and Internet Explorer I used, respectively 3.5.6 and 6.0 (!) use POST for POST and GET for everything else. That’s a real case against using REST. There are some workarounds, though.

The first one is not to use the HTTP method for the verb but to put it in the URL. Thus

  • to access a customer, one would use http://frankel.ch/get/customer/1
  • and to remove one, http://frankel.ch/delete/customer/1

This clearly violates REST’s principle of using the HTTP method for the verb but this works for simple cases.

The second workaround is a bit more complex but it has two big advantages: it conforms to REST principles and it is usable with most modern-days browsers.

The trick is to use a neat little object created by Microsoft but now implemented everywhere, the XMLHttpRequest object. Yes, this is the object at the foundation of Ajax but is is also the solution of our problem. XMLHttpRequest’s open() method takes two parameters, the first being the HTTP method to use for accessing the url (which is the second parameter). Now you can pass the verb you want, like the following example.

xmlhttp = new XMLHttpRequest();
xmlhttp.open('DELETE', 'http://frankel.ch/customer/1');
xmlhttp.send(null);

Morevover, you can not only use the 4 CRUD verbs but also any verb you want.

This solution has two main limitations:

  • it requires modern-day browsers since the XMLHttpRequest object is not available in more ancient ones
  • it requires JavaScript, so you need to enable it on client browsers and you need to manage browser compatibilities. For example, the above script with Firefox 3.5 but not IE 6 (and to be blunt, I’m not really bothered by it)

It seems this hack will be rendered useless by the HTML 5 specifications which declares (in their draft state) that all 4 basic CRUD verbs will have to be supported.

You can find an example for this article here. Tu use, navigate to http://localhost:8080/httpmethods/ if deployed in Eclipse. It was tested on Firefox 3.5 and works on it flawlessly. On the contrary, it doesn’t work for IE 8 since my script is not crafted to be cross-browsers. For Tomcat users, you have to add JSTL capabilities to Tomcat (meaning adding standard.jar and jstl.jar in the commons/lib directory).

To go further :

Categories: JEE Tags: ,

Simple templating solution with SiteMesh

October 24th, 2009 Nicolas Frankel No comments

In this article, I will show you how to use SiteMesh in your JEE web sites in order to bring a sense of unity to them.

When talking about templating, the method everyone uses at first is to use <@include> tags throughout the JSP pages. This course of action is flawed from the start since all JSPs are responsible to call includes and thus, there’s no real enforcement to use the correct ones.

The most used method is Apache Tiles. To be frank, I didn’t have a look at Tiles since it went from Struts to Apache. Struts Tiles were meant to be used in conjunction with Struts. Apache Tiles seems to support many more technologies (JSP, Velocity, Freemarker, …) but I didn’t see any JSF support out-of-the-box though there seem to exist plenty of articles that tackle the subject and its problems.

When I used Struts Tiles, I found it was a very powerful framework, yet many junior developers had some problems with it. In most projects I worked on, a senior developer assembled tiles while junior ones created the pages themselves. I found Tiles very configurable but this came at the cost of complexity. In most cases, I didn’t need all the functionalities of Tiles: I only wanted to have a header, a footer and a menu nicely crafted around my main page.

When investigating AppFuse, I stumbled upon a nice templating tool that just does that: SiteMesh. SiteMesh is technology-neutral, meaning it can be used with whatever view framework is used, JSF included. It is based on the very simple concept of servlet filters. An XML file forms the basis of the template’s configuration. This configuration holds what pages are decorated and with what templates.

The templating mechanism is made so each page is seen as complete either when viewed standalone or when viewed through the filter. For example, when you write the page normally, you provide the title’s text (what is displayed in most browser’s title bar). If you are using SiteMesh, nothing changes. At runtime, the servlet filter reads the title’s text value from the source HTML (which can come from a dynamic source) and outputs the decorated page with the same title’s text value, although the page design will be different.

The following example shows how it is achieved in the template:

<html>
  <head>...</head>
  <body>
    <div id="top">Header</div>
    <h1><decorator:getProperty property="title" /></h1>
    ...
  </body>
<html>

Nothing could be simpler. Yet, the solution decouples the standalone view from the decorated view. The former has no need to know about the latter!

A common use-case is to put common CSS and JavaScript declarations in the template.

Moreover, the choice of which decorator(s) to use can come from different strategies:

  • configuration files,
  • cookies,
  • browser language,
  • display agent (browser or printer),
  • etc.

The simplicity and the robustness of the solution is what will make me deeply think about using it if I have simple templating needs. On the opposite site, if you have complex templating requirements, SiteMesh won’t be enough.

You will find a very simple project here in Maven/Eclipse format.

To go further:

Tomcat’s Valve, an alternative to Filter

September 11th, 2009 Nicolas Frankel 1 comment

Tomcat's logoIn this article, I will show you how to replace filters declared in web.xml with unobtrusive mechanism in Tomcat.

I’m a big friend of Apache Tomcat. In many cases, even enterprise applications can run with a simple JSP – servlet container and Tomcat has passed through all the evolutions of the standards with flying colors. This is not to say that other containers are bad (Jetty for instance, is very good at being embedded), only that I know enough about Tomcat to know it’s stable and bugfixes are regularly available: a condition for using a product in the enterprise. I am always amazed at why so few Tomcat run in production, compared to big fat application servers. Is it because it is too simple? Yet, it can be very powerful, as I will show with the Valve concept.

Designers and architects know about the Intercepting Filter pattern: these filters intercept requests and responses and can be chained. The implementation of this pattern is the javax.servlet.Filter interface available since Servlet v2.3. Let’s take an example: suppose you have to get additional informations in a database (suche as name, ect.) when authentifying with a classical JAAS login. Since your application is not responsible for performing the check, it is impossible to get these infos at the right time. It is very simple when using a filter.

First problem: you do not want your developers to write the database access code with each new application. You create the filter once, put it in the JAR and tell your teams to use this filter in their web.xml once and for all. Now your enterprise evolve and put information relative to people in a LDAP server (not really a bad idea). For newly created applications, you create another filter that access LDAP and use it from now on.

Second problem: what do you do with your applications that use the legacy filter?

  1. You can run a batch that update the web.xml throughout your entire filesystem. Well, for me, that’s too risky… I wouldn’t want to get my production down in one big shot! And if the webapps run in non-exploded mode, it is impossible.
  2. You can still use the database and create a batch that synchronize data from the LDAP server to the database. Not risky at all. And 20 years latter, your information system is a big plate of spaghetti because information is duplicated everywhere. Not very urban.
  3. Finally, you can rely on our Tomcat friend from the beginning, remove the filter from applications at all and put a specific filter called a valve in Tomcat itself. A big disadvantage is that you now are coupled to Tomcat. This is not as bad as it sounds since the code is so isolated it can safely be migrated to another application server API real quick.

I suppose mad dogs would go with option 1 and managers that change every 2 years would go with option 2. Of course, from my clearly subjective presentation of the solutions, you can guess i would go with option 3.

“Valve is a request processing component associated with a particular Container. A series of Valves are generally associated with each other into a Pipeline.”

From Tomcat’s Javadoc

A valve is designed with a very generic interface org.apache.catalina.Valve. Tomcat also provides an abstract class org.apache.catalina.valves.ValveBase that can be safely extended. The main method of the latter is the invoke() method where you can access both request and response. Don’t forget to call the next valve in it or, like in filters, the chaining will stop.

From this point, you are free to do as you choose: access the LDAP server, put a cookie, log performances, etc.

You can find the Maven sources for 2 very simple examples here.

To go further:

Please note that the links point to the latest v6.0 version but the concepts exposed above are available in v5.5 and v4.1.

Categories: JEE Tags: , ,

Google AppEngine limitations for Java (and how to overcome them)

April 10th, 2009 Nicolas Frankel 6 comments

Since the start of Google’s App Engine for Java, I have tried to create a small but representative project and to deploy it on Google’s infrastructure. I have learned much, mainly by making mistakes. Interestingly enough, there are much that I achieved I didn’t hope I would. On the contrary, the Devil is in the details, as they say, and I found some problems I couldn’t imagine there: for some, there are other solutions, for some, there aren’t.

Eclipse

Eclipse is my first and foremost IDE. I tried NetBeans but, though I am NetBeans certified, it was too strange for me to work with. Anyway, Google provides an Eclipse plugin for GAE. When I tried to install it with the update site, I had a not so nice error popup:

Cannot complete the install because one or more required items could not be found.
Software being installed: com.google.gdt.eclipse.suite.e34.feature.feature.group 1.0.0.v200904062334
Missing requirement: com.google.gdt.eclipse.suite.e34.feature.feature.group 1.0.0.v200904062334 requires \
    'org.eclipse.platform.feature.group [3.4.0,3.5.0)' but it could not be found

Google’s plugin only works with version 3.4 (Ganymede) and I have version 3.5 (Galileo). So long for Eclipse, yet it seems Google plans to release a Galileo compatible version no later than Galileo own’s release (thanks Rajeev).

Maven

Like every not-so-young Java developer, I was proficient in Ant once. But I was bored to script the same tasks for every project, so I let Maven seduce me. It seems people at Google are still using only Ant (there’s no reference to Maven in GAE documentation), so you have to do the following if you want to use Maven:

  • Reference DataNucleus repository. Here’s the url : http://www.datanucleus.org/downloads/maven2,
  • Add dependencies to :
    • org.datanucleus:datanucleus-core:1.1.0:jar,
    • org.datanucleus:datanucleus-jpa:1.1.0:jar,
    • org.datanucleus:datanucleus-enhancer:1.1.0:jar,
  • datanucleus-core has a dependency on javax.jta:transaction-api:1.1:jar. Since its POM references a local repository (!), this artifact won’t be found. You have to install manually JTA 1.1 under this name,
  • Install manually and add dependencies to :
    • org.datanucleus:datanucleus-appengine:1.0.0.final:jar,
    • com.google.appengine:appengine-api:1.0:jar.

Spring

Spring works like a charm in GAE. GAE’s documentation says that reflection is near fully supported, so this shouldn’t come as a surprise. I didn’t use AOP though.

Commons-logging

Commons-logging is a dependency of many frameworks, Spring included. On the local server, everything runs fine. In the cloud, Google App Engine infrastructure replaces the commons-logging-1.1.1.jar with a JAR of its own that has a different package structure. In effect, that means you get funny NoClassDefFoundError on org.apache.commons.logging.LogFactory even though you included the JAR as a dependency. The solution is to still include the classes, but to give the JAR another name.

Since I use Maven, I removed the commons-logging dependency from the WAR with the exclusion tag for Spring and MyFaces artifact. Then, I added a dependency on commons-logging:commons-logging-api:1.1:jar with the runtime scope. This jar won’t be replaced.

JSP

JSP work fine in pages. Yet, XML format JSP doesn’t seem to get translated. You need to create “classic” JSP.

Still, you may run into some funny exception. It will look like this:

java.lang.ClassCastException: SomeException cannot be cast to javax.servlet.ServletException
    at org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:754)
    at org.apache.jsp.some_jsp._jspService(some_jsp.java:some_line)

It seems ther’s a bug in the PageContextImpl class where any RuntimeException will be cast to ServletException and thus end up creating another exception. It is very hindering since the ClassCastException’s stack trace will hide the first one’s stack trace. In order to debug, I advise you to use the following code snippet in the incriminated JSP:

&lt;% try { %&gt;

... your JSP body...

&lt;% } catch (RuntimeException e) {

    Logger log = Logger.getLogger(getClass().getName());
    StringWriter sw = new StringWriter();
    e.printStackTrace(new PrintWriter(sw));
    log.severe(sw.toString());
    throw e;

} %&gt;

EL

EL syntax in JSF tags (#) run fine. For EL syntax in JSTL taglibs – core for example ($), it didn’t work at first. Thanks to Jim, I know now you have to tell the App Engine not to ignore it with the code <%@ page isELIgnored="false" %> on each page you use EL with JSTL. IMHO, it could be a default behaviour, like in Tomcat, for example.

JSF

Apache MyFaces v1.1 works nicely. I had a problem with version 1.2: apparently, there was an API mismatch somewhere. So I’m stuck with the older version for now.

JPA

GAE’s persistence API of choice is JDO. Come on, guys, JDO in 2009? Still, GAE accepts JPA as an alternate persistence API, so you can use it, with caution. In both cases, GAE uses the DataNucleus framework (first time I heard of it – it seems related to JDO JPOX team). This framework, like any JDO framework enhances your entity classes with custom byte-code: this takes place in the build process after compilation. What’s very surprising with DataNucleus is that even if you choose JPA as your persistence API, you have to enhance your entity classes.

Since the enhancement process is dependent on some artifacts, check whether these artifacts are referenced as dependencies (see above for list). To bind the enhancement to the compile phase, use the following snippet in your POM (thanks Andy):

<build>
...
    <plugin>
        <groupId>org.datanucleus</groupId>
        <artifactId>maven-datanucleus-plugin</artifactId>
        <version>1.1.0</version>
        <configuration>
            <mappingIncludes>net/frankel/hr/cra/model/*.class</mappingIncludes>
            <verbose>true</verbose>
            <api>JPA</api>
        </configuration>
        <executions>
            <execution>
                <phase>compile</phase>
                <goals>
                    <goal>enhance</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
...
</build>

Using Datanucleus presents another limitation in that if you query using JPA (or JDO), you have to explicitly call the size() method on the resulting List. Otherwise, your JSP will throw a not-so-nice NucleusUserException labeled “Object Manager has been closed”. There’s an issue raised on the datanucleus-appengine integration project.

Local AppEngine server

Local server runs fine. I can’t help wondering why the translation / compilation process takes som much time (measured in minutes) though. Once it’s done, page rendering is very swift, since I think the server optimizes caching.

Deploying the application

The initial appcfg.cmd launches a Java class. I don’t know why but the application just ignores the JAVA_HOME environment variable and keeps checking for the java.home system property. If the latter is not found, it tries to use C:\Program Files\Java\jre6\bin and C:\Program Files\Java\bin looking for javac. Then it fails if not found… I had to modify the appcfg.cmd to put this command line (modification in bold and italic):

@java -Djava.home="%JAVA_HOME%" -cp "%~dp0\..\lib\appengine-tools-api.jar" com.google.appengine.tools.admin.AppCfg %*

Anyway, it avails to nothing because I get this following SSL exception:

Unable to upload:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found
	at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
	at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
	at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
	at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
	at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(Unknown Source)
	at com.google.appengine.tools.admin.ServerConnection.connect(ServerConnection.java:295)
	at com.google.appengine.tools.admin.ServerConnection.getAuthToken(ServerConnection.java:215)
	at com.google.appengine.tools.admin.ServerConnection.authenticate(ServerConnection.java:189)
	at com.google.appengine.tools.admin.ServerConnection.send(ServerConnection.java:116)
	at com.google.appengine.tools.admin.ServerConnection.post(ServerConnection.java:66)
	at com.google.appengine.tools.admin.AppVersionUpload.send(AppVersionUpload.java:345)
	at com.google.appengine.tools.admin.AppVersionUpload.beginTransaction(AppVersionUpload.java:159)
	at com.google.appengine.tools.admin.AppVersionUpload.doUpload(AppVersionUpload.java:68)
	at com.google.appengine.tools.admin.AppAdminImpl.update(AppAdminImpl.java:41)
	at com.google.appengine.tools.admin.AppCfg$UpdateAction.execute(AppCfg.java:469)
	at com.google.appengine.tools.admin.AppCfg.(AppCfg.java:114)
	at com.google.appengine.tools.admin.AppCfg.main(AppCfg.java:59)
Caused by: sun.security.validator.ValidatorException: No trusted certificate found
	at sun.security.validator.SimpleValidator.buildTrustedChain(Unknown Source)
	at sun.security.validator.SimpleValidator.engineValidate(Unknown Source)
	at sun.security.validator.Validator.validate(Unknown Source)
	at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(Unknown Source)
	at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
	at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
	... 24 more

The solution is to use the JRE bundled in your JDK. The command line thus becomes:

@java -Djava.home="%JAVA_HOME%/jre" -cp "%~dp0\..\lib\appengine-tools-api.jar" com.google.appengine.tools.admin.AppCfg %*

Now everything should run perfectly from here. Have fun!

To go further:

Categories: JEE Tags: ,

Free Java hosting

April 8th, 2009 Nicolas Frankel No comments

They did it! Yes, they did it! Since a long time, PHP hosting is avalaible freely on the web from a multitude of providers but when you search the web for free Java hosting you find… nothing. Mark today as a the day Java free hosting came to reality: they did it!

Who? Them, the techies from Google now support Java as their second language on Google App Engine. GAE leverages the entire Google infrastructure to host your web applications. Strangely enough, it was until then only available for the Python language. Now it’s not the case anymore. No need to pay for dedicated hosting. Just create your JEE application, add a small proprietary file for the App Engine and deploy using Google’s tools. Google’s infrastructure provides:

  • Java 6 Virtual Machine,
  • Servlets and JSP API (version undocumented),
  • support for standard interfaces to the App Engine datastore and services (JDO, JPA, JavaMail, JCache)

But since there’s no such thing as a free lunch, the only thing to do to have these things for free is to be under the following quotas:

  • 1,300,000 http requests per day,
  • 10,000 calls to Data store service per day,
  • and so on

Since these limits are very high for a personal website or even a small company’s one, it seems to the days of free Java hosting have come. In a next post, I’ll probably be creating a simple Java application to host. Until then, have fun.

To go further:

Categories: JEE Tags: , ,

Custom LoginModule in Tomcat

April 3rd, 2009 Nicolas Frankel 2 comments

Tomcat manages application security through the concept of realm. A realm is a coherent package of name password pairs that identify valid users for a web application.

Tomcat’s default realm is MemoryRealm. This realm reads the famous conf/tomcat-users.xml file and uses it check for name password pair validity. Tomcat also provides realms to check against pairs stored in a database, either through a direct connection, or through a configured datasource. The main disadvantage of these all these realms is that they force you to adopt Tomcat’ expected data structure. In most organizations, these constraints will be enough for the architect to rely upon custom or 3rd-party security components.

In order to use your enterprise database structure, you would code a custom realm. Tomcat provides the org.apache.catalina.Realm interface. The drawback of implementing your own realm is that if you change your application server afterwards, all of your code would have been for naught. Yet, if you check Tomcat documentation thoroughly, you will see Tomcat also provides a JAASRealm. JAAS is the Java security feature and enable you to write custom security modules in a portable way. Tomcat’s JAASRealm performs as a adapter between realms and login modules so you only have to write a LoginModule and Tomcat will know how and when to call it. Read more…

Categories: JEE Tags: , , , ,

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:

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

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:

&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;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 "&gt;
    &lt;tlib-version&gt;1.0&lt;/tlib-version&gt;
    &lt;short-name&gt;tf&lt;/short-name&gt;
    &lt;uri&gt;http://blog.frankel.ch/examples/tagfiles&lt;/uri&gt;
    &lt;!-- don't use tagclass --&gt;
    &lt;tag-file&gt;
        &lt;name&gt;hello&lt;/name&gt;
        &lt;path&gt;/META-INF/tags/hello.tag&lt;/path&gt;
    &lt;/tag-file&gt;
&lt;/taglib&gt;

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:

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

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: , , ,

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 :

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

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 :

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

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(&amp;amp;quot;linebreak&amp;amp;quot;);
	String mungeString = config.getInitParameter(&amp;amp;quot;munge&amp;amp;quot;);
	String verboseString = config.getInitParameter(&amp;amp;quot;verbose&amp;amp;quot;);
	String preserveAllSemiColonsString = config.getInitParameter(&amp;amp;quot;preserveAllSemiColons&amp;amp;quot;);
	String disableOptimizationsString = config.getInitParameter(&amp;amp;quot;disableOptimizations&amp;amp;quot;);

	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:

&amp;amp;lt;servlet&amp;amp;gt;
    &amp;amp;lt;servlet-name&amp;amp;gt;JawrServlet&amp;amp;lt;/servlet-name&amp;amp;gt;
    &amp;amp;lt;servlet-class&amp;amp;gt;net.jawr.web.servlet.JawrServlet&amp;amp;lt;/servlet-class&amp;amp;gt;
    &amp;amp;lt;init-param&amp;amp;gt;
        &amp;amp;lt;param-name&amp;amp;gt;configLocation&amp;amp;lt;/param-name&amp;amp;gt;
        &amp;amp;lt;param-value&amp;amp;gt;/jawr.properties&amp;amp;lt;/param-value&amp;amp;gt;
    &amp;amp;lt;/init-param&amp;amp;gt;
    &amp;amp;lt;load-on-startup&amp;amp;gt;1&amp;amp;lt;/load-on-startup&amp;amp;gt;
&amp;amp;lt;/servlet&amp;amp;gt;
&amp;amp;lt;servlet-mapping&amp;amp;gt;
    &amp;amp;lt;servlet-name&amp;amp;gt;JawrServlet&amp;amp;lt;/servlet-name&amp;amp;gt;
    &amp;amp;lt;url-pattern&amp;amp;gt;*.js&amp;amp;lt;/url-pattern&amp;amp;gt;
&amp;amp;lt;/servlet-mapping&amp;amp;gt;

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:

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

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: , , , ,