Monday, May 17, 2010

Java Security Packages JCA/JCE

In this tutorial, the author explains the cryptography-related concepts and packages in JDK, with code examples. Many of the concepts and technical terms thus learnt will be useful in understanding the Cryptography API in MFC also.

There are three security-related packages in JDK1.4, as follows:

1.  JCA/JCE (Java Cryptography Architecture & Java Cryptography Extensions)

2.  JSSE( Java Secure-Sockets Extension).

3.  JAAS( Java Authentication & Auhorization Service)

( Prior to JDK1.4, many of these packages were not available within the JDK and had to be separately installed and used. But, JDK1.4 has incorporated all these within JDK itself).

Understanding the terminology of these important packages requires that we have some familiarity with the technical terms used in the field of Network Security. We can begin by saying that secure communication ,should ensure the following.
  •  Integrity
  •  Confidentiality
  •  Authentication
  •  Non-repudiation
[ There is also another requirement (ie). Authorization and it is more to protect resources and programs from users, than with communicating the data. JAAS deals with that].

These are all standard terms used in Security. When a person, say, Sam, wants to send some information to Tom, it must be ensured that the information thus sent, is not tampered with or altered on the way. This is known as Data Integrity.

Secondly, the information is meant only for Tom and so no one else should be able to understand the message. This is known as Confidentiality. There should be some indication that the message came from Sam and there should be some proof for that. This is Identification. Authentication, that the message came from Sam is provided by Digital Signature. There should preferably be a trusted third party to vouchsafe for the identity and signature of Sam. This is achieved by Digital Certificate, which authenticates the signature of Sam. Besides these, sometimes it is equally important that Sam should not be able to say later that he did not send the message to Tom and the message was actually sent by someone else ,in his name. This is ensuring Non-repudiation. This purpose also is served by Digital signature. We will now see step-by-step development of these concepts. Except 'Authorization', other things can be understood in the context of everyday exchange of information.

Confidentiality is achieved by using Cryptography techniques. For the sake of simple illustration, let us assume that Sam wants to send a message to Tom.( By convention, two persons Alice & Bob are chosen for illustration, because the original thesis made use of these names. Let us use Sam and Tom instead). Sam does not want his message to be understood by anybody else except Tom. So, he encrypts it. When Tom receives the encrypted message, he 'decrypts' it, so that he can read the original message. The original message is known as 'plaintext'. After Encryption, it becomes 'cipher text'. The process of converting the cipher text into the original plaintext is known as Decryption. A 'key' is used for controlling Encryption and Decryption.

There are two types of key-based encryption algorithms, namely, Symmetric algorithm and Asymmetric Algorithm.


I ).  Symmetric Algorithm: This algorithm uses the same key for encryption and decryption. This is also known as 'Secret key'.

In this scheme, when Sam wants to send a message to Tom, he encrypts the message by the mutually agreed secret-key and then sends the cipher text to Tom. Tom uses the same secret key and decrypts the message and reads it.

Symmetric key system is faster than the Asymmetric system but the problem of agreeing on mutual secret key and preserving the secrecy of the key while communicating it over the network, led to the development of Asymmetric key systems.

Some of the Symmetric key Algorithms are as follows: (Most of them are implemented in JCA/JCE).

1.  DES( Data-Encryption-Standard).. developed in 1970 and recommended by US government. Though it is not fool-proof, it is considered to be sufficiently safe and is in wide use.

It has different modes of operation.
  • Electronic Cook book ( ECB)
  • Cipher Block Chaining ( CBC)
  • Output Feedback Mode (OFB)
  • Cipher Feedback Mode ( CFB)
2. ) Triple DES( also known as DESede) ..

An improved and very safe method of DES.

3. ) IDEA (International Data Encryption Algorithm). This is used in PGP ( Pretty-Good-Privacy method of secure Email).

An important advantage of Secret-key algorithm is that a hardware-approach is possible. This results in very high speed encryption. The hardware implementation by a VLSI chip can be about 20 times faster than the corresponding software implementation! IDEA has been implemented in hardware.

4. ) Blowfish...This algorithm was designed by Bruce Schneier. It is not patented and he has placed the implementation in public domain.

5. ) There is also a method known as Password-Based Encryption (PBE). We will have a brief description of this method ,with code example, shortly.

Ready-made implementations for many of these algorithms are available in SunJCA/JCE and the programmer just chooses the desired algorithm and uses it. No deep knowledge of the mathematical theory of the algorithms or how these algorithms are implemented ,is required .Such topics are highly mathematical and are dealt with in books on Cryptography .

II ). Asymmetric Algorithms

This algorithm is also known as 'Public Key' algorithm. There are two keys in this scheme. One key is known as 'public key' and the other key is known as 'private key'.( It should be noted that 'secret key' does not mean 'private key'.)

The basic theory of Public key Cryptography was developed by two research workers at Stanford University Diffie & Hellman in 1976. The DH algorithm is known as Key-Agreement method. RSA algorithm is an implementation , named after the initials of the three academics who invented it. ( Rivest, Shamir & Adleman). RSA is the defacto standard. Another Asymmetric algorithm is DSA ( Digital Signature Algorithm). Yet another algorithm is known as ECC (Elliptic-Curve Cryptography). It is reputed to be very efficient and fast.
[ However, SunJCA/JCE does not provide ready-made implementation for ECC.]

The public key and private key are known as 'keypair'. The public key and private key are mathematically related in the sense that if a message is encrypted by using a particular public key, it can be decrypted by the corresponding private key and vice-versa (ie) the data can also be encrypted by using a private key and can be decrypted by the corresponding public key, and not by any other public key. But the problem is that any person who knows Sam's public key can decrypt the message. So, RSA system uses public key of the recipient to encrypt the data.( But, the private key cannot be derived from public key. Similarly, the public key cannot be derived from private key).

RSA method is the most widely used scheme. When Sam wants to send a secret message to Tom, he should know the public key of Tom to begin with.( Just as we should know the mail-id of our friend first, if we want to send email to him). Sam encrypts the message by using Tom's public key and sends it to Tom. At the receiving end, Tom uses his (Tom's) private key and decrypts the letter and reads it. The advantage of this scheme is that it ensures that only Tom will be able to read the message, as only his private-key can decrypt the message encrypted with his public key. A person's private key need never be known to anyone else and there is no sharing the key with another person. Only the public key needs to be informed to others. ( like the difference in sharing our mail-id and sharing our password!). Thus key-administration problem is less.

