EJB3 Plugin enhancement

Version 1

    Overview:

    This document is a detailed discussion on how the EJB3 Plugin should work against the JBoss Application Server, to allow EJB3 container configurations and EJB3 container components to be pushed in the AS.

    Terms:

    Package - The word "package" in this document refers to a EJB3 component/module. Simply put, it can be considered as a jar file generated by the EJBTHREE project.

     

    EJB3 - Unless specified, the use of EJB3 in this documentation refers to the JBoss EJBTHREE project (i.e. combination of both EJB3.0 and EJB3.1). EJB3.0 will specifically be used wherever appropriate. Same is the case with EJB3.1

    Current State:

    - EJB3 Installer (org.jboss.ejb3:jboss-ejb3-installer) : Until very recently, the jboss-ejb3-installer used to dictate which packages/files from the EJB3 project are patched into the AS. However, recently starting version 1.0.3 of jboss-ejb3-installer, the responsibility of specifying the packages/files to be patched into the AS was delegated to the EJB3 plugin component.

     

    - EJB3 Plugin (org.jboss.ejb3:jboss-ejb3-plugin) : The EJB3 Plugin decides which packages and what versions of those packages are installed into the AS. Currently driven through a package-list.txt http://anonsvn.jboss.org/repos/jbossas/projects/ejb3/trunk/plugin/src/main/resources/package-list.txt:

    jboss-ejb3-timerservice-spi.xml
    jboss-ejb3-endpointdeployer.xml
    jboss-ejb3-endpoint.xml
    jboss-ejb3-metrics-deployer.xml
    

    Each of these .xml files in the package-list.txt are build files responsible for patching the AS with the corresponding package. These build files have an "install" and "uninstall" targets which are invoked by the EJB3 Installer. The "install" target is responsible for doing the necessary work to install the package. The "uninstall" as the name suggests is responsible for uninstalling the package.

     

    Note: The "uninstall" part isn't fully tested. For the rest of the document, the main emphasis will be on "install" of packages. Once we have a clear understanding on how that is to be done, we will be considering the "uninstall" on similar lines.

     

    Here's an example of what the "install" target looks like in each of these package installation build files:

    <target name="install"> 
          <copy file="lib/jboss-ejb3-endpoint.jar" todir="${jboss.home}/common/lib" verbose="${verbose}"/> 
    </target>
    

    Future:

    - The EJB3 installer's (jboss-ejb3-installer) sole responsibility would be to install EJB3 packages into the AS. It will *not* decide which packages have to be installed. The EJB3 plugin (see next) will decide which ones are to be fed to the installer so that the installer just installs them.

     

    - The EJB3 Plugin will provide a set of EJB3 packages to be installed into the AS. It will use the EJB3 installer to get these installed into the AS.

    Related JIRA:

    EJBTHREE-1939 https://jira.jboss.org/jira/browse/EJBTHREE-1939

    As part of EJBTHREE-1939, we plan to allow the EJB3 plugin to be able to:

     

    1) Allow users to opt for the regular EJB3.0 bug fixes that come in from the current EJB3 plugin against AS-5

     

    2) Allow users to opt for EJB 3.1 features through the plugin against AS-5

    Finer (implementation) details:

    EJB3 Plugin and Installer interaction:

    As mentioned earlier, the installer will just install the packages that are fed to it by the Plugin. In it's simplest form (which has been implemented as a POC for EJBTHREE-1939) the installer will expect a "packages.xml" build file from the EJB3 Plugin. The packages.xml is expected to be a build file which contains an "install" and an "uninstall" target. The EJB3 installer will just trigger an "install" on this packages.xml and leave the rest of installation to this packages.xml implementation. Same would be the case with "uninstall".

     

    From the packages.xml "install" point of view, it would internally install each of the packages that form the corresponding runtime (EJB3.0 or EJB3.1). To do this, it would look for *-package.xml file within a pre-defined "packages" folder within the EJB3 Plugin jar

    Responsibility of each package:

    Each package that forms a part of the EJB3 container is responsible for providing a *-package.xml file. The *-package.xml is expected to be an ant build file which will contain "install" and "uninstall" targets. For example, the jboss-ejb3-nointerface will contain a jboss-ejb3-nointerface-package.xml file (just an example):

    <target name="install">
          <copy file="lib/jboss-ejb3-nointerface.jar" todir="${jboss.home}/common/lib" verbose="${verbose}"/>
    </target>
    

    Since these *-package.xml files are meant for installation of the packages, these xmls should not make it to the runtime of the AS. Hence these should be placed in the src/main/assembly folder of the project component. For example, EJB3_TRUNK/nointerface/src/main/assembly/jboss-ejb3-nointerface-package.xml. The later section(s) discuss how this src/main/assembly/*-package.xml files are handled during the build of the Plugin.

    Maven Profiles:

    To map these requirements which what we have discussed so far in this wiki - the EJB3 plugin in co-ordination with the EJB3 installer should be able to install packages that collectively form a "EJB3.0 implementation" and/or "EJB3.1 implementation". In Maven terms, let's consider each of this as a "profile". So the EJB3 plugin will now have a new profile for EJB3.1 (named EJB3_1). The earlier default profile would continue being specific to EJB3.0 implementation. The EJB3.1 profile will be a superset of EJB3.0 (default) profile. Each profile will be responsible for declaring the packages that this profile is dependent on to form the profile. The common dependencies for EJB3.0 and EJB3.1 will be provided by the default profile since EJB3.1 is an extension of EJB3.0. Any specific package dependency for EJB3.1 (ex: jboss-ejb3-nointerface) will be made available through the EJB3_1 profile. Here's an example from the jboss-ejb3-plugin pom.xml (work-in-progress):

    <profiles>
        <profile>
            <!--  Profile for EJB 3.1 features to be delivered through the Plugin -->
            <id>EJB3_1</id>
            ...
            
            <!--  Dependencies for EJB 3.1 features -->
            <dependencies>
                <dependency>
                    <groupId>org.jboss.ejb3</groupId>
                    <artifactId>jboss-ejb3-nointerface</artifactId>
                    <version>1.0.0-SNAPSHOT</version>
                </dependency>
            </dependencies>
        </profile>
    </profiles>
    

    Notice that this EJB3_1 profile contains only EJB3.1 specific package dependencies - jboss-ejb3-nointerface being one of them. The rest of the common package dependencies like EJB3 core comes from the default profile.

    Assembling "packages" by the EJB3 Plugin:

    The final output of the EJB3 Plugin would be a .jar file containing one "packages.xml" file and multiple *-package.xml files in a pre-defined folder within the jar (let's assume the folder name is "packages"). Each profile is responsible for providing the right set of *-package.xml files in the packages folder of this plugin jar.  For example, the EJB3.0 profile will provide *-package.xml files which form the EJB3.0 implementation. It will *not* provide any EJB3.1 specific packages (*-package.xml files). On the other hand, the EJB3.1 profile will bring in the EJB3.1 related packages (Note that this would implicitly mean, EJB3.1 profile would bring in EJB3.0 *-package.xml since EJB3.1 is an extension of EJB3.0). Here's how the EJB3.0 plugin jar would look (just the relevant parts):

    jboss-ejb3-plugin.jar
    |
    |--- packages
    |     |
    |     |--- jboss-ejb3-endpoint-package.xml
    |     |--- jboss-ejb3-endpoint-deployer-package.xml
    |     |--- jboss-ejb3-metrics-deployer-package.xml
    |     |--- jboss-ejb3-timerservice-package.xml
    
    

    The EJB3.1 would look like:

    jboss-ejb3-plugin-ejb31.jar
    |
    |--- packages
    |     |
    |     |--- jboss-ejb3-endpoint-package.xml
    |     |--- jboss-ejb3-endpoint-deployer-package.xml
    |     |--- jboss-ejb3-metrics-deployer-package.xml
    |     |--- jboss-ejb3-timerservice-package.xml
    |     |--- jboss-ejb3-nointerface-package.xml
    

    The EJB3 plugin component would be responsible for generating the correct set of packages during build time. In it's current state (the work-in-progress patch for EJBTHREE-1939), it will use the maven-assembler-plugin http://maven.apache.org/plugins/maven-assembly-plugin/ to create these package assemblies. The EJB3.0 (default) profile will use the EJB3_TRUNK/plugin/src/main/assembly/ejb3-installer.xml to create the relevant set of plugin.jar/packages/*-package.xml  files:

    <?xml version="1.0" encoding="UTF-8"?>
    <assembly 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/xsd/assembly-1.0.0.xsd"
    >
      <id>installer</id>
      <formats>
        <format>jar</format>
      </formats>
      <includeBaseDirectory>false</includeBaseDirectory>
      
      <componentDescriptors>
         <!-- Common components required both in EJB3 and EJB3.1 -->
        <componentDescriptor>src/main/assembly/ejb3-installer-components.xml</componentDescriptor>
      </componentDescriptors>
    </assembly> 
    

    The common components assembly descriptor file:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <component>
      <fileSets>
        <fileSet>
          <directory>src/main/resources</directory>
          <includes>
         <!-- The *-package.xml files -->
            <include>jboss-ejb3-timerservice-spi-package.xml</include>
            <include>jboss-ejb3-endpointdeployer-package.xml</include>
            <include>jboss-ejb3-endpoint-package.xml</include>
            <include>jboss-ejb3-metrics-deployer-package.xml</include>
            <include>setup.xml</include>
            <include>packages.xml</include>
          </includes>
          <outputDirectory>packages</outputDirectory>
        </fileSet>
      </fileSets>
    
      <dependencySets>
        <dependencySet>
          <outputFileNameMapping></outputFileNameMapping>
          <unpack>true</unpack>
          <includes>
            <include>org.jboss.ejb3:jboss-ejb3-installer</include>
            <include>org.jboss.ejb3:jboss-ejb3-common</include>
          </includes>
        </dependencySet>
        <dependencySet>
          <outputFileNameMapping>${artifactId}.${extension}</outputFileNameMapping>
          <includes>
            <include>ant-contrib:ant-contrib</include>
            <include>org.jboss.ejb3:jboss-ejb3-cache:jar</include>
            <include>org.jboss.ejb3:jboss-ejb3-common:jar</include>
            <include>org.jboss.ejb3:jboss-ejb3-core:jar</include>
            <include>org.jboss.ejb3:jboss-ejb3-deployers:jar</include>
            <include>org.jboss.ejb3:jboss-ejb3-endpoint:jar</include>
            <include>org.jboss.ejb3:jboss-ejb3-endpoint-deployer:jar</include>
            <include>org.jboss.ejb3:jboss-ejb3-ext-api:jar</include>
            <include>org.jboss.ejb3:jboss-ejb3-ext-api-impl:jar</include>
            <include>org.jboss.ejb3:jboss-ejb3-interceptors:jar</include>
            <include>org.jboss.ejb3:jboss-ejb3-metadata:jar</include>
            <include>org.jboss.ejb3:jboss-ejb3-mc-int:jar</include>
            <include>org.jboss.ejb3:jboss-ejb3-metrics-deployer:jar</include>
            <include>org.jboss.ejb3:jboss-ejb3-proxy-impl:jar</include>
            <include>org.jboss.ejb3:jboss-ejb3-proxy-spi:jar</include>
            <include>org.jboss.ejb3:jboss-ejb3-proxy-clustered:jar</include>
            <include>org.jboss.ejb3:jboss-ejb3-security:jar</include>
            <include>org.jboss.ejb3:jboss-ejb3-timerservice-spi:jar</include>
            <include>org.jboss.ejb3:jboss-ejb3-transactions:jar</include>
          </includes>
          <outputDirectory>lib</outputDirectory>
        </dependencySet>
        <dependencySet>
          <outputFileNameMapping>${artifactId}.${extension}</outputFileNameMapping>
          <includes>
            <include>org.jboss.ejb3:jboss-ejb3-endpoint-deployer:jar</include>
          </includes>
          <outputDirectory>deploy</outputDirectory>
        </dependencySet>
        <dependencySet>
          <outputFileNameMapping>${artifactId}-${classifier}.${extension}</outputFileNameMapping>
          <includes>
            <include>org.jboss.ejb3:jboss-ejb3-common:jar:client</include>
            <include>org.jboss.ejb3:jboss-ejb3-core:jar:client</include>
            <include>org.jboss.ejb3:jboss-ejb3-proxy-impl:jar:client</include>
            <include>org.jboss.ejb3:jboss-ejb3-proxy-spi:jar:client</include>
            <include>org.jboss.ejb3:jboss-ejb3-proxy-clustered:jar:client</include>
            <include>org.jboss.ejb3:jboss-ejb3-security:jar:client</include>
          </includes>
          <outputDirectory>lib</outputDirectory>
        </dependencySet>
      </dependencySets>
    </component>
    

    And finally, the EJB3.1 specific assembly file:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <assembly 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/xsd/assembly-1.0.0.xsd"
    >
      <id>ejb31-installer</id>
      <formats>
        <format>jar</format>
      </formats>
      <includeBaseDirectory>false</includeBaseDirectory>
      <fileSets>
        <fileSet>
          <directory>src/main/resources</directory>
          <includes>
         <!-- EJB3.1 specific *-package.xml file(s) -->
            <include>jboss-ejb3-nointerface-package.xml</include>
          </includes>
          <outputDirectory>packages</outputDirectory>
        </fileSet>
      </fileSets>
      <componentDescriptors>
         <!-- Common EJB3.0 and EJB3.1 packages -->
        <componentDescriptor>src/main/assembly/ejb3-installer-components.xml</componentDescriptor>
      </componentDescriptors>
        <dependencySets>
            <dependencySet>
         <!-- EJB3.1 specific libraries -->
              <outputFileNameMapping>${artifactId}.${extension}</outputFileNameMapping>
              <includes>
                <include>org.jboss.ejb3:jboss-ejb3-nointerface:jar</include>
              </includes>
              <outputDirectory>lib</outputDirectory>
            </dependencySet>
        </dependencySets>
    </assembly>
    

    Each of the Maven profile in the EJB3 plugin pom would then refer to the appropriate assembly descriptor file to create the packages for installation. For example, the EJB3_1 profile would use the following maven-assembly-plugin configuration:

    <profile>
         <!--  Profile for EJB 3.1 features to be delivered through the Plugin -->
         <id>EJB3_1</id>
         <build>
              <plugins>
              <!-- Assembly Plugin -->
                   <plugin>
                   <artifactId>maven-assembly-plugin</artifactId>
                   <version>2.2-beta-1</version>
                   <executions>
                   <execution>
                   <id>make-assembly</id> 
                   <phase>package</phase>
                   <goals>
                        <goal>single</goal>
                   </goals>
                   </execution>
                   </executions>
                   <configuration>
                   <descriptors>
                   <!--  Use the EJB 3.1 installer descriptor  -->
                   <descriptor>src/main/assembly/ejb31-installer.xml</descriptor>
                   </descriptors>
                   <archive>
                   <manifest>
                        <mainClass>org.jboss.ejb3.installer.Installer</mainClass>
                   </manifest>
                   </archive>
                   </configuration>
                   <inherited>false</inherited>
                   </plugin>
              </plugins>
         </build>
    ...
    

    And the EJB3.0 (default) profile would use:

    <descriptors>
         <!--  Use the EJB 3.0 installer descriptor  -->
         <descriptor>src/main/assembly/ejb3-installer.xml</descriptor>
    </descriptors>
    

    Plugin creation:

    At build time, we decide which plugin we want to create. Either EJB3.0 (by default) or EJB3.1. For EJB3.1 plugin generation, use the following command:

    mvn clean install -P EJB3_1
    

    TODO:

    1) This is just an initial draft, more will be discussed in this wiki or the EJB3 dev forum

     

    2) The implementation suggestions mentioned above, do not break any backward compatibility of the Plugin or the Installer.