Category Archives: J2EE

cache instances of objects in a web application

I’m (perennially) working on karensrecipes.com tonight, putting the final touches on the application. I’d running into a couple places on the site where performance is not so good so I’d like to start caching objects, presumably in the servlet container. I’m looking for ‘the way’ to cache instances of objects in a web application. I found this article on JavaWorld.com, which seems promising, but doesn’t relate caching to a servlet container. Would you just place the hashtable in the ServletContext using setAttribute()?

JCACHE – Java Temporary Caching API looks promising as well, although I don’t see where JCACHE lives.. anyone else know if JCACHE is alive and well?

I remember going to a presentation on caching at JavaOne last year, one of the presentations was on ESI, but of course, they have nothing to download on that site, so it’s worthless.

More on ColdFusion & HttpSessionListener interface

Update on yesterday’s post. Here’s a sample listener that implements the HttpSessionListener interface:

****************************************************
package com.mindseye;

import javax.servlet.http.*;
import javax.servlet.http.HttpSessionListener;

/**
* @author Aaron Johnson
* ajohnson@mindseye.com
*
* CFMXHttpSessionListener: An object that implements the HttpSessionListener
* interface, allowing CFMX developers to use session_OnStart and session_OnEnd
* events. This class can only retrieve the J2EE session ID when “Use J2EE
* session variables” is checked in CFIDE –> Administrator –> Memory
* Variables.
*/

public class CFMXHttpSessionListener implements HttpSessionListener {

public void sessionCreated(HttpSessionEvent se) {

// get the session just created
HttpSession newSession = se.getSession();

// do something with the new session (ie: log to db, write to a file, email to a friend
System.err.println(“A new session was created: session = ” + newSession.toString());
System.err.println(“Creation:” + newSession.getCreationTime());

}

public void sessionDestroyed(HttpSessionEvent se) {

// get the session just created
HttpSession newSession = se.getSession();

/* do stuff upon session end, (ie: delete items from this users shopping cart
if you’re persisting items to a db..)
*/
System.err.println(“A session was destroyed: session = ” + newSession.toString());
System.err.println(“Creation:” + newSession.getCreationTime());

}
}

****************************************************
And then to get this class to run, you must add

<listener>
  <listener-class>
    com.mindseye.CFMXHttpSessionListener
  </listener-class>
</listener>

to CFMX\wwwroot\WEB-INF\web.xml and you must copy the compiled class to the CFMX\wwwroot\WEB-INF\classes\com\mindseye\ folder. Additionally, it appears that (and this makes sense) the session we’re getting information about is the J2EE session ID, not the CFID & CFTOKEN. This means that you must have “Use J2EE session variables” checked in CFIDE –> Administrator –> Memory Variables. Restart CFMX and then you can see the results in cfusionmx\runtime\logs\default-err.log

This class would probably be way more useful if it actually did something… like log the start and end times, the id and maybe the servlet context to a database, but each developer will probably want to do something different, so I’ll leave that unfinished. I’m *not* seeing the session_OnEnd fired in my testing… anyone wanna take a guess?

Here’s a sample application_OnStart for CFMX:

****************************************************
package com.mindseye;

import javax.servlet.*;
import javax.servlet.ServletContextListener;

/**
* @author Aaron Johnson
* ajohnson@mindseye.com
*
* CFMXServletContextListener: An object that implements the ServletContextListener
* interface, allowing CFMX developers to use application_OnStart and
* application_OnEnd events.
*/
public class CFMXServletContextListener implements ServletContextListener {

public void contextDestroyed(ServletContextEvent sce) {

ServletContext sc = sce.getServletContext();

// do something on destroy()
System.err.println(“The application ‘” + sc.getServletContextName() + “‘ was destroyed”);

}

public void contextInitialized(ServletContextEvent sce) {

ServletContext sc = sce.getServletContext();

// do something on destroy()
System.err.println(“The application ‘” + sc.getServletContextName() + “‘ was started”);
}
}
****************************************************

Again, same thing, you must copy the compiled class files to cfusion\wwwroot\WEB-INF\classes\com\mindseye\, add a <listener> element to web.xml and restart CFMX. You’ll see the results in cfusion\runtime\logs\default-err.log.

I’d love to hear from Macromedia (or any other Java geeks) as to why I don’t get an results from sessionDestroyed().

ColdFusion & HttpSessionListener interface

