MyEclipse and a J2EE-blueprint-based tree

Gregory Golberg (grisha@alum.mit.edu)

MyEclipse forum announcement

Abstract

How to use a J2EE-blueprint-like-compliant source tree with MyEclipse for maximum benefit, or something...

Problem:

Given:
  1. an existing source tree structure following, more or less, J2EE blueprints

    The "more or less" part is kind of meaningless, since the blueprints themselves are "recommended conventions" or "guidelines [...] intended to assist developers". Nevertheless, for those literally minded, this is what I mean:

    1. There is more layers between a "myapp1" and "myapp1-war" - a folder called "modules". It is insignificant, but I thought I'd mention it.

    2. There are no classes or libraries included in a WAR (to end up under WEB-INF/classes or WEB-INF/lib, respectively). All compiled source (whether from modules or components) is packaged into utility JARs that live off the root of the EAR, each component/module built/packaged into its own utility JAR. The WAR's META-INF/MANIFEST.MF has a Class-Path attribute that lists the utility JARs.

    3. All third-party libraries are gathered together in a single place, to be shared among all applications. The actual inclusion of libraries for compilation and/or packaging of particular applications is handled by the build scripts (in our case, by property files, conforming to a given format, that parameterize the build scripts). For the purposes of IDE-based development, the dependencies can be set as desired for proper compilation. The build script will package and deploy the right set of JARs, and these will not be changed in the process of regular development/debugging (if they must change, a rebuild/redeploy will be required).

    The tree used is illustrated in more details below.

  2. WebSphere 6.0

  3. An existing set of [generic/parametrizable] Ant scripts for building and deploying the applications that reside in this tree

Create

a setup (with hot deployment!) for MyEclipse 4.1.1 (used with Eclipse 3.1.2).

Background

This may seem like a lot of assumptions; that is, a very particular case for which there's no need to publish a "tutorial". But while a set up exactly like this is a particular case, similar source trees may be common, if produced for/by other IDEs, and/or designed to follow J2EE blueprints for ease of writing build scripts. I am writing this because
  1. Setting up such a structure in MyEclipse requires jumping through some hoops to realize that, in part:

    1. There is an overlap in a J2EE blueprint structure between would-be EAR projects and their constituents, and Eclipse does not like that (I think Eclipse 3.2 actually does...)

    2. The source and context root folder of a web project can, apparently, only be set upon its creation

    3. There are choices to be made as to what hot-deployment policy to follow.

    4. Naming of [My]Eclipse projects matters. For example, certainly, WAR projects are named on their creation, but behind the scenes the archive attribute of project-module tag in .mymetadata for a project named foo is set to foo.war. This will affect the deployment.

  2. Maybe this + Google will help someone with something...

  3. I like nested lists.

Caveats

  1. This setup has not been proven out EJBs

  2. The thing about expanded JARs (that is, a folder named foo.jar in place of a foo.jar JAR) per se: WAS has a problem with it with respect to J2EE application clients.

  3. I am still sure what's up with -Xj9 vs reloadingEnabled attribute. Certainly the former is necessary to keep WAS in sync with code in IDE, but it does not seem sufficient... O well, MyEclipse does not pay me, so why bother...

Assumptions

We will assume that:
  1. The root of the source tree is somewhere - say, d:/mysourceroot, hereafter referred to as SOURCEROOT, which is where the tree such as the one below is located:

    |-apps
    | |-- myapp1
    |     |---META-INF
    |     |   |---application.xml
    |     |
    |     |---modules
    |         |---myapp1-war
    |         |    |---src
    |         |      |---web
    |         |        |---mypage.jsp
    |         |---myapp1-jar
    |           |---src
    |               |---java
    |                   |---com
    |                       |---foo
    |                           |---X.java
    |-components   
      |--comp1
         |---src
             |---java
               |---com
                   |---bar
                      |---Y.java
    

  2. As seen in the above tree, the WAR project folders have names ending with -war, and utility JAR project folders have names ending with -jar.

  3. Steps 1 through 4 from Debugging with WebSphere Application Server 6 Quickstart were performed.

    Steps 5 and 6 are also suggested. However, if you do not want to always split infinitives run WAS from MyEclipse, you may not want to redirect the System{Out,Err}.log to console as step 5 suggests, because when you run standalone, you have no way of looking at the logs. The reverse is not true. If you do not redirect the logs, you can always create a quick External Tool launch configuration in [My]Eclipse that will run tail -f on those WAS log files, and get the logs piped nicely to your console. If you do that, be sure to kill those tail launches when restarting WAS.

    For arguments to the VM that runs WebSphere I ( YMMV) like:

    -Xj9 -Xjit

    If run via MyEclipse, those are "Optional VM arguments" in MyEclipse's WAS setup. If run separately for whatever reason, as above, those those are specified in WAS Administration Console, under "Servers - Application Servers - <server> - Java and Process Management - Process Definition - Java Virtual Machine - Generic JVM arguments".

Steps

Perform the following steps.

For convenience,most of the steps below are automated by org.hrum.misc.MyEclipseWorkspaceCreator class. It is not intended to be used flexibly and repetitively to set up every developer. Rather, it should be tweaked and run by someone who will set up this environment, if needed. Then the person running it should just export/make available appropriate Eclipse settings for the rest.

This class assumes one more level of folders between the SOURCEROOT and apps - in our case, one for each team working on a suite of applications. This is for historical reasons, based on how project repositories were set up in source control, and can be easily tweaked in the code.

If you wish to use it:

  1. Perform the step to create WORKSPACE below.

  2. Stop Eclipse.

  3. Modify the MyEclipseWorkspaceCreator program as you wish and run.

  4. Point MyEclipse to the workspace created above by giving it the option -data WORKSPACE, and start it.

  5. In the workspace, right-click, choose "Import", then "Existing projects into workspace". Browse to SOURCEROOT, and import all projects found.

  6. Do the step above with WORKSPACE as root this time.

  7. Continue with step "Set up EAR deployment policy" below

  1. Create a workspace -- an empty directory. I will create it in d:\dev, and refer to it, hereafter, as WORKSPACE.

    Make sure there is no overlap between WORKSPACE and SOURCEROOT.

    Point MyEclipse to the
    workspace created above by giving it the option -data WORKSPACE, and start it.

  2. For each utility JAR (that is, for each module/component):

    1. Create a Java project (from existing source -- that is, SOURCEROOT/apps/myapp1/modules/myapp1-jar, SOURCEROOT/components/comp1, etc.). Set up build path (project/JAR dependencies) as appropriate. If not all dependencies are created yet, you will come back to this later anyway.

    2. Set output folders. It is a feature of at least WebSphere that if x.jar is deployed in an application, a folder named x.jar containing classes will work just as well. Therefore:

      1. For each Java project corresponding to a utility JAR, go to "Java Build Path", "Source" tab and set the "Default output folder" to the name of the JAR it is packaged into by the build script. That is, if component1 is packaged into component1.jar, make the output folder component1.jar.

      2. Modify the build script to, after installing applications in WAS, expand all utility JARs inside it under the folder whose name corresponds to the name of the JAR.

  3. Create the Web project. We will create it in SOURCEROOT (to reiterate: not in WORKSPACE) - so:
    1. Uncheck the "Use default location" checkbox.
    2. In "Directory", browse to the "myapp-war1" location and hit "Ok"
    3. As Project Name, specify the name of the <web-uri> specified under myapp1/META-INF/application.xml.
    4. As "Context root URL", specify the <context-root> from the above-mentioned application.xml.
    5. Specify src/web as "Web root folder" (since this is per the blueprint).
    6. Specify dummysrc for the "Source folder" (so as not to conflict with the src/web; in our setup, we do not have any Java code under a Web project, only under utility JARs).
    7. "Finish".

  4. Create EAR projects:
    1. We will create this one in WORKSPACE -- that is, we will keep default location
    2. The project should be named whatever the build script installs that particular EAR as (Say, if explicitly specified as -appName argument to one of them JACL scripts.) We assume it's the same as <display-name> from application.xml.
    3. Uncheck "Define EJB Project Modules", and click "Next"
    4. Select the appropriate WAR(s) created above, and "Finish".
    5. Delete the META-INF folder from the EAR project created above.
    6. Right-click on the EAR project, select "New - Folder", type "META-INF" as the name, click "Advanced", check "Link to the folder in the file system" and browse to the SOURCEROOT/apps/myapp1/META-INF folder, and "Finish".
    7. Set up EAR deployment policy:
      1. Right-click on the EAR project, and select "Properties".
      2. Select "MyEclipse-EAR", uncheck both "Use workbench settings" boxes.
      3. Choose "Ignore" for "Dependent Java Project Deployment Policy"
      4. Uncheck all other checkboxes

        If you understand what is being accomplished above you can set it as your workspace policy, or you can come up with the one that works for you.

      5. Select "Do not modify 'application.xml'", "Apply".

    8. In the left-hand frame, now select "Project references", and check off all the projects that are the constituents of this EAR, or that the constituents of this EAR depend on, and turtles all the way down. This is deployment dependency. You will set up compile-time dependency soon enough.
    9. "Ok".

  5. For all JARs and WARs, set up the build dependencies on other projects and JARs, appropriately so that everything compiles. You may need to Clean all projects.

    You may use "Order and Export" tab to keep dependencies streamlined as you wish, it will have no bearing on deployment strategy as presented here.

  6. For each of the WARs, set the following in WEB-INF/ibm-web-ext.xmi:

    1. In <webappext:WebAppExtension> tag, set the element reloadingEnabled="true".
    2. Inside the above tag, add or set the appropriate <jspAttributes> tag so that

      Beware of what
      setting reloadEnabled="true" in deployedObject tag of deployment.xml means -- it results in recycling the application. This is not what I want, so I set it to false. See also Hot-deploy to WAS resulting in app restart topic on MyEclipse forums.

  7. Right-click in the "Package Explorer" view, go to "MyEclipse - "Add and Remove Project Deployments", select EAR project in the "Project" drop-down list, click "Add", choose "Custom Location - Suffixed", select "Exploded Archive", browse to the location, choose "Overwrite remote resources", "Finish", "OK". Repeat for all EARs in your workspace (not for WARs -- but they will also appear in the "Project" drop-down list!).

  8. Run your regular build with deployment, and you are all set.

See also:

  1. Hot-deploy to WAS resulting in app restart

  2. Clickable JSP stack traces

  3. Having your log and eating it too

  4. Editing JSP pages in MyEclipse

  5. Discussion of MyEclipse performance.