Friday, October 15, 2010

Maven, RAD and WebSphere: how to generate a set of RAD 7.5 projects for a J2EE application

This post continues the series on building RAD/WebSphere applications with Maven2.

 What we are trying to do here:
  • For a typical J2EE application, generate a set of RAD 7.5 projects using Maven's Eclipse plug-in (not to be confused with M2Eclipse, the Eclipse plug-in for Maven
  • Make sure the projects are usable "both ways": deploy on a local WebSphere server in the "normal" RAD way, and also build and deploy with Maven
  • Use Maven WAS6 plug-in to handle container-specific tasks: EJB stubs generation, bindings generation, application deployment

The main goal is to create a set-up that would not put any Eclipse/RAD-specific artefact (like .project, .classpath, .settings, etc.) in source control. Instead, the project in source control would be completely defined by the POM. The reason one would want to do that is that RAD projects -- in my humble opinion and experience -- are brittle, redundant and likely to contain settings that only make sense on a given workstation; this makes it hard to share. Another reason is that RAD is slow, rather bloated and an overkill for most tasks; if we don't standardize on RAD, people that don't use the advanced features would be able to use "vanilla" Eclipse, Net Beans, or any other IDE. Finally, making Maven POMs the single source of information about the project makes sure that this information is shared between the build script and the IDE.

Running Maven to generate RAD projects:

D:\apache-maven-2.2.1\bin\mvn.bat clean eclipse:clean eclipse:configure-workspace eclipse:eclipse -Declipse.workspace="${workspace_loc}


What follows is the Maven Eclipse plug-in configuration for the main POMs:

  • Common definitions factored out to parent POM:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.rbc.eca</groupId>
  <artifactId>J2EEProto</artifactId>
  <packaging>pom</packaging>
  <version>1.0-SNAPSHOT</version>

  <modules>
    <module>../J2EEProto-EAR</module>
    <module>../J2EEProto-lib</module>
    <module>../J2EEProto-ejb</module>
    <module>../J2EEProto-web</module>
  </modules>
...
    <pluginManagement>
...
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-eclipse-plugin</artifactId>
          <version>2.8</version>
          <inherited>true</inherited>
          <configuration>

            <wtpdefaultserver>WebSphere Application Server v6.1</wtpdefaultserver>
            <wtpmanifest>false</wtpmanifest>
            <wtpapplicationxml>true</wtpapplicationxml>
            <wtpversion>1.5</wtpversion>

            <downloadSources>true</downloadSources>
            <downloadJavadocs>true</downloadJavadocs>

            <projectNameTemplate>[artifactId]</projectNameTemplate>
            <useProjectReferences>true</useProjectReferences>

            <additionalBuildcommands>
              <buildcommand>org.eclipse.wst.validation.validationbuilder</buildcommand>
              <buildcommand>org.eclipse.wst.common.project.facet.core.builder</buildcommand>
            </additionalBuildcommands>

            <additionalProjectnatures>
              <projectnature>org.eclipse.wst.common.project.facet.core.nature</projectnature>
              <projectnature>org.eclipse.wst.common.modulecore.ModuleCoreNature</projectnature>
            </additionalProjectnatures>

            <classpathContainers>
              <classpathContainer>org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/WebSphere v6.1 JRE</classpathContainer>
              <classpathContainer>org.eclipse.jst.server.core.container/com.ibm.ws.ast.st.runtime.runtimeTarget.v61/was.base.v61</classpathContainer>
              <classpathContainer>org.eclipse.jst.j2ee.internal.module.container</classpathContainer>
            </classpathContainers>

          </configuration>
        </plugin>
    </pluginManagement>
...
  </project>

  • EJB project

This project uses Eclipse plug-in definitions from the parent POM, and
also calls Maven's WAS6 plug-in to prepare the EJB for deployment
outside of RAD.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.rbc.eca</groupId>
    <artifactId>J2EEProto</artifactId>
    <version>1.0-SNAPSHOT</version>
    <relativePath>../J2EEProto/pom.xml</relativePath>
  </parent>
  <artifactId>J2EEProto-ejb</artifactId>
  <packaging>ejb</packaging>

