WebObjects Deployment Notes

Deployment is a big hairy subject, and I don’t pretend to be an expert, but these are some notes of things that help me.

Some caveats: I only develop on Mac OS X Client with Eclipse+WOLips and install on Mac OS X Server, so these notes probably won’t make any sense for anyone else… sorry.

WARNING !AOOGA HORN SOUND! Not a tutorial, just a little list of tips, if you’ve got any tips of your own to add, leave a comment.

1. Use Project Wonder:

No justification, just do it.

2. Use split Properties:

Create multiple sets of Properties to minimize the amount of tweaking.

For example: Configure the one in your project (I dub thee “Project”) and the other in the root of your home directory (I’ll call you “Local”) with different values.

Set the Project properties to those that make sense for deployment, they will be overridden by the values in the Local properties which you configure for development.

Additionally, use this suggestion from Mike Schrag:

… and also Properties.yourusername. For instance, I have a Properties.mschrag that lets me set per-project-per-user properties overrides. Very handy.

If you need to access a property in your code use ERXProperties to do so, you’ll get the same property searching and caching behaviour that ERXConfigurationManager uses:

    String admin = ERXProperties.stringForKey("cs.project.adminname")

This means there are far fewer “little tweaks” to be made when deploying.

3. Build locally with embedded frameworks:

Modify your build.xml file to embed your frameworks:

   

This will make your application bundle a lot bigger, but it also means that you’ve completely eliminated any possibility of a version conflict between your new app deployment and any existing applications.

To build the app, just select something in the Eclipse Package Explorer view and ctrl+click -> WOLips Ant Tools -> Install… Select the apps to install and click “OK”.

The resulting app bundle(s) will be installed in /Library/WebObjects/Applications/

4. Copy the app to the server:

I usually zip my app bundle and copy it to the server via ssh where I have a script that extracts the archive into /Library/WebObjects/Applications/. Though rsync is looking more and more attractive… when I get the time. 🙂

5. Prep the virtual doc root:

I’m going to assume that most apps are deployed behind an Apache virtual domain configured to point at a subdirectory of the main doc root (i.e. /Library/WebServer/Documents/_site).

The app’s resource manager is going to expect to find web server resources in the following places:

Application:

 _site/
  WebObjects/
    AppName.woa/
      Contents/
        WebServerResources/

Frameworks:

 _site/
  WebObjects/
    Frameworks/
      FrameworkName.framework/
        WebServerResources/

Because we are embedding all of the frameworks, the framework’s WebServerResources will actually be in your app’s bundle. So, you could copy the WebServerResources directories from the apps and frameworks to those paths, or your could create sym-links, which is what I do.

I use a little script (prepWebObjectsDeploy.sh) to help me do that.

Because I use sym-links, this only has to be done the first time I install the app (unless subsequent releases add Frameworks to the build).

James Brook offers this tasty tip in the comments: Instead you can specify a property in the woapplication task of your ant build. If you set ‘frameworksBaseURL=”/WebObjects/MyApp.woa/Contents/ Frameworks/Library /Frameworks”’ the application will link to the resources in the embedded directories.

6. Test the installed app:

After copying the app, it’s usually a good idea to test the app via the command line to catch any weirdities:

   root# /Library/WebObjects/Applications/AppName.woa/AppName

7. Configure Monitor

I’m not going to talk about Monitor much, there are lots of other places that cover that in detail. The only thing I always make sure to do is to create a directory for the app’s logs (usually in /Library/Logs/WebObjects/AppName/) and set the Output path accordingly.

Profit!

Connection Dictionary Twiddling

Another “so I don’t have to look it up” post:

Connection dictionaries are the collection of information in your eomodel that configures your access through jdbc to your database.

It is possible to set/modify this information through code and I, along with many others, have built classes that read these settings from your Properties file on app launch. Project Wonder has ERXConfigurationManager that will do this for you as well.

Example:

  • dbConnectURLGLOBAL=jdbc:mysql://host/dbname
  • dbConnectUserGLOBAL=dbuser
  • dbConnectPasswordGLOBAL=dbpassword

Just drop those entries into your Properties file and away you go. Also, because the ERXConfigurationManager reads all your Properties files, you can override the settings in your project with personal ones in your ~/WebObjects.properties resulting in fewer changes to make when deploying. In fact that little trick works great for er.javamail and log4j settings as well.

Suppressing the wosid in a DirectAction

Two common means of generating DirectAction URLs in WebObjects are by using the directActionName bindings available in WOHyperLink (and it’s brethren) and by using the WOContext method: directActionURLForActionNamed(String name, NSDictionary).

Kol. Panic offered a tip on suppressing the Session ID (wosid) in DirectAction urls generated from a WOHyperLink in the comments of this post.

It turns out that there is a similar method if you are generating the URL in your code from a WOContext:

  public String loginUrl() {
    NSDictionary dict = new NSDictionary(
        new Object[] {Boolean.FALSE},
        new String[] {"wosid"});
    return context().directActionURLForActionNamed("login", dict);
  }