Couple weeks ago some guys from Macromedia stopped by to yack with us about what we thought could be improved and/or added to the next version of CFMX. One of the things that came up a couple times was that it would be nice to have session OnStart and OnEnd functionality as well as application OnStart and OnEnd. Reading this month’s Java Developer’s Journal, it has an article on the HttpSession object (I’d link to it, but they charge for their content… too bad, I bet they’d be getting alot more traffic and readers if they’d provide their content for free), which provides multiple listener objects, HttpSessionListener, HttpSessionBindingListener, HttpSessionAttributeListener, and HttpSessionActivationListener. I don’t have CFMX here at home, but it seems like it would be possible to write a class that implements those either of those interfaces (probably the sessionCreated() and sessionDestroyed methods of the HttpSessionListener object), register that class in the web.xml of WEB-INF for your application like this:

<listener>
  <listener-class>
    com.yourApp.yourSessionListener
  </listener-class>
</listener>

Turns out you could do the same type of thing w/ javax.servlet.ServletContextListener [contextDestroyed() and contextInitialized()] and then register:

<listener>
  <listener-class>
    com.yourApp.yourApplicationListener
  </listener-class>
</listener>

in your web.xml and then… hypothetically, you’d have session OnStart, session OnEnd, application OnStart and application OnEnd just like ASP.

I’ll try it out tomorrow, unless you beat me to it.

Use of the Class object

On the subject of the use of the Class object:

“… Reassuringly, instanceof and isInstance( ) produce exactly the same results, as do equals( ) and ==. But the tests themselves draw different conclusions. In keeping with the concept of type, instanceof says “are you this class, or a class derived from this class?” On the other hand, if you compare the actual Class objects using ==, (or getClass()) there is no concern with inheritance—it’s either the exact type or it isn’t.” [ezdefinition]

JSP Precompilation

More from the JSP Spec:

“A request to a JSP page that has a request parameter with name “jsp_precompile” is a precompilation request . The “jsp_precompile” parameter may have no value, or may have values “true” or “false”. In all cases, the request should not be delivered to the JSP page. The intention of the precompilation request is that of a suggestion to the JSP container to precompile the JSP page into its JSP page implementation class. The suggestion is conveyed by giving the parameter the value “true” or no value, but note that the request can be ignored.

For example:
1. ?jsp_precompile
2. ?jsp_precompile=”true”
3. ?jsp_precompile=”false”
4. ?foobar=”foobaz”&jsp_precompile=”true”
5. ?foobar=”foobaz”&jsp_precompile=”false”

1, 2 and 4 are legal; the request will not be delivered to the page. 3 and 5 are legal; the request will not be delivered to the page.

6. ?jsp_precompile=”foo”

This is illegal and will generate an HTTP error; 500 (Server error).”

So does anyone have utilities for automating this upon deployment of an application? Nice… apparently Ant has a task built in to do this very thing.

WEB-INF

So today at work a question came up about were you’re supposed to store your tld file for your JSP tags… in the webroot (ie: wwwroot/mytags.tld) or in the WEB-INF directory. From my work with with JSP and Servlets, I knew that mytags.tld was supposed to go in the WEB-INF directory, but I didn’t know why. So, why is it that way?

JSR-000053 JavaTM Servlet 2.3, page 61 of 257:

“A special directory exists within the application hierarchy named “WEB-INF”. This directory contains all things related to the application that aren’t in the document root of the application. The WEB-INF node is not part of the public document tree of the application. No file contained in the WEB-INF directory may be served directly to a client by the container. However, the contents of the WEB-INF directory are visible to servlet code using the getResource and getResourceAsStream method calls on the ServletContext. Hence, if the Application Developer needs access, from servlet code, to application specific configuration information that he does not wish to be exposed to the web client, he may place it under this directory. Since requests are matched to resource mappings case-sensitively, client requests for ‘/WEB-INF/foo’, ‘/WEb-iNf/foo’, for example, should not result in contents of the web application located under /WEB-INF being returned, nor any form of directory listing thereof.”

Still no mention of the TLD (tag library descriptor), although we now know that the WEB-INF directory is meant to be a secure place for application developers to place code without worrying about it being exposed to client requests.

So then you have to download JavaServer PagesTM 1.2 Specifications, page 112 of 268 says:

“Tag library descriptor files have names that use the extension “.tld”, and the extension indicates a tag library descriptor file. When deployed inside a JAR file, the tag library descriptor files must be in the META-INF directory, or a subdirectory of it. When deployed directly into a web application, the tag library descriptor files must always be in the WEB-INF directory, or some subdirectory of it.”

Ah, so according to the JSP Spec, we have to deploy the .tld file inside WEB-INF. But how are we supposed to reference the taglib once we have it deployed? Page 116 answers that:

“The explicit web.xml map provides a explicit description of the tag libraries that are being used in a web application. The implicit map from TLDs means that a JAR file implementing a tag library can be dropped in and used immediatedly through its stable URIs. The use of relative URI specifications in the taglib map enables very short names in the taglib directive. For example, if the map is:

<taglib>
  <taglib-uri>/myPRlibrary</taglib-uri>
  <taglib-location>/WEB-INF/tlds/PRlibrary_1_4.tld</taglib-location>
</taglib>

then it can be used as:

<%@ taglib uri=”/myPRlibrary” prefix=”x” %>

Finally, the fallback rule allows a taglib directive to refer directly to the TLD. This arrangement is very convenient for quick development at the expense of less flexibility and accountability. For example, in the case above, it enables:

<%@ taglib uri=”/WEB-INF/tlds/PRlibrary_1_4.tld” prefix=”x” %>”

Fun for the whole family! Let’s all go and try to use our taglibs now!

Manipulate expressions with the new features of java.lang.String

From builder.com: “Manipulate expressions with the new features of java.lang.String”

“The Java String class has remained largely unchanged since JDK 1.0,
receiving only a minor addition of new methods with JDK 1.2. However, there
have been some major additions in JDK 1.4.

Regular expressions have arrived with much fanfare in JDK 1.4, but the
melding of the java.lang.String class to the java.util.regexp package has
been less talked about. Four new regexp-based methods have arrived, with
their various overloads, to help enhance the String class.

The String.matches(String) method returns true if the current String
matches a given regular expression. For example:

“Music”.matches(“M.*”) returns true while
“Noise”.matches(“M.*”) returns false.

The String.replaceFirst(String, String) method replaces the first
instance of a regular expression with a replacement value and returns the
new
version of the String. For example:

“Small angry, angry kittens”.replaceFirst(“angry”, “fluffy”)

will give us:

“Small fluffy, angry kittens”.

We also have the replaceAll method, which is exactly the same except
that it will replace all the values. So we get:

“Small fluffy, fluffy kittens”.

The first argument to a replace method is a regular expression, while
the second argument is the replacement value. This replacement value may
contain references to captured values.

Lastly, we have the String.split(String) method, which turns a String
into an array of Strings, based on a common delimiter. The following code
shows how to split a line of comma-separated values:

String csv = “one,two, three,four, five”;
String[] fields = csv.split(“,\s*”);

The argument may be a regular expression, which allows the code in this
instance to ignore the white space characters.

The addition of regular expressions to Java is a long-awaited affair,
but the new helper methods in java.lang.String are an added bonus that
should reduce the regular expression learning curve.”

Object finalization and cleanup

Object finalization and cleanup: How to design classes for proper object cleanup

“…By now you may be getting the feeling that you don’t have much use for finalizers. While it is likely that most of the classes you design won’t include a finalizer, there are some reasons to use finalizers.

One reasonable, though rare, application for a finalizer is to free memory allocated by native methods. If an object invokes a native method that allocates memory (perhaps a C function that calls malloc()), that object’s finalizer could invoke a native method that frees that memory (calls free()). In this situation, you would be using the finalizer to free up memory allocated on behalf of an object — memory that will not be automatically reclaimed by the garbage collector.

Another, more common, use of finalizers is to provide a fallback mechanism for releasing non-memory finite resources such as file handles or sockets. As mentioned previously, you shouldn’t rely on finalizers for releasing finite non-memory resources. Instead, you should provide a method that will release the resource. But you may also wish to include a finalizer that checks to make sure the resource has already been released, and if it hasn’t, that goes ahead and releases it. Such a finalizer guards against (and hopefully will not encourage) sloppy use of your class. If a client programmer forgets to invoke the method you provided to release the resource, the finalizer will release the resource if the object is ever garbage collected.”

Abstract classes vs. interfaces: When does it make sense to choose an abstract class over an interface?

Abstract classes vs. interfaces: When does it make sense to choose an abstract class over an interface? [source: javaworld]

“Abstract classes let you define some behaviors; they force your subclasses to provide others. For example, if you have an application framework, an abstract class may provide default services such as event and message handling. Those services allow your application to plug in to your application framework. However, there is some application-specific functionality that only your application can perform. Such functionality might include startup and shutdown tasks, which are often application-dependent. So instead of trying to define that behavior itself, the abstract base class can declare abstract shutdown and startup methods. The base class knows that it needs those methods, but an abstract class lets your class admit that it doesn’t know how to perform those actions; it only knows that it must initiate the actions. When it is time to start up, the abstract class can call the startup method. When the base class calls this method, Java calls the method defined by the child class.”