Digital Signature & Message Digest

The Asymmetric system has another use as well. It can be used for creating the Digital Signature, to ensure that the message came from Sam. Though the message itself can be signed without creating a digest, the usual method is to sign the message digest, so that Integrity of data also can be ensured.

A 'Message Digest' is a digital fingerprint. It is often referred to simply as a digest ( summary) or hash. It is an one-way process ( ie) it is impossible to reconstruct the original from the hash.

MD5(MessageDigest-5) and SHA-1( Secure Hash Algorithm) are two examples of such Digesting algorithms. These two are provided in Sun security package.MD5 accepts some input and produces a 128-bit message digest. SHA-1 is more secure and produces a 160-bit message digest.

When Sam wants to send a secure message, he passes the message through a Message Digest engine. The result is a hash.

He then encrypts the hash by using Sam's private key.( This encryption is done on the hash and not on the data). Thus we get the Digital Signature.

Finally, Sam encrypts the original message using Tom's Public key. After this, Sam sends the package to Tom.

At the receiving end, Tom uses his (Tom's) private key to decrypt the message. By using Sam's public key, he decrypts the digital signature and so gets the original hash( hash1). Using the same one way hash algorithm on the text message, Tom creates another hash( hash2).If hash2 exactly matches hash1, it means that the data has not been altered in transit. Thus, we get assurance of Confidentiality and Data Integrity. It also ensures the identity of the sender, becuase the the hash1 was obtained by using the public key of Sam to decrypt the package.

If the public key of Sam, used by Tom, has the added assurance from a certificate authority that it really belongs to Sam, this is a clear-cut method with no problems except that it is not suitable if the message being encrypted is of large size. Besides satisfying the requirements of Authentication, Confidentiality, Integrity and Non-Repudiation, we should also ensure that the process is fast, in Enterprise level. The method outlined above is slow and so may not be suitable for large messages. Otherwise, it is a satisfactory method.

(We will describe a hybrid method used for large messages, shortly).

Sometimes, it may be enough if there is Authentication and Non-Repudiation, without confidentiality. In such cases, it is enough if Sam sends the message-digest encrypted by Sam's privatekey ,along with the plaintext.

Digital Certificate
Just now , we saw that Tom made use of Sam's public key to verify his Digital Signature. How does Tom get to know the public key of Sam? Sam could have published his public key in the internet or could have sent it to Tom, personally. A person's public key can be freely published and shared and for this reason, anybody can use it , not necessarily Sam. A Digital signature of Sam can be verified only if Sam's public key is available to Tom but as it is a public key, impersonation is possible. A trusted third-party is required to certify that the said key is really Sam's public key. This is known as Digital Certificate and the authorities who issue such certifictes are Certifying Authority.

Public Key Infrastructure( PKI)
When Sam wants his public key to be certified by a CA, he generates a keypair and sends the public key to an appropriate CA with some proof of his identification.

The CA checks the identification and then after satisfying that the key has not been modified in transit, issues a certificate relating the public key of Sam with his identity, by signing the public key of Sam with the private key of the CA. The standard format of issuing the certificate is known as X509.

Who is to attest the CA themselves? The CA are self-attested.

The PKI standard has been developed by RSA Security Systems in collaboration with Industry leaders like SUN, IBM and Microsoft and is the industry standard.

Certificate-Revocation
A certificate becomes invalid after the expiry of validation period. Sometimes, the private key associated with a public key gets compromised ( ie) exposed, and in that case also, the certificate should be withdrawn( revoked). The owner of the private key also may like to change it. The CA publishes a list of such defunct certificates and Tom should verify that Sam's certificate is still valid, before important transactions.

Message-Authentication-Code ( MAC)

Digital Signature makes use of Sam's private key to sign the hash. An alternative to Digital Signature is to use a secret key to encrypt the hash. By its very definition, secret key is common to both Sam & Tom. So Tom can use the secret key at his end and get back the hash. The code thus generated by mixing the hash and the secret key is known as MAC. Digital Signature is better than MAC because it does not need any 'secret' key. In the context of E-Commerce, where there are thousands of parties , secret key administration is always very difficult.

The scheme outlined above is suitable for most purposes. However, for very large amounts of data, encryption and decryption of data by public-key systems becomes time consuming and requires large resources. In such cases, it is preferred to use Symmetric Encryption systems with some modifications. Hybrid Systems make use of Asymmetric method for agreeing upon a secret key and the actual encryption and decryption of data is done by this secret key. Some such method is the usual Industrial practice. The Secret key used here is valid only for a particular instance of transmission of message and so is usually called 'session-key'. ( This is not the 'session' as usually understood in servlates, because this is an one-time operation).

Digital Envelope

An illustration of Hybrid method is a Digital Envelope. In this scheme, Sam encrypts the message by a random Secret key, ( known as DEK i.e. Data-Encryption-key or session key). Next Sam encrypts this session key with Tom's public key. At this stage, Sam sends both the encrypted message and the encrypted session key to Tom.

At the receiving end, Tom uses his private key to get the session key. Using this session key, Tom decrypts the message. As Symmetric method is about 1000 times faster than Asymmetric method , this is a good combination. Though public key method also has been used here, it is only for encrypting the session key and not the message. This can be further improved by creating a hash of the message and signing it. Also, there is no permanent Secret key between Sam & Tom, and the required secret key is produced just as required and then discarded after the job. Thus, the method is fast and secure.

With this background information, let us now see some simple code examples, specific to JDK.

There are a number of Cryptographic Engines in Sun JCA & Sun JCE. They are listed below.

It will be immediately evident that the names will be Greek & Latin to us , unless we have a background in Crypto terminology. That is why, a broad outline was given. The function of some of the engines will be evident from the earlier discussion. A few more of the remaining items will be clear when we deal with code examples.

Cryptographic Engines
  •  Key Generator ( symmetric)
    (Blowfish, DES, Triple DES, HmacMD5, HmacSHA1,RC5)
  •  Key Pair Generator ( asymmetric)
    (Diffie Hellman, DSA, RSA)
  •  Mac ( message authentication code)
    ( HmacMD5, HmacSHA1)
  •  Message Digest
    (MD5, SHA1)
  • Signature
    ( MD5withRSA, SHA1withRSA, SHA1withDSA)
  • Cipher
    ( Blowfish, DES, Triple DES etc)
  • Certificate Factory
    ( X509)
  • Key Agreement
    ( Diffie Hellman)
  • Key Factory
  • Secret Key Factory
  • Secure Random
    ( SHA1PRNG) (ie)
    ( SHA1 ..pseudo-random-number-generator)
  • Trust Manager Factory
  • Key Manager Factory
  • Key Sore
    ( JKS, PHCS12)
  • SSL Context
  • Algorithm Parameter Generator
  • Algorithm Parameters
Let us now see a series of code-examples to get familiarity with some of the above engines. For all the examples, we are using JDK1.4.2. Our working directory is g:\securitydemos. CD to g:\securitydemos

We should set path as : c:\windows\command;d:\jdk1.4.2\bin

The easiest to understand is the Message Digest. "demo1.java" creates the message digest of the string s1, by SHA method (Secure Hash Algorithm) . The given string is first converted into a byte array, because the function md. digest(), accepts only a bytearray. md. update() simply adds the array to existing arrays, if any. The digest object thus created is simply saved as object to the file.

// demo1.java 
// creation of message-digest
// storing the string & digest in file
import java.io.*;
import java.security.*;

class demo1 {
   public static void main(String args[]) {
     try { 
       MessageDigest md = MessageDigest.getInstance("SHA"); 
       String s1 = " we are learning java";
       byte[] array = s1.getBytes();
       md.update(array);
       FileOutputStream fos = new FileOutputStream("demo1test");
       ObjectOutputStream oos = new ObjectOutputStream(fos);
       oos.writeObject(s1);
       oos.writeObject(md.digest ());
       System.out.println(" digest ready!");
     }catch(Exception e1) {
       System.out.println(""+e1);
     }
   }
}

In demo2.java, we learn how a given messagedigest can be used for checking up for Integrity of data. We begin by getting the original string as well as the existing hash. Next we create another hash of the original string by the same algorithm to get hash2. Then, we compare hash1 with hash2. If they are not equal, we get the message "corrupted". From these examples, it will be appreciated how much the Java API shields the programmer from the inner workings of the highly mathematical theory of Cryptology.

----------------------------------------

// demo2.java
// getting a string and digest from file
// creating a hash and verifying the digest
import java.io.*;
import java.security.*;
class demo2 {
  public static void main(String args[]){
    try {
       FileInputStream fis = new FileInputStream("demo1test");
       ObjectInputStream ois = new ObjectInputStream(fis);
       Object ob1 = ois.readObject();
       String s1 = (String) ob1;
 
       System.out.println(s1);

       Object ob2 = ois.readObject();
       byte[] array1= (byte[]) ob2;
       MessageDigest md = MessageDigestgetInstance("SHA");
       md.update(s1.getBytes());
       if(MessageDigest.isEqual(md.digest(), array1)) {
         System.out.println("valid"); 
       }else{          System.out.println("corrupted");
       }
    } catch(Exception e1){
       System.out.println(""+e1);
    }
  }
}

In the third example(demo3.java) , we see how a secret key is created by the DES algorithm. Cipher class is the Encryption and Decryption engine.After initialising the Cipher engine for encrypting mode, we

give the command ci.doFinal(). This creates the encrypted message of the specified string. We should also get the initvector, by the command ci.getIV().

To avoid writing a separate example, we illustrate the process of decrypting also here, in the next stage. We get the initvector and then define the cipher for decrypt mode. After this , ci.doFinal(), does the decryption.

// demo3.java
// creation of secret key
// encryption using secret key
// decryption using secret key

import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
class demo3 {
   public static void main(String args[]) {
     try {
       KeyGenerator kg = KeyGenerator.getInstance("DES");
       // DES= Data Encryption Standard
       Key key = kg.generateKey();
       Cipher ci = Cipher.getInstance("DES/CBC/PKCS5Padding");
       ci.init(Cipher.ENCRYPT_MODE, key);
       String s ="we are learning Java";
       byte[] array1 = s.getBytes();
       byte[] array2 = ci.doFinal(array1);
       byte[] initvector = ci.getIV();
       System.out.println ("string has been encrypted");
       System.out.println ("we are now decrypting");
       IvParameterSpec spec = new IvParameterSpec(initvector);
       ci.init (Cipher.DECRYPT_MODE, key, spec);
       byte[] array3 = ci.doFinal(array2);
       String s2 = new String(array3);
       System.out.println(s2);
    }catch(Exception e1){
       System.out.println(""+e1);
    }
  }
}


The following program displays information about the Providers available in JDK.

// demo4.java
import java.security.*;
import java.util.*;
class demo4 {
   public static void main(String args[]) {
     try {
       Provider[] array = Security.getProviders();
       int n = array.length;
       for(int j=0; j
         System.out.println(array[j]);
         for(Enumeration e=array[j].keys(); e.hasMoreElements();) {
           System.out.println("\t"+e.nextElement());
         }
       }
     } catch(Exception e1) {
       System.out.println(""+e1);
     }
  }
}

When we execute the program, we get a long list We can run the program as:

>java demo4 > list.txt

and then inspect list.txt

In demo5 , we create a privatekey/publickey pair, by using

the DSA( Digital Signature Algorithm).

The Key Pair Generator class is used for that, by specifying a pseudo-random number. The key pair is easily generated by the command, kpg.genKeyPair(). After this we get get the public key and private key. Next we specify the Signature algorithm as Secure Hash DSA. After initializing the sig with the private key, we create the byte array for the string to be signed and ask the sig to sign that array [sig. sign();]

Now the data string has been signed by the sender's private key. In the next section, we have loaded sig with the public key and used the command to verify with the original array.. This will return 'true' , if the keys belong to the same pair. The code is almost self-explanatory, except for the syntax.

When we run the program demo5 , we get the following output.

G:\SECURI~1>java demo5

public & private keys ready!

the data has been signed by private key

now verifying with public key

verified & found ok

// demo5.java
// creation of public & private keys
// signing the data by private key
// verifying the data by public key

import java.security.*;
import javax.crypto.*;
class demo5 {
   public static void main(String args[]) {
     try {
       SecureRandom sr = new SecureRandom();
       byte[] pr =new byte[100];
       sr.nextBytes(pr);
       KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
       kpg.initialize(512,sr);
       KeyPair kp = kpg.genKeyPair();
       PublicKey pubkey = kp.getPublic();
       PrivateKey prikey = kp.getPrivate();
       System.out.println ("public & private keys ready!");
       Signature sig = Signature.getInstance("SHA1withDSA");
       sig.initSign(prikey);
       String s1 = "we are learning Java";
       byte[] array1= s1.getBytes();
       update(array1);
       byte[] array2 = sig.sign();
       System.out.println ("the data signed by private key");
       System.out.println ("now verifying with public key");
       sig.initVerify(pubkey);
       sig.update(array1);
       boolean ok = sig.verify(array2);
       if(ok==true){
          System.out.println("authentic..ok");        } else{
          System.out.println("not authentic");
       }
   } catch(Exception e1){
       System.out.println(""+e1);
   }
}

We will conclude this tutorial with an illustration for Password-based secret key.

Users are supposed to remember their password, easily. If a secret key can be generated based on the password, it will be easier to generate. Users can then generate such a secret key and use it to encrypt and decrypt their files. The algorithm uses a 'salt' and an integer number for iteration. The paramspec is created using these two values. The Cipher engine for PBEWithMD5AndDES( PBE=Password-based-encryption, MD5=MessageDigest-5 &DES=Data Encryption Standard) is then created. The program asks for a password and then the string to be encrypted. A secret key based on the password supplied is generated and used to encrypt the data.

Just for illustration, the program asks for the password again. When we type it correctly, the secret key is again generated and used to decrypt the encrypted data. Finally, the original string is printed.

The output of demo6 is shown below.

( system prompt & output in bold)

G:\SECURI~1>java demo6

enter the password

abcd1234

enter the string to be encrypted

we are studying java cryptography

encryption over

now decrypting

enter the password again!

abcd1234

we are studying java cryptography

// demo6.java
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.io.*;

class demo6 {
   public static void main(String args[]) {
     String salt="saltings";
     int n = 20; // iterations
     byte[] a = salt.getBytes();
     PBEParameterSpec paramspec= new PBEParameterSpec (a,n);
     try {
       Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");
       DataInputStream ins = new DataInputStream(System.in);

       System.out.println ("enter the password");
       String s1=ins.readLine();
       System.out.println("enter the datastring");
       String s2=ins.readLine();
       byte[] array1 = s2.getBytes();
       PBEKeySpec keyspec = new PBEKeySpec(s1.toCharArray());
       SecretKeyFactory factory= SecretKeyFactory.getInstance ("PBEWithMD5AndDES");
       SecretKey key = factory.generateSecret(keyspec);
       cipher.init (Cipher.ENCRYPT_MODE, key, paramspec);
       byte[] array2 = cipher.doFinal(array1);
       System.out.println("encryption over");
       System.out.println("now decrypting");
       System.out.println ("enter the password again!");
       String s3=ins.readLine();
       keyspec = new PBEKeySpec(s3.toCharArray());
       factory= SecretKeyFactory.getInstance("PBEWithMD5AndDES");
       key = factory.generateSecret(keyspec);
       cipher.init (Cipher.DECRYPT_MODE, key, paramspec);
       byte[] array3 = cipher.doFinal(array2);
       String s4=new String(array3);
       System.out.println(s4);
     } catch(Exception e1){
       System.out.println(""+e1);
     }
   }
}

That completes our introductory tutorial

on JCA/JCE. All the above programs have been tested and are working correctly. Students are encouraged to follow this up with the reference material mentioned below:

RERFERENCE BOOKS
  • Mastering Java Security
    (Cryptography, Algorithms & Architecture) by Rich Helton & Johennie Helton ( Wiley/ DreamTech)
  • Professional Java JDK 5 edition. Clay Richardson & others ( chapter- ) Wrox/Wiley/DreamTech
  • Java Security by Scott Oaks ( of SUN MICRO SYSTEMS) ( SPD/OReilley)
  • Java Distributed Objects by Bill McCarty ( chapter- )
  • Professional Java Web Services by Mack Hendricks (SUN) & others chapter-6 on Security by James Millbury

Friday, May 07, 2010

Application ClassLoader’s Footprint Memory Leak in Shared Containers

(http://www.theserverside.com/news/thread.tss?thread_id=60076)
Basic Reason for the leak:
Every time an application is deployed and un-deployed in a container, the application is given its own class loader (application class loader) by the container’s class loader. This application class loader might end up creating a cyclic reference to the container’s class loader, which makes it un-garbage collectible. From my observations getting rid of the application’s class loader from memory (1 to 2 MBs) could be a very difficult and tedious task because of the amount of third party tools we use, but can be contained, although not ideal.

Avoiding the leak from Crossing Threshold:
a)      One Main Culprit : Spring Class Based Proxies
Many Enterprise applications use Spring, AOP and Hibernate as tools for their projects. With Hibernate comes the Session Factory beast in memory. The Hibernate Session Factories can become huge based on the project’s DB tables count and Hibernate Mapping Structure (150MB for the application that I work on). So when Session Factory gets attached to the un-garbage collectible Class Loader which has been left behind, we have huge memory leak in containers causing us losing valuable resources.
So how does this Session Factory get attached to the un-garbage collectible class loader?
Spring uses proxies to weave in Advices. Transactions are most commonly “AOP Advised” in Enterprise Applications using Declarative Transaction Management.
As you might know, there are 2 types of Proxies that Spring creates, based on the implementation of the class that needs to be advised
1)      Interface Based Proxies – not a problem
  1. Spring uses JDK proxies if there is an interface available for all the advised methods; this is the default type of proxy that is created. A new class is created with methods that needs to be advised, through which advises will be weaved in. A call is then delegated from the new class to the actual class that had to be advised.
2)      Class Based Proxies – A Problem
  1. Spring uses CGLIB to create proxies if an interface is not available for the existing methods that needs to be advised. This type of Proxy should be an exception in general, and it is only provided for backward compatibility for third party libraries that cannot be modified.
  2. The problem here is CGLIB’s implementation leads it to tie a hard link between the Application Class Loader and the Session Factory when it is trying to advise the method of particular transaction choice.
  3. Hence trying to avoid Class based proxies for Spring Transaction Management, in an application with an existing Class Loader leak, may avoid it from crossing the “Threshold” (2 MB to 154MB in a project that I was working on).
