Wednesday, April 23, 2008

Deploying Grails and Hudson on OracleAS 10g R3

I recently had to deploy Hudson (the open-source continuous integration server) and CDR (a Grails application I built using Grails 1.0.1) at a client site onto OC4J 10g R3. As many of you old timey Grails developers may know Oracle is documented as having class loading issues with Grails applications. These issues are captured in an Oracle article written back in 2006. The fix, as documented by this article, is to set the deployment plan to "Search local classes first".

Ironically, my Grails application would not load with these settings. So I tried loading it without changing the deployment plan and Viola! It loaded with no issues.

The article did go to some good use, however. Hudson would not load without changing the setting to "Search local classes first."

Be warned, the current configuration UI is not identical to the one in the article.

Tuesday, April 22, 2008

Creating multiple Jetty Server instances

For my current project I was required to create multiple Jetty Server instances to run different applications and I found the documentation to be lacking.
It's possible that someone documented this somewhere but I couldn't find much info using the normal channels (google searches, etc).
I'm very hopeful that this will start some conversation and people will let me know if there are better ways to do this.

We're running Jetty on a Solaris 10 instance which I access using SSH. The requirements I had were:

  1. Jetty had to run in a shell-less mode. Meaning that when I logged out the server didn't shut down.

  2. I needed multiple instances of the Server to run different applications.
    It wasn't required for them to run in seperate JVMs which frankly I have yet to try.

Running Jetty shell-less is as simple as using the jetty.sh start script. This is probably obvious to old-time Jetty
users but it took me some researching to find this out. Starting Jetty this way requires you to be in the $JETTY_HOME directory and sexecute the script as follows:

./bin/jetty.sh start

This is a fairly useful script and you can view other useful commands by typing:

./bin/jetty.sh

...which will spit out all the usable commands.

Well that was easy enough, so how about starting multiple instances? Jetty uses the jetty.xml file (sometimes refered to generically as config.xml) found in the $JETTY_HOME/etc directory as the default configuration file for the server. You can override the default and pass in multiple files from the command line just by typing their path after the start command:

./bin/jetty.sh start $JETTY_HOME/env/foo.xml $JETTY_HOME/env/bar.xml

What will Jetty do with two configuration files? Well there is line very early in each config.xml file that identifies the server instance:
If the id for each file is the same then Jetty will combine both files. If they are different then Jetty creates multiple instances.

So I created a new file called jetty-cdr-instance.xml by copying the jetty.xml file. The first thing I did was change the line above:

After that all you have to do is look through the file and change ports or whatever other setting you need or want to change. I changed the port from 8080 to 8081 and changed all the other ports (not sure if I needed to):

<call name="addConnector">
<arg>
<new class="org.mortbay.jetty.nio.SelectChannelConnector">
<set name="port"><systemproperty name="jetty.port" default="8081"></systemproperty>
<set name="maxIdleTime">30000</set>
<set name="Acceptors">2</set>
<set name="statsOn">false</set>
<set name="confidentialPort">9453</set>
<set name="lowResourcesConnections">5000</set>
<set name="lowResourcesMaxIdleTime">5000</set>
</set>
</new>
</arg></call>

There are a number of other settings that can be configured but one that is important is where to find deployment archives (WAR files). By default Jetty looks into the $JETTY_HOME/webapps directory, which is fine for the default instance. But for my second instance I want to deploy different apps so I created a webapps2 directory and changed the configuration setting:

<call name="addLifeCycle">
<arg>
<new class="org.mortbay.jetty.deployer.WebAppDeployer">
<set name="contexts"><ref id="Contexts"></ref>
<set name="webAppDir"><systemproperty name="jetty.home" default=".">/webapps2</systemproperty>
<set name="parentLoaderPriority">false</set>
<set name="extract">true</set>
<set name="allowDuplicates">false</set>
<set name="defaultsDescriptor"><systemproperty name="jetty.home" default=".">/etc/webdefault.xml</systemproperty>
</set>
</set>
</set></new></arg></call>


And that's about it! So now if I feed both files at the command line I get two server instances, one running on the default port 8080 and the other 8081 and each running the applications in their respective webAppDir directory. But what if I don't want to pass the file names in the command line?

I'm sure there is a better way to do this, probably involving the jetty.conf file, but I was unable to find sufficient documentation. In the jetty.sh script you will find the lines:

#####################################################
# Run the standard server if there's nothing else to run
#####################################################
if [ -z "$CONFIGS" ]
then
CONFIGS="${JETTY_HOME}/etc/jetty.xml"
fi

I changed:

CONFIGS="${JETTY_HOME}/etc/jetty.xml"

to:

CONFIGS="${JETTY_HOME}/etc/jetty.xml ${JETTY_HOME}/etc/jetty-cdr-instance.xml"

and now by simply typing:

./bin/jetty.sh

I get both instances running.

And that's it! I'm still pretty new to administering Jetty so if you know better ways to handle these things please let me know.

Wednesday, April 16, 2008

CDR (Configuration Data Repository) Open Sourced!

This is big news for me as CDR is the first application that Delegata has open sourced. It was also my first stab at using Grails for a project that is being used in production.

CDR is an extremely simple Configuration Management Database. It is meant to be a starting point for an organization that is taking the initial steps toward getting their Configuration Management under control. As such, it's not meant to compete with the big CMDB vendors in features and functionality (yet).

I'm building CDR using the following:
  • Grails 1.01
    • Jsecurity Plugin (the latest 0.2 snapshot)
    • Jasper Reports Plugin (0.7.5)
    • WebTest Plugin(0.3)
I'm hoping to post in the coming weeks about some of my experiences, work-arounds, etc.

Delegata released it under the new BSD license so it can pretty much be used by whoever wants it for whatever purpose they have for it. Our goal is by open sourcing this product, it will continue to bring value to or clients beyond the initial release as they will be able to take advantage of any improvements made by me or anyone else.

I am still actively developing CDR, adding tests of all sorts, making UI improvements, and enhancing functionality. The source is available at:

http://code.google.com/p/configuration-data-repository/

My latest Blog design, not my first...

Nor will it be my last. I've changed the template a half dozen times already and I'm still not satisfied. The designs are creative but they never really represent my work or myself in any significant way...oh well...I'm sure I'll have a new one next month.

Monkey Search