Thursday Oct 18, 2007

Upgrading from GlassFish V1 to GlassFish V2 and an Interesting Deployment ...

I came across this interesting use case while discussing GlassFish V1-> V2 upgrade.

As you might know, we have modified the process launcher a great deal for V2. This contributed to improved startup performance. In the process, following happened:

  1. asadmin start-domain does not invoke the domain-folder/bin/startserv script anymore.

A user was using V1 in an interesting way. The assumption was asadmin start-domain will always invoke the startserv script.

Here is how:

Consider that I have a heterogeneous environment, with various libraries being used by my application. We have a complicated build environment and we finally make sure that all the libraries needed by the application are saved at a particular location say /libraries and is captured in an environment variable AS_LIBRARIES as:

export AS_LIBRARIES=/libraries/foo.jar:/libraries/bar.jar ...

Then we modified the startserv script as: -Dmylibraries=$AS_LIBRARIES ...

and finally we modified domain.xml as:

<java-config classpath-suffix="${mylibraries}" ....

/>

Now, this was clearly a hack and worked only because of peculiar way in which GlassFish V1 treats the system properties. This is clearly an area in GlassFish that needs improvement because of its over-dependence on (evil) System Properties. Here, however, the user had employed this to his advantage! In short, what he has done was:

Invented a way to pass an environment variable on the system whose value at a given point in time would be picked up by the domain dynamically, at the startup. That way, the user would just modify the value of the environment variable and restart the server to pick up the changes in the variable!

The ordeal is expressed here.

I liked the way they used it and I thought of helping him. Of course, there are better ways of doing this, but they had been having this for some time and apparently, this was the thing holding them back from upgrading to GlassFish V2.

I remembered suddenly, the GlassFish had an attribute named env-classpath-ignored which is set to true by default. This means, that whoever (user on Operating System) starts the application server, if s/he has an environment variable named CLASSPATH it is always ignored by the server by default. This works well in almost all cases, since CLASSPATH is being forgotten by the Java community.

I thought of suggesting this to him and instead of setting AS_LIBRARIES, if CLASSPATH is set as the environment variable in this user's environment, the problem would be solved.

The way the launcher deals with this is:

  • Look at the env-classpath-ignored and it it is set to false (non-default case), append its value to the -cp argument to the JVM.
  • Effectively place the jars pointed to by CLASSPATH into the application server JVM's System ClassLoader.

I thought the problem is solved!

But no, because of various class-loaders in application server (each for a specific purpose), this was not working correctly as some classes were loaded too early by the System ClassLoader. The correct solution was to:

  • Look at env-classpath-ignored and if it is false,
  • Get the value of CLASSPATH and set it as -Dcom.sun.aas.ClassPathSuffix along with classpath-suffix in domain.xml.

It worked perfectly and user tested it (on his laptop, in Mumbai).

Lessons learned:
- Don't rely on private interfaces of a product. Hacks are OK, but look at the consequences.
- Consider using ${path.separator} instead of ':' or ';' if you want GlassFish to virtualize the 
operating platform for you. So, while setting path-like entries in domain.xml, always use
${path.separator}. GlassFish is designed to do the right thing.

Thanks to both Byron Nevins and Sivakumar Thyagarajan for their help in this regard.

About

Welcome to my blog where mostly my work related thoughts are expressed.

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today