b)      Some Third Party Libraries:
There are some third party tools that do the same thing of attaching itself to the class loader and creating a hard link between the runtime classes that they create and the class loader itself. Some examples that I know of right away are Dozer and Apache Common’s Logging.
So it looks like there is no good way to solve the problem of Application Class Loader’s Footprint leak in a Shared Container turning out of control, hence the intent of this article is to make one aware of the issues and point them in the right direction.

PermGen Space will be affected as well
Now this leak may also cause your PermGen Space run out of memory since the meta-inf about the loaded classes may not be garbage collected.
Krank Keviet has done a pretty good job explaining the issue in one of his blogs with respect to Perm Gen Space, a reference to his blog is below.


References
http://blogs.sun.com/fkieviet/entry/classloader_leaks_the_dreaded_java
J2EE Classloaders Demystified

Classloader leaks: the dreaded "java.lang.OutOfMemoryError: PermGen space" exception

(From http://blogs.sun.com/fkieviet/entry/classloader_leaks_the_dreaded_java)


Did you ever encounter a java.lang.OutOfMemoryError: PermGen space error when you redeployed your application to an application server? Did you curse the application server, while restarting the application server, to continue with your work thinking that this is clearly a bug in the application server. Those application server developers should get their act together, shouldn't they? Well, perhaps. But perhaps it's really  your fault!
Take a look at the following example of an innocent looking servlet.
package com.stc.test;

import java.io.*;
import java.util.logging.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class MyServlet extends HttpServlet {
 protected void doGet(HttpServletRequest request, HttpServletResponse response)
 throws ServletException, IOException {
 // Log at a custom level
 Level customLevel = new Level("OOPS", 555) {};
 Logger.getLogger("test").log(customLevel, "doGet() called");
 }
}
Try to redeploy this little sample a number of times.  I bet this will eventually fail with the dreaded java.lang.OutOfMemoryError: PermGen space error. If you like to understand what's happening, read on.

The problem in a nutshell

Application servers such as Glassfish allow you to write an application (.ear, .war, etc) and deploy this application with other applications on this application server. Should you feel the need to make a change to your application, you can simply make the change in your source code, compile the source, and redeploy the application without affecting the other still running applications in the application server: you don't need to restart the application server. This mechanism works fine on Glassfish and other application servers (e.g. Java CAPS Integration Server).

The way that this works is that each application is loaded using its own classloader. Simply put, a classloader is a special class that loads .class files from jar files. When you undeploy the application, the classloader is discarded and it and all the classes that it loaded, should be garbage collected sooner or later.

Somehow, something may hold on to the classloader however, and prevent it from being garbage collected. And that's what's causing the java.lang.OutOfMemoryError: PermGen space exception.

PermGen space

What is PermGen space anyways? The memory in the Virtual Machine is divided into a number of regions. One of these regions is PermGen. It's an area of memory that is used to (among other things) load class files. The size of this memory region is fixed, i.e. it does not change when the VM is running. You can specify the size of this region with a commandline switch: -XX:MaxPermSize . The default is 64 Mb on the Sun VMs.

If there's a problem with garbage collecting classes and if you keep loading new classes, the VM will run out of space in that memory region, even if there's plenty of memory available on the heap. Setting the -Xmx parameter will not help: this parameter only specifies the size of the total heap and does not affect the size of the PermGen region.

Garbage collecting and classloaders

When you write something silly like

private void x1() {
        for (;;) {
            List c = new ArrayList();
        }
    }
you're continuously allocating objects; yet the program doesn't run out of memory: the objects that you create are garbage collected thereby freeing up space so that you can allocate another object. An object can only be garbage collected if the object is "unreachable". What this means is that there is no way to access the object from anywhere in the program. If nobody can access the object, there's no point in keeping the object, so it gets garbage collected. Let's take a look at the memory picture of the servlet example. First, let's even further simplify this example:
package com.stc.test;

import java.io.*;
import java.net.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Servlet1 extends HttpServlet {
 private static final String STATICNAME = "Simple";
 protected void doGet(HttpServletRequest request, HttpServletResponse response)
 throws ServletException, IOException {
 }
}
After loading the above servlet, the following objects are in memory (ofcourse limited to the relevant ones):

In this picture you see the objects loaded by the application classloader in yellow, and the rest in green. You see a simplified container object that holds references to the application classloader that was created just for this application, and to the servlet instance so that the container can invoke the doGet() method on it when a web request comes in. Note that the STATICNAME object is owned by the class object. Other important things to notice:

  1. Like each object, the Servlet1 instance holds a reference to its class (Servlet1.class).
  2. Each class object (e.g. Servlet1.class) holds a reference to the classloader that loaded it.
  3. Each classloader holds references to all the classes that it loaded.
The important consequence of this is that whenever an object outside of AppClassloader holds a reference to an object loaded by AppClassloader, none of the classes can be garbage collected.

To illustrate this, let's see what happens when the application gets undeployed: the Container object nullifies its references to the Servlet1 instance and to the AppClassloader object.

As you can see, none of the objects are reachable, so they all can be garbage collected. Now let's see what happens when we use the original example where we use the Level class:
package com.stc.test;

import java.io.*;
import java.net.*;
import java.util.logging.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class LeakServlet extends HttpServlet {
 private static final String STATICNAME = "This leaks!";
 private static final Level CUSTOMLEVEL = new Level("test", 550) {}; // anon class!

 protected void doGet(HttpServletRequest request, HttpServletResponse response)
 throws ServletException, IOException {
 Logger.getLogger("test").log(CUSTOMLEVEL, "doGet called");
 }
}
Note that the CUSTOMLEVEL's class is an anonymous class. That is necessary because the constructor of Level is protected. Let's take a look at the memory picture of this scenario:


In this picture you see something you may not have expected: the Level class holds a static member to all Level objects that were created. Here's the constructor of the Level class in the JDK:
protected Level(String name, int value) {
 this.name = name;
 this.value = value;
 synchronized (Level.class) {
 known.add(this);
 }
 }
Here known is a static ArrayList in the Level class. Now what happens if the application is undeployed?


Only the LeakServlet object can be garbage collected. Because of the reference to the CUSTOMLEVEL object from outside of AppClassloader, the  CUSTOMLEVEL anyonymous class objects (LeakServlet$1.class) cannot be garbage collected, and through that neither can the AppClassloader, and hence none of the classes that the AppClassloader loaded can be garbage collected.
Conclusion: any reference from outside the application to an object in the application of which the class is loaded by the application's classloader will cause a classloader leak.

More sneaky problems

I don't blame you if you didn't see the problem with the Level class: it's sneaky. Last year we had some undeployment problems in our application server. My team, in particular Edward Chou, spent some time to track them all down. Next to the problem with Level, here are some other problems Edward and I encountered. For instance, if you happen to use some of the Apache Commons BeanHelper's code: there's a static cache in that code that refers to Method objects. The Method object holds a reference to the class the Method points to. Not a problem if the Apache Commons code is loaded in your application's classloader. However, you do have a problem if this code is also present in the classpath of the application server because those classes take precedence. As a result now you have references to classes in your application from the application server's classloader... a classloader leak!

I did not mentiond yet the simplest recipe for disaster: a thread started by the application while the thread does not exit after the application is undeployed.

Detection and solution

Classloader leaks are difficult. Detecting if there's such a leak without having to deploy/undeploy a large number of times is difficult. Finding the source of a classloader leak is even trickier. This is because all the profilers that we tried at the time, did not follow links through classloaders. Therefore we resorted to writing some custom code to find the leaks from memory dump files. Since that exercise, new tools came to market in JDK 6. The next blog will outline what the easiest approach today is for tracking down a glassloader leak.  

Spring 2.5 Makes Unit Testing Easy with Annotations

(From http://www.mularien.com/blog/2007/11/07/spring-25-makes-unit-testing-easy-with-annotations/)

One feature of Spring 2.5 (previously known as Spring 2.1) that hasn’t gotten a lot of mention is its significantly enhanced unit testing framework, including the brand new org.springframework.test.context package. Rod Johnson mentioned it in his updated article on Spring 2.5 on TheServerSide, but other than that, I tried searching for someone blogging about this subject, and failed – so I figured I’d jot down my impressions about this great improvement.

Prior to Spring 2.5, Spring provided a series of superclasses that your unit tests were required to inherit. These superclasses (AbstractDependencyInjectionSpringContextTests and the like) provided dependency injection into unit tests, and autowiring by type as default behavior. For those who are unit testing transactional systems, the AbstractTransactionalDataSourceSpringContextTests base class is essential for setting up transaction management and auto-rollback around each unit test.

Spring 2.5 continues this rich and convenient testing framework, while now removing the requirement that your unit tests extend Spring framework tests. This is a welcome change, as it frees up your unit test hierarchy to allow you more flexibility in inheritance.

Instead of providing functionality through subclassing and very specific method overriding, a series of Java 5 annotations are provided to handle various aspects of test data management.

As usual, the Spring documentation has excellent coverage of this new functionality, starting with its coverage of the test context concept, provided by the @ContextConfiguration annotation, which is used in place of the legacy method override of getConfigLocations.

To wit, where before, including several ApplicationContext XML files required the following:
    @Override
    protected String[] getConfigLocations() {
    System.out.println(System.getProperty("java.class.path"));
    return new String[] { "classpath:applicationContext.xml",
        "classpath:applicationContext-acegi.xml",
        "classpath:applicationContext-test.xml" };
    }

… with Spring 2.5 all that is required is a simple annotation at the unit test class level:
 @ContextConfiguration(locations = { "/applicationContext.xml",
    "/applicationContext-acegi.xml", "/applicationContext-test.xml" })

The default ContextLoader will automatically find these resources on the classpath.

Similar simplicity is provided in the realm of transactional support and DI. In prior versions of Spring, the superclass hierarchy dictated whether or not transactional and DI support was provided. In Spring 2.5, the default ContextLoader will also auto-wire dependencies in the test class, annotated via the typical @Autowired (by type) or @Resource (by name) methods.

For transaction management, the standard Spring @Transactional annotation is supported, to wrap transactions around unit test methods (and rolling back after method completion, as Spring 2.0 used to do). Spring 2.5 provides a couple additional annotations to further specify transactional behavior within a unit test, including the @NotTransactional annotation (for methods not requiring one), and the @Rollback annotation, which can be used to override the default auto-rollback behavior.

Finally, since you’re no longer extending a base class, you can’t override the onSetUp*Transaction and onTearDown*Transaction methods, like in Matt Raible’s example from way back when (among many others).

Instead, the standard JUnit 4 @Before and @After annotations are used in place of onSetUpInTransaction and onTearDownInTransaction. An obvious benefit is the fact that you can annotate multiple methods with these annotations, instead of the single method that was imposed by the override-based implementation. Spring-specific @BeforeTransaction and @AfterTransaction annotations are used to replace the onSetUpBeforeTransaction and onTearDownAfterTransaction methods.

There’s some additional annotations that allow for test timeout measurement (above and beyond what JUnit 4 provides), test repeating, and a few other goodies.

I tested this on a couple existing Spring projects that I’ve worked on, and the transition process was extremely smooth, and allowed me to greatly simplify the unit testing code by stripping out the stuff that used to be required by the Spring class-based unit testing framework.

Unfortunately, although Spring provides some support for TestNG, out of the box it will still require inheriting a [new] Spring 2.5 class, AbstractTransactionalTestNGSpringContextTests. Hopefully Cedric and Alexandru can work with the Spring team to enhance this support to match (or exceed!) the level of support offered to JUnit 4 users.

Spring 2.5 will be released soon, and I bet a lot of users will be buzzing about the unit test enhancements there. Enjoy!

PropertyPlaceholderConfigurer in Spring 2.5

(From http://www.mularien.com/blog/2007/11/13/quick-tip-spring-25-makes-use-of-propertyplaceholderconfigurer-simpler/)
While not explicitly highlighted in the Spring 2.5 “What’s New” section, this is a nice little bit to remove a few lines of XML. Spring 2.5 (with the introduction of a new “context:” namespace) takes the common use of a PropertyPlaceholderConfigurer externalizing properties and folds it from the awkward 5-line syntax into a single line.

Before (Spring 2.0 and earlier):
<bean id="propertyConfigurer"
   class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
 <property name="location">
  <value>file:${user.home}/env.properties</value>
 </property>
</bean>

After (Spring 2.5):
<context:property-placeholder location="file:${user.home}/env.properties"/>

The nit-picky will note that you will need to add in the spring-context-2.5.xsd schema reference, however you may be using that already anyway in Spring 2.5 to take advantage of some of the Java-based annotation functionality.

Tuesday, April 27, 2010

Spring Batch - ItemReader and ItemWriter configuration

How to read a record to a object
ItemReader will utilize LineMapper, LineTokenizer and FieldSetMapper to get a Object.
LineMapper: DefaultLineMapper, PattermMatchingCompositeLineMapper
LineTokenizer: DelimitedLineTokenizer, FixedLengthTokenizer, PattermMatchingCompositeLineTokenizer
FieldSetMapper: BeanWrapperFieldSetMapper
Configuration Hierarchy:
<ItemReader>
  <LineMapper>
    <LineTokenizer/>
    <FieldMapper/>
  </LineMapper>
<ItemReader/>

Multiple record type with single file

It is very common that a file might have records with different formats that need to be tokenized differently and mapped to different objects.

USER;Smith;Peter;;T;20014539;F
LINEA;1044391041ABC037.49G201XX1383.12H
LINEB;2134776319DEF422.99M005LI

The PatternMatchingCompositeLineMapper makes this easy by allowing maps of patterns to LineTokenizers and patterns to FieldSetMappers to be configured:



<bean id="orderFileLineMapper" class="org.spr...PatternMatchingCompositeLineMapper">
  <property name="tokenizers">
    <map>
      <entry key="USER*" value-ref="userTokenizer" />
      <entry key="LINEA*" value-ref="lineATokenizer" />
      <entry key="LINEB*" value-ref="lineBTokenizer" />
    </map>
  </property>
  <property name="fieldSetMappers">
    <map>
      <entry key="USER*" value-ref="userFieldSetMapper" />
      <entry key="LINE*" value-ref="lineFieldSetMapper" />
    </map>
  </property>
</bean>


How to write a file
The ItemWriter will leverage the LineAggregator and FieldExtractor to write out the data to file.
LineAggregator: PassThroughLineAggregator, DelimitedLineAggregator
FieldExtractor: BeanWrapperFieldExtractor


Configuration Hierarchy:
<ItemWriter>
  <LineAggregator>
    <FieldExtractor/>
  </LineAggregator>
<ItemWriter/>

Monday, April 05, 2010

How to pass filename to FlatFileItemReader with JobParameters in Spring Batch?



 The follow config was tested and succeeded on Spring Batch 2.0.4.
<bean id="flatFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step">
  <property name="resource"  value="file:#{jobParameters['input.file.name']}" />
  <property name="lineMapper" ref="lineMapper"/>
</bean>



Java code:

try {
//launcher.run(job, new JobParameters());
JobParametersBuilder jpBuilder = new   JobParametersBuilder().addString("input.file.name", "files/input/test.txt");

 jpBuilder.addString("output.file.name", "files/output/"+System.currentTimeMillis()+"_test.txt");
launcher.run(job, jpBuilder.toJobParameters());
} catch (Exception e) {
e.printStackTrace();
}


Another config used FileSystemResource for resource likes the follow.

<property name="resource">
   <bean class="org.springframework.core.io.FileSystemResource" scope="step" autowire-candidate="false">
     <constructor-arg value="#{jobParameters['input.file.name']}" />
   </bean>
</property>



For ItemWriter, the configuration almost same.
NOTE:
The 'file:' is mandatory if the resource is a file needed to be load from specified path.
The  scope="step" is very important. It seems the file cannot be found if it is missed.
From the reference, I found 'Any bean that uses late-binding must be declared with scope="step".'.


The follow code is is used by SpringBatch 1.x.
Just like the reference metioned, you need to define a listener for step to the proxy to have the access to the StepExecution.

<property name="listeners">
  <list>
    <ref bean="inputFile" />
  </list>
</property>

<bean id="inputFile" class="org.springframework.batch.core.resource.StepExecutionResourceProxy">

  <property name="filePattern" value="file://%file.name%"/>
</bean>

<bean id="myFileItemReader" class="org.springframework.batch.item.file.FlatFil eItemReader">
  <property name="resource" ref="inputFile" />
</bean>


Java Code:

JobParametersBuilder builder = new JobParametersBuilder();
builder.addString("file.name", "files/input/test.txt");

JobExecution jobExecution = getJobLauncher().run(getJob(), builder.toJobParameters());

Wednesday, March 24, 2010

The Benefits of Java EE5

http://www.theserverside.com/news/1363899/The-Benefits-of-Java-EE5

From its inception more than a decade ago, the Java platform has matured considerably making it the preferred choice of many professionals & organizations for developing applications. In its most recent version for the enterprise -- dubbed Java EE 5 -- its designers have placed a special emphasis on doing more with less, so whether you're a seasoned expert or just starting out, it's likely you will find some fresh approaches that will simplify and ease your development efforts – this article takes a closer look.

Annotations : Meta data & Descriptors

POJO input validation
Java EE 5 Pre Java EE 5
public class User {
    private String password;

    @MinLength(5)
    @MaxLength(20)
    public void setPassword(String password) {
        this.password = password;
    }

    public String getPassword() {
        return password;
    }

}
public class User {
  private String password;

  public void setPassword(String password) throws Exception {
    if ((newPassword != null) && (newPassword.length() > 20))
      throw new Exception();
    this.password = password;
  }

   public String getPassword() {
        return password;
    }

}
Meta data is a powerful programming concept, one which allows developers to specify or alter application code behavior outside of the actual programming logic. In prior Java enterprise versions, this was achieved through XML files known as deployment descriptors; however, while this allowed for such behavioral customizations, it forced even the simplest applications to fulfill such a requirement whether they needed meta data or not.
In Java EE 5, meta data can now be embedded directly in application code -- a process known as attribute programming. What was once required to be specified in additional XML descriptors can now be accomplished with in-line declarations, providing a more streamlined development process -- users of an open source Java project named XDoclet can probably relate to this concept.
This is not to say XML descriptors are obsolete in Java EE 5, they are still very much valid. As a matter of fact, XML descriptors provide a secondary and overriding mechanism to any meta data that might have been declared within application code. In other words, a Java EE 5 application server will automatically take any behavior properties declared in a deployment descriptor over those embedded in Java byte-code.
It should be pointed out that attribute programming is not an exclusive addition to Java EE 5, but rather part of the Java standard edition 5(J2SE), an enhancement which cannot be underestimated, not only because standard support for attribute programming marks a shift in Java as a whole, but also because many other areas pertaining to Java EE 5 -- not just deployment descriptors -- can be enhanced using this same principle.
Annotations are very much open ended in terms of the functionality they can offer, making them ideal for pre-packaging any type of Java logic that might have been considered tedious in earlier Java enterprise versions. To cite a concrete example, let's take the case of data validation. In prior Java versions, data validation either entailed a substantial amount of scaffolding code or an ad-hoc framework -- say Struts -- to validate input. In Java EE 5, we can make use of Java annotations so our POJO's look something like the following listing.
Use of Entity API with O/R annotations
@Entity(access=AccessType.FIELD)
public class AddressBook {
   @Id(generate=GeneratorType.AUTO) long pk;
   @ManyToOne Owner own;
   @OneToMany(cascade=CascadeType.PERSIST) Set entries =
       new HashSet();
   Date enteredDate;

   protected AddressBook() {  }
   public AddressBook(Owner own) { this.own = own; }
   public void addEntry(Entry entry) { entries.add(entry); }
   public Set getEntries() { return entries; }
   public Owner getOwner() { return own; }
   public void enteredAddressBook() { enteredDate = new Date(); }
   }
Each of the previous annotations represents a particular behavior in an O/R design, with the backing logic and relational data bridging being executed by a Java EE 5 compliant application server, which in turn, allows organizations to choose among best-of-breed implementations based on a common standard, a point that can be especially important to those who have dealt with the fragmented/proprietary syntax used by commercial O/R vendors -- like Coco base -- and open source projects such as Hibernate.
Continuing with our discussion on the persistence API for EJB 3.0, another functionality that was factored into its design was the capacity to operate outside the context of Java EE containers, in effect creating a general purpose persistence API usable in standard Java environments(J2SE). As a matter of fact, it is a confirmed possibility by Sun that this same persistence API will be spun out of EJB 3.0 into its own working group/JSR. But let's not stray too far away from our main theme on Java EE 5.
Turning back to the previous code listing, you may have noticed we were dealing with a POJO, which is another addition to working with the whole gamut of components in EJB 3.0 -- not just entities, but also the new incarnations for session beans and messaging beans. Among the main advantages of using POJO's in Java EE 5, are two factors which go hand in hand: testing and simplicity.
Once relegated to the biggest enterprise projects, testing has become an integral part of the software development process with the popularity of agile principles; however, in the pre-3.0 EJB model, this process proved to be an elaborate endeavor at best. The reasons behind this complexity lied in both the container based environment required to execute EJB's and the inheritance hierarchy imposed by earlier versions.
With a container needed to manage middleware services inherent to EJB's -- such as transactions and security -- this required the replication and bootstrapping of a similar container to test the business logic behind an underlying EJB. And even though the use of such a testing container was technically feasible, what proved to be an even more difficult task was the actual creation of tests for a given EJB. This was due to the close-knit design around such container services enforced through an inheritance hierarchy.
In the pre-3.0 EJB world, every design was required to inherit behavior from an EJB base class to wire up middleware services. In Java EE 5 this requirement has been lifted, allowing the use of POJO's to be enabled as EJB's and in this same process ease the creation of tests, achieving a very clean separation between the middleware service required for EJB's and the actual business logic behind them. Take a look at the following listing which illustrates an EJB 3.0 session bean.
Session bean POJO in EJB 3.0
@Stateless
public class RateCalculator  {


  public int add(int a, int b) {
    return a + b;
  }

  public int subtract(int a, int b) {
    return a - b;
  }

  public int multiply(int a, int b) {
    return a * b;
  }

  public int divide(int a, int b) {
    return a / b;
  }
}
Notice how we use an annotation to wire up the EJB, but more importantly, how all of its methods are structured as a POJO, making the code testing process a simple step in the development life-cycle, and one which does not require intricate knowledge in setting up ancillary dependencies which were the norm in pre-3.0 EJB.
Java EE 5 -- just like its predecessors -- also has another major part in its architecture, one related to technologies on the web tier.

Web Tier : JSF and Co.

The web tier in Java EE 5 has not changed as radically as its EJB counterpart from earlier versions, but there are a few issues worth mentioning, such as the formal incorporation of Java Server Faces(JSF) into the Java enterprise mix.
Created as a means for standardizing UI components, handling navigation, input validation and page events for web applications, JSF has had various implementations and tools circulating since early 2004, but to many in those early days, the appearance of JSF came with a sense of too little, too late or simply too late. Since JSF was neither designed to be a web framework nor a substitute for core Java web technologies -- Java Server Pages(JSP) and Servlets -- it created a certain misconception around its use, given that many developers were either just comfortable with the productivity provided by core technologies -- JSP's & Servlets -- or simply saw overlap in JSF compared to many of the Java web frameworks that appeared earlier.
With Java EE 5, JSF will officially be supported in every compliant application server, making it a powerful addition to the enterprise platform and a compelling one at that, especially with support for standardized UI components. With the appearance of web techniques like Asynchronous JavaScript and XML(AJAX), the bar for creating powerful web interfaces has only risen, so the capacity of mixing and matching pre-built UI components or Faces -- think widgets -- will probably become even more attractive to many.
Still, for those who may have worked with earlier JSF versions and experienced a certain conflict with the principles established by JSP's as a presentation technology, the version behind Java EE 5 -- JSF 1.2 / JSR 220 -- is specifically designed to align these particular issues while still remaining in-line with earlier JSF versions.
As far as other Java enterprise web technologies are concerned -- namely JSP's, Servlets and JSTL -- with the exception of a few minor additions and revisions, there are no new surprises with respect to earlier versions.
We have pretty much covered the major benefits behind Java EE 5, but we still have one more issue to address, how to actually take advantage of these features.

* Compatible Java EE 5 application servers

Like any other technology based on standards, Sun Microsystems requires that every Java EE 5 application server provider pass a series of compatibility tests in order to qualify as a certified vendor. The current list of compatible Java EE application servers include :
  • Apusic Application Server (v5.0), by Kingdee.
  • NetWeaver Application Server Java EE 5 Edition, by SAP.
  • Sun Java System Application Server Platform Edition 9, by Sun Microsystems
  • JEUS 6, by TmaxSoft
You can read more about the providers and the compatibility process at http://java.sun.com/javaee/overview/compatibility.jsp .
About the Author: Daniel Rubio is a software consultant with over 10 years of experience in enterprise software development, having recently founded Mashup Soft, a startup specializing in the use Web services for Mashups. He is a technology enthusiast in all areas related to software platforms and maintains a blog on these topics at http://webforefront.com