...

  <properties>
    <was6-home>D:\IBM\SDP75\runtimes\base_v61</was6-home>
  </properties>


  <build>
...

   <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-ejb-plugin</artifactId>
        <version>2.1</version>
        <configuration>
          <ejbVersion>2.1</ejbVersion>
          <generateClient>true</generateClient>
          <archive>
            <manifest>
              <classpathPrefix>lib/</classpathPrefix>
              <addClasspath>true</addClasspath>
            </manifest>
          </archive>
        </configuration>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-eclipse-plugin</artifactId>
        <configuration>

          <additionalProjectFacets>
            <jst.ejb>2.1</jst.ejb>
            <com.ibm.websphere.extended.ejb>6.1</com.ibm.websphere.extended.ejb>
          </additionalProjectFacets>

        </configuration>
      </plugin>


    </plugins>
  </build>


  <profiles>
    <!-- Profile used for batch build, needs WebSphere's J2EE JARs -->
    <profile>
      <id>batch</id>
      <activation>
        <property>
          <name>batch</name>
          <value>true</value>
        </property>
      </activation>

      <dependencies>
        <dependency>
          <groupId>websphere</groupId>
          <artifactId>j2ee</artifactId>
          <version>6.1</version>
          <scope>system</scope>
          <systemPath>${was6-home}\lib\j2ee.jar</systemPath>
        </dependency>

        <dependency>
          <groupId>websphere</groupId>
          <artifactId>ejbruntime</artifactId>
          <version>6.1</version>
          <scope>system</scope>
          <systemPath>${was6-home}\plugins\com.ibm.ws.runtime_6.1.0.jar</systemPath>
        </dependency>

        <dependency>
          <groupId>websphere</groupId>
          <artifactId>ejbportable</artifactId>
          <version>6.1</version>
          <scope>system</scope>
          <systemPath>${was6-home}\plugins\com.ibm.ws.ejbportable_6.1.0.jar</systemPath>
        </dependency>

        <dependency>
          <groupId>websphere</groupId>
          <artifactId>iwsorbutil</artifactId>
          <version>6.1</version>
          <scope>system</scope>
          <systemPath>${was6-home}\java\jre\lib\ext\iwsorbutil.jar</systemPath>
        </dependency>

      </dependencies>

      <build>

        <plugins>

          <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>was6-maven-plugin</artifactId>
            <executions>
              <execution>
                <id>integration-test</id>
                <phase>integration-test</phase>
                <goals>
                  <goal>ejbdeploy</goal>
                </goals>
              </execution>
            </executions>
            <configuration>
              <legacyMode>true</legacyMode>
            </configuration>
          </plugin>

        </plugins>
      </build>
    </profile>
  </profiles>
