Thursday, July 02, 2009

Working with FatWire and Eclipse

The project I am currently working with uses FatWire 5.5. It has been very painful to work without Eclipse since the plugin doesn't work for FatWire 5.5. Here is a technique I introduced that allows me to use Eclipse in concert with Content Server Explorer. It is not as nice as the plugin would be, but for my money it is vastly superior to working with plain old text editors!

Eclipse Project for FatWire Code

FatWire 5.5 needs JDK 1.3, so I set up JDK1.3 as an installed JRE in my Eclipse workspace. Get JDK 1.3 from Sun's Archive Page.

  1. Within Eclipse, go to Windows > Preferences > Java > Installed JREs.
  2. Click "Add".
  3. Click "Standard VM" and then click Next.
  4. For "JRE Home", click Directory and navigate to the location of your JDK 1.3 install (for example C:\Java\jdk1.3.1_20).
  5. Click OK.
  6. For "JRE Name", enter something like "jdk1.3.1_20".
  7. Click Finish and then click OK.

Now I make a Java project for my FatWire based code that uses JDK 1.3. Unlike other web applications I have worked on, I don't need to make a Dynamic Web Project for the code I will deploy to FatWire Content Server; I just need a standard Java Project.


Under the FatWire paradigm, all JSPs are created and maintained through FatWire tools - Content Server Advanced Interface and Content Server Explorer. I will deploy an EAR/WAR, but it will not contain any of my JSPs - which are CSElements. Instead, Content Server puts those files into the exploded EAR/WAR at runtime initialisation. This means that I never store JSPs in my own project (or static image or HTML files), so there is little advantage in using a Dynamic Web Project. I chose to use a standard Java Project for my project's FatWire code to keep the project structure simple. I use Ant build scripts to create the appropriate EAR/WAR file as needed.

Eclipse Project for Test Code

I keep unit tests in a separate project, which also means I can use a more recent JDK for unit tests. I set up another standard Java Project for the unit tests - and this project uses JDK 1.6. After I make the project (in the same workspace as the above project), I make the main project available to the unit test project. To do this, I select the unit test project and select Project > Properties > Java Build Path > Projects > click Add > check the box against the main FatWire code project. Now my unit test project will have all of the main FatWire project's code in its classpath.

Local JumpStart

In this section, I will explain the steps required to set up a local version of JumpStart that can be used for development and testing of both elements and Java backend code. I will integrate this JumpStart with my FatWire code project.

JumpStart 5.5 uses Resin underneath the hood.

  1. I get the JumpStart kit from the company repository (it's proprietary software and not available from the 'net) and unzip it somewhere such as C:\WorkSpaces\FatWireJsk_5.5.
  2. Click C:\WorkSpaces\FatWireJsk_5.5\CLICK ME FIRST.exe to start Content Server.
  3. I have a short-cut for this (for Windows).
    1. I right click on CLICK ME FIRST.exe and select "Create Shortcut"
    2. I rename the short-cut to something like "JumpStart - CS 5.5".
    3. I click and drag the shortcut to my Quick Launch bar.
    4. I do the same with Content Server Explorer (C:\WorkSpaces\FatWireJsk_5.5\JumpStart\tools\ContentServerExplorer\ContentServerExplorer.exe) and name it something like "CS-Explorer 5.5".
    5. It is important to keep track of the version numbers - CS-Explorer 7.02 is a bit flaky when connecting to Content Server 5.5 for example.
  4. I copy any JAR files I use in my FatWire code project to JumpStart's WEB-INF\lib folder, e.g. C:\WorkSpaces\FatWireJsk_5.5\resin\webapps\servlet\WEB-INF\lib. At least two exceptions are standard.jar and jstl.jar! Resin has its own jar files that cover this functionality.
  5. I next go to the WEB-INF directory that classes will be served from for JumpStart. For CS 5.5, this is C:\WorkSpaces\FatWireJsk_5.5\resin\webapps\servlet\WEB-INF.
  6. I create a classes directory within that folder.
  7. Within Eclipse I create an Ant build script (build.xml) in the main FatWire code project.
  8. I create an Ant task that will copy class files from the main FatWire code project to the WEB-INF\classes directory I just created. For example:
  9. <target name="deployClassesToLocalJumpstart">
      <fail unless="classes.dir"
            message="You must set classes.dir, such as -Dclasses.dir=C:\WorkSpaces\FatWireJsk_5.5\resin\webapps\servlet\WEB-INF\classes" />
      <copy todir="${classes.dir}">
         <fileset dir="bin">
            <include name="**/*.*" />
  10. In Eclipse, I create a run configuration to make it easy to run this task from within Eclipse.
    1. From within Eclipse, I select Run > External Tools > External Tools Configurations..
    2. I right click on Ant Build and select New and then select the new Ant build configuration just created.
    3. On the Main tab, I make sure the Buildfile points to my build.xml.
    4. Within the Arguments text area, I fill in the classes.dir argument. For example: -Dclasses.dir=C:\WorkSpaces\FatWireJsk_5.5\resin\webapps\servlet\WEB-INF\classes.
    5. On the Targets tab, I make sure the target I just wrote (deployClassesToLocalJumpstart) is ticked - and no others.
    6. On the Common tab, I select the Shared File radio button and click the Browse tab to select a directory in which to save the "run configuration". I do this so that I can check the "run configuration" file into source control for other programmers to use. Within my Eclipse project, I create a folder such as tools\eclipseIde for these sorts of files.
    7. Under "Display in favourites menu" I check the box for "External Tools". This makes it easier for me and other programmers to invoke the "run configuration".
    8. I click Apply.
    9. I click Close.
  11. Whenever I want to run this to deploy classes to my local JumpStart, I go Run > External Tools > DeployClassesToJumpstart. Personally, I use the keyboard shortcut for these run configurations: Alt, R (for Run), E (for External Tools), X (whatever number DeployClassesToJumpstart is assigned in the menu). For me, I currently type Alt,R,E,2 to deploy classes locally.
  12. After running this, I don't have to re-start JumpStart, but I do have to re-login to ContentServer and Content Server Explorer, because the web application gets restarted.

Now I have a local JumpStart running that I can run my own Java code within - and an Ant task to copy code over to Content Server. I use Content Server Explorer and the Advanced Interface as usual to interact with the other parts of Content Server.

Dynamic Web Project for CS Element Development

Now I need a way to edit CSElement files (primarily JSPs) in Eclipse. In this section I will go over how to create a Dynamic Web Project in Eclipse and set it up with all the ContentServer TLDs and Jar files. In the next section I will explore how to edit Content Server files in the Dynamic Web Project.

  1. In the same Eclipse workspace, I make a Dynamic Web Project. Since I am using FatWire 5.5, I made sure that "Dynamic Web Module Version" is at 2.3.
  2. Copy all of the files inside JumpStart's WEB-INF\lib folder to my dynamic web project's WEB-INF\lib folder, e.g. for FatWire 5.5 this was JumpStart5.5\resin\webapps\servlet\WEB-INF\lib.
  3. I copy the FatWire TLDs to my dynamic web project. For FatWire 5.5 this means copying the futuretense_cs folder (JumpStart5.5\resin\webapps\servlet\WEB-INF\futuretense_cs) to my dynamic web project's WEB-INF folder, i.e. I now have WEB-INF\futuretense_cs.
  4. Copy all of the TAGLIB elements from FatWire's web.xml (JumpStart5.5\resin\webapps\servlet\WEB-INF\web.xml) into my dynamic web project's web.xml.
    • Note the differences between web.xml in Servlet 2.3 (used in FatWire 5.5) and Servlet 2.4 (used in FatWire 7 and beyond).

      Excerpt from a Content Server web.xml using Servlet 2.3 - note that taglib is a child of web-app.

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "">
      <web-app id="WebApp_ID">
        <display-name>Fatwire5.5 Web</display-name>

      Excerpt from a Content Server web.xml using Servlet 2.4 - note that taglib is a child of jsp-config.

      <?xml version="1.0" encoding="UTF-8"?>
      <web-app id="WebApp_ID" version="2.4"
        <display-name>Fatwire7.0 Web</display-name>
  5. I give the dynamic web project access to my FatWire project code by selecting the dynamic web project and selecting Project > Properties > Java Build Path > Projects > click Add > check the box against the main FatWire code project. Now my dynamic web project project will have all of my main FatWire project's code in its classpath.

Editing CSElements

Now I have a dynamic web project with access to all the FatWire tag and Java libraries plus my own project work. I still need to hook this project up to my Content Server files so that I can edit them with Eclipse. Normally, I access Content Server files (CSElements such JSPs, XML files etc) through Content Server Explorer, which opens them up in a text editor of my choice. But this means I won't find out about compilation errors 'till I run the file - and I can't take advantage of the Eclipse tooling for JSP, Javascript, XML etc. I will fix this now.

Set up Eclipse to edit Content Server Explorer files in place. Whenever I edit or open some element through Content Server Explorer, it creates a copy of that file into temporary storage on my hard disk: these are the files I should edit with Eclipse.

  1. Find out what directory Content Server Explorer uses when creating local copies of the element files. UltraEdit tells me file locations when I use it to edit element files (I can also right click on a file tab and select "Open Folder" to open that directory in Windows Explorer). For me, running a FatWire 5.5 instance locally, it makes the files here: C:\Documents and Settings\rbram\Local Settings\Temp\localhost7001\ElementCatalog. Note the localhost7001 part: it is always a concatenation of the host-name/IP plus port number.
  2. I go to the WebContent/WEB-INF folder of my dynamic web project, right click and select New > Folder.
  3. Click Advanced.
  4. Check "Link to folder in the file system".
  5. Click Browse and navigate to the ElementCatalog directory Content Server Explorer is creating the local files within.
  6. I always change the "Folder name" of the folder to reflect the environment I am working within e.g. Local ElementCatalog or Dev ElementCatalog etc.
  7. Click OK.
  8. Click Finish.
  9. I can now directly modify any Content Server element from Eclipse, as long as I lock it and open it through Content Server Explorer first - then refresh my Navigator or Package Explorer view in Eclipse to pick up the file.
  10. Whenever I make an edit, I still have to go back to Content Server Explorer and select "save" there to have it upload the changes to the running application.
  11. Advantages to this approach:
    • I get to see all the files I am currently editing or just looking at - by that I mean all the files I have either opened or locked through Content Server Explorer.
  12. Disadvantages to this approach:
    • Every time I save in Content Server Explorer and go back to Eclipse, I get an annoying dialog that says "the file has been changed outside of Eclipse: do I want to reload the file?" I tried enabling the auto-refresh preference in Eclipse: Window > Preferences > General > Workspace > Refresh automatically. This had no effect so it seems I am stuck with that dialog every time.

Now I can do the following:

  1. My JSPs will compile and I will know about compilation errors etc immediately, without needing to run them.
  2. I have access to all the FatWire tags and classes because the dynamic web project includes the TLDs and APIs for them in the project classpath.
  3. I have access to all the classes in my main FatWire project because the dynamic web project includes the main FatWire project source in its project classpath.