Experiences building ssdd war using WOLips

From: Stephen Edwards (edward..s.vt.edu)
Date: Wed Feb 09 2005 - 16:11:49 EST

  • Next message: Geoff Hopson: "Re: Experiences building ssdd war using WOLips"

    Since I mentioned that I had slogged through this myself a while
    back, I thought I'd finally contribute a more detailed explanation of
    my experiences. This is a bit long, so feel free to skip it if you aren't
    interested.

    Bear in mind that I am no WO expert, and certainly not a Tomcat/
    servlet expert! This was my first experience trying to deploy a WO
    app as a servlet, and I relied heavily on the info in the "Practical
    WebObjects" book (an excellent book, IMHO).

    OK, so the first thing I did was to follow the comments in my wolips-
    generated build.xml file and enable the war and ssdd targets as
    indicated. I added the webXML="true" attribute to the woapplication
    Since I was shooting for an ssdd, I also create a plain text file called
    LICENSE containing a single line with my deployment license key in it,
    and placed it in the root of my project. So far so good.

    Also, from elsewhere on this list, I had added the (undocumented!)
    attribute embed="true" to all of the frameworks tags within the
    woapplication task of the build.woapp target. This attribute causes
    the contents of the corresponding framework(s) to be copied
    into the directory from which the war is built. Put it on *every*
    framework set within the woapplication task if you are trying for
    an ssdd that can run on a server that does not have WO installed.

    Building went fine, but it wouldn't start up correctly when
    deployed (I was deploying on Tomcat running alongside apache).
    One of the first things I noticed is that the directory layout within
    the generated war wasn't what was in the "Practical WebObjects"
    book or what I would expect in a traditional servlet--everything was
    all contained within the WEB-INF directory. In the end, I decided
    to stick with the dir layout generated by the default build file
    instead of trying to change to a more traditional layout, however.

    I took a look into the web.xml file and found these issues:

    1) The WOROOT parameter was set to the correct value for
         a non-ssdd install, but obviously wouldn't work for ssdd.
         I added a web_XML_WOROOT="..." attribute to the woapplication
         task in the build.xml file to specify a value appropriate for
         my final installation location. Note that the embed="true" attribute
         for the frameworks within the woapplication task causes the frameworks
         to be copied into the WEB-INF/<appname>.woa/Contents/Frameworks
         folder. As a result, the addition I made looks like this:
         <woapplication
             ...
     
    webXML_WOROOT="${servlet.install.dir}/${project.name}/WEB-INF/${project.name}.woa/Contents/Frameworks"
    >

         Here, the ${servlet.install.dir} was a new property that
         I defined in my build.properties file.

    2) The LOCALROOT parameter had the same problem. I
         fixed it by adding a webXML_LOCALROOT="..." attribute
         to the woapplication task. It pointed to the same dir that
         the webXML_WOROOT did (all local and system frameworks
         get copied to the same spot if you embed="true").

    3) The WOAINSTALLROOT parameter had the same problem.
         I don't really know if that is an issue or not, since I don't know what
         it is used for. I fixed it anyway, by adding a webXML_WOAINSTALLROOT="..."
         attribute to the woapplication task:
         <woapplication
             ...
             webXML_WOAINSTALLROOT="${servlet.install.dir}/${project.name}/WEB-INF"
    >

    4) The WOClasspath was hosed. Every entry began with:
         WEBINFROOTAPPROOT. For example, if the JavaWebObjects
         framework were on your classpath, it would appear like this
         in the web.xml file:

    WEBINFROOTAPPROOT\Frameworks\Library\Frameworks\JavaWebObjects.framework\Resources\Java\javawebobjects.jar

         I know that these prefixes on the classpath entries are substituted
         using the parameters present in the web.xml file (I think by the
         WOServletAdaptor, but I'm not positive). Whatever engine does the
         substituting, it is very myopic, and won't substitute the above
    appropriately.
         Again, I'm not positive, but I think it will only substitute WEBINFROOT
         (anyone know for sure?). I could never get "APPROOT" to substitute no
         matter what I did.

         In the end, I changed all the WOClasspath entries to look like this:

    WEBINFROOT/<appname>.woa/Contents/Frameworks/Library/Frameworks/JavaWebObjects.framework/Resources/Java/javawebobjects.jar

         This does work. Since I didn't want to have to hand-edit the
         web.xml file every time I rebuilt, I wrote a small perl script to
         do this munging for me.

    5) The classpath ordering was wrong--it is the app's Contents/Resources/Jar
         directory first, followed by the dependent frameworks purely in
         alphabetical order. In particular, the framework ordering in
         the project's .classpath file has no effect. Is there a better way in
         WOLips to control this? Anyway, since I use woproject in this app
         and wanted the ERExtensions framework to initialize before any of
         my own frameworks, and I also wanted the frameworks containing
         eomodel prototypes to appear before frameworks using the prototypes,
         I wanted to control this ordering. I tweaked my
         perl script so that it would "bubble" the ERJars, ERExtensions, and
         *Prototypes classpath items to the front of the list..

    6) The woapplication task generated the web.xml file in the
         ${dest.dir}/${project.name}/WEB-INF/${project.name}.woa/Contents
         dir, but the war task expected it to be in a slightly different location.
         I edited the pre-generated value for webxml="..." in the war task
         to point to the same location the woapplication task used.

    7) I added a basedir="${dest.dir}/${project.name}" attribute to
         the war task so that it would not include extra levels of subdirectories
         in the generated war file. I also deleted the existing .woa/** fileset that
         was there, since the entire .woa tree was already inside the WEB-INF
         root (and the fileset didn't seem to match anything in the build structure
         for the ant file).

    8) The LICENSE fileset in the war task also seemed to be broken,
         and pointed to the wrong dir (it points outside the project dir,
         if ant is invoked at the top level of the project). Further, it would
         place the LICENSE file in the wrong place (it needs to be in the
         WEB-INF dir). Instead, I moved this to a copy task in the ssdd target:

         <copy todir="${dest.dir}/${project.name}/WEB-INF/">
             <fileset dir=".">
                 <include name="LICENSE"/>
             </fileset>
         </copy>

    9) The default zipfileset entry in the war task for the WO tag library
         resulted in the tag library being placed in a location different
         from the one that the web.xml file points to, so I had to fix that.
         I ended up just removing the zipfileset entry and instead using
         a copy task in the ssdd directive:

         <copy todir="${dest.dir}/${project.name}/WEB-INF/tlds">
             <fileset
    dir="${wo.systemroot}/Library/Frameworks/JavaWOJSPServlet.framework/Resources/">
                 <include name="WOtaglib_1_0.tld"/>
             </fileset>
         </copy>

    10) There is no 10th change :-). Actually, I tested & retested the
         deploy, then customized my build.xml file so that my funky perl
         script would correct the web.xml classpath entries, and then
         split the build directive into two separate paths so that I could
         do an ssdd servlet installation or build/install a traditional stand-alone
         app from the same build.xml file.

    As near as I can reconstruct, these are the main things I had to
    change. The result is an odd-looking war file, since *everything*
    is inside the WEB-INF directory, but that seemed like the path of
    least resistance for getting the existing woproject ant tasks to produce
    a working war using the wolips-generated build.xml file. And
    like I said, since I'm no expert on this, I didn't want to try for
    major overhauls. Of course, that also means I may have done
    something the hard way that could've been done more easily.

    For woproject developers, the big issues were with the WOClasspath
    in the web.xml generated by the woapplication task. As near as
    I can tell, the generated classpath being produced just doesn't
    work. For wolips developers, the big issues were with the generated
    build.xml file, which provides incorrect placement of some
    items in the war file (e.g., the license file and the tag library),
    and omits some of the steps necessary for an ssdd war.

    Whew! That was a long message. Now you know why it took
    me so long to send it ;-).

                                     -- Steve

    --
    Stephen Edwards            604 McBryde Hall          Dept. of Computer Science
    e-mail      : edward..s.vt.edu           U.S. mail: Virginia Tech (VPI&SU)
    office phone: (540)-231-5723                         Blacksburg, VA  24061
    -------------------------------------------------------------------------------
    



    This archive was generated by hypermail 2.0.0 : Wed Feb 09 2005 - 16:10:24 EST