</project>

  • EAR project

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.rbc.eca</groupId>
    <artifactId>J2EEProto</artifactId>
    <version>1.0-SNAPSHOT</version>
    <relativePath>../J2EEProto/pom.xml</relativePath>
  </parent>
  <artifactId>J2EEProto-EAR</artifactId>
  <packaging>ear</packaging>

  <properties>
    <was6-home>D:\IBM\SDP75\runtimes\base_v61</was6-home>
  </properties>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-ear-plugin</artifactId>
        <version>2.4.2</version>
        <configuration>
          <filtering>true</filtering>
          <earSourceIncludes>**/ibmconfig/**</earSourceIncludes>
          <earSourceExcludes>**/target/**</earSourceExcludes>
          <version>1.4</version>
<!-- Generating it is the simplest solution if we don't have any extra
     settings; we could use an existing one otherwise, and use Maven
     resource filtering to get correct artifact versions in it -->
          <generateApplicationXml>true</generateApplicationXml>
<!--          <applicationXml>${basedir}/src/main/application/META-INF/application.xml</applicationXml>-->
          <modules>
            <webModule>
              <groupId>${project.groupId}</groupId>
              <artifactId>J2EEProto-web</artifactId>
              <contextRoot>/J2EEProto-web</contextRoot>
            </webModule>

            <jarModule>
              <groupId>${project.groupId}</groupId>
              <artifactId>J2EEProto-lib</artifactId>
            </jarModule>
            <ejbModule>
              <groupId>${project.groupId}</groupId>
              <artifactId>J2EEProto-ejb</artifactId>
            </ejbModule>
            <ejbClientModule>
              <groupId>${project.groupId}</groupId>
              <artifactId>J2EEProto-ejb</artifactId>
            </ejbClientModule>
          </modules>
        </configuration>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-eclipse-plugin</artifactId>
        <configuration>
        </configuration>
      </plugin>

      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>was6-maven-plugin</artifactId>
        <executions>
          <execution>
            <id>integration-test</id>
            <phase>integration-test</phase>
            <goals>
              <goal>wsStopServer</goal>
              <goal>wsUninstallApp</goal>
              <goal>wsDefaultBindings</goal>
              <goal>installApp</goal>
              <goal>wsStartServer</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <applicationName>${project.artifactId}</applicationName>
          <updateExisting>false</updateExisting>
          <earFile>${dest-ear}</earFile>
          <verbose>true</verbose>
        </configuration>
      </plugin>

    </plugins>
  </build>

  <dependencies>
    <dependency>
      <groupId>${project.groupId}</groupId>
      <artifactId>J2EEProto-web</artifactId>
      <version>${project.version}</version>
      <type>war</type>
    </dependency>
    <dependency>
      <groupId>${project.groupId}</groupId>
      <artifactId>J2EEProto-test</artifactId>
      <version>${project.version}</version>
      <type>war</type>
    </dependency>
    <dependency>
      <groupId>${project.groupId}</groupId>
      <artifactId>J2EEProto-ejb</artifactId>
      <version>${project.version}</version>
      <type>ejb</type>
    </dependency>
    <dependency>
      <groupId>${project.groupId}</groupId>
      <artifactId>J2EEProto-ejb</artifactId>
      <version>${project.version}</version>
      <type>ejb-client</type>
    </dependency>
    <dependency>
      <groupId>${project.groupId}</groupId>
      <artifactId>J2EEProto-lib</artifactId>
      <version>${project.version}</version>
    </dependency>

...

  </dependencies>


  <profiles>

    <!-- 
    If building for integration testing, deploy J2EEProto-test.war
     -->
    <profile>
      <id>integration-build</id>
      <activation>
        <property>
          <name>it-build</name>
          <value>true</value>
        </property>
      </activation>
      <properties>
        <exclude-integration>false</exclude-integration>
      </properties>
      <build>
      </build>
    </profile>

  </profiles>

</project>

  • Web Project

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>com.rbc.eca</groupId>
    <artifactId>J2EEProto</artifactId>
    <version>1.0-SNAPSHOT</version>
    <relativePath>../J2EEProto/pom.xml</relativePath>
  </parent>

  <artifactId>J2EEProto-web</artifactId>
  <packaging>war</packaging>

...

  <properties>
    <was6-home>D:\IBM\SDP75\runtimes\base_v61</was6-home>
  </properties>

  <build>

    <plugins>
...
       <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-eclipse-plugin</artifactId>
        <configuration>

          <warContextRoot>J2EEProto-web</warContextRoot>

          <additionalProjectFacets>
            <jst.web>2.4</jst.web>
            <com.ibm.websphere.extended.web>6.1</com.ibm.websphere.extended.web>
            <com.ibm.websphere.coexistence.web>6.1</com.ibm.websphere.coexistence.web>
          </additionalProjectFacets>

        </configuration>
      </plugin>

    </plugins>
  </build>

  <profiles>
...
</project>

  • Library project

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.rbc.eca</groupId>
    <artifactId>J2EEProto</artifactId>
    <version>1.0-SNAPSHOT</version>
    <relativePath>../J2EEProto/pom.xml</relativePath>
  </parent>
  <artifactId>J2EEProto-lib</artifactId>

...

  <build>
    <plugins>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-eclipse-plugin</artifactId>
        <configuration>
          <additionalProjectFacets>
            <jst.utility>1.0</jst.utility>
          </additionalProjectFacets>
        </configuration>
      </plugin>


    </plugins>
  </build>
  
   <reporting>    
   
    <plugins>  
    </plugins>      
  </reporting>  
 
</project>

No comments: