FeaturesPluginsDocs & SupportCommunityPartners

Building an EJB 3.0 application using GlassFish v2, Apache Maven 2 and NetBeans IDE 6.0

While I was putting together the environment for reconstructing a potential error in the operation of Apache OpenEJB, where the remove() method could be incorrectly thought to be disallowed (GERONIMO-3452 Stateless Session EJBs cannot contain a remove() method), I decided to use the tools available to try and minimize the time needed for its creation. I decided to tackle the issue by first running it on the Java EE 5-certified application server - GlassFish v2, which is the reference implementation of Java EE 5, and then to act according to whether it ran there properly or not.

Contents

Content on this page applies to NetBeans IDE 6.0

Required Software

In order to create the environment needed to build the EJB 3.0 application you need to have the following installed:

  • "Web & Java EE" or "All" download of NetBeans IDE 6.0 (download).
  • Java Standard Development Kit (JDK) version 5.0 or version 6.0 (download)
  • GlassFish V2 Application Server (bundled with full IDE download) or Sun Java System Application Server, Platform Edition 9 (download)
  • Apache Maven 2.0.7 (download)
  • Maven plugin (available from the Update Center via the Plugins manager) (Maven2 project, NetBeans support for Maven)

Let us assume that the above software is installed and operating correctly. Software installation boils down to selecting and unzipping a folder in the selected directory.

In order to install the NetBeans Maven2 project support plugin we need to startup NetBeans IDE 6.0. Next, select the Tools > Plugins menu and from the dialogue box which appears choose the Available Plugins tab and select the plugin.

The complete project is available as ejb3-remove-stateless.zip.

Creating the project structure

2.1 Creating the parent project - ejb3-remove-stateless

We will start by creating the parent project (main project) from the point of view of organizing the project run by Apache Maven 2 (hereafter called m2). This will be a pom-type project which will include two sub-projects - the EJB bean module and the remote client module.

We can either create the project by hand - with the help of the mvn command, or using the NetBeans Maven2 project support plugin. Using the plugin made the process of creating the environment and working with m2 much easier. Thanks to the plugin we are able to perform most management functions from the IDE level. Until now these functions were performed from the command line level.

Assuming that the NetBeans Maven2 project support plugin has been installed correctly, select the File > New Project menu, and then the Maven category and the Maven Project.


(click to enlarge screenshot)

Click Next >


(click to enlarge screenshot)

Click Next > again, staying within the selection of the Maven Quickstart Project archetype.

On the next screen select the following project settings:

  • Project Name: ejb3-remove-stateless
  • Project Location: C:\
  • Group Id: pl.jaceklaskowski.javaee
  • Version: 1.0
  • Package: pl.jaceklaskowski.javaee


(click to enlarge screenshot)

These settings may differ from those given but the rest of this article assumes that they are the same as those listed above.

Click Finish to complete the creation of the project.

Finally a jar-type project is created. We will change the configuration of this project in order for it to fulfill the role of parent project. Select the new ejb3-remove-stateless project, right click the mouse and choose the Properties option from the drop-down menu. Change the Packaging field from jar to pom.


(click to enlarge screenshot)

We will also modify the property of the project since we are using the Java version.


(click to enlarge screenshot)

Agree to the changes by clicking OK.

We will finish preparing the project by deleting the src directory which is created by default when the project is created, but which we will not need. To remove the directory go to the Files tab, select the src directory and choose Delete from the drop-down menu.

Remove the test library junit-3.8.1 from the project (we will later change this to version 4.2)

Creating the sub-project - ejb3-remove-stateless-ejb3

To create the ejb3-remove-stateless-ejb3 sub-project we will again use NetBeans IDE 6.0. We will follow similar steps to those we took when we created the ejb3-remove-stateless parent project, just changing the location of the target sub-project so that it appears in the directory containing the parent project (this is similar to performing the command mvn create:archetype in the parent catalogue).

Select the following project settings:

  • Project Name: ejb3-remove-stateless-ejb3
  • Project Location: C:\ejb3-remove-stateless
  • Group Id: pl.jaceklaskowski.javaee
  • Version: 1.0
  • Package: pl.jaceklaskowski.javaee


(click to enlarge screenshot)

Click Finish to complete the creation of the project.

Successful creation of the project will cause the pom.xml file of the parent project to be modified due to the registration of module ejb3-remove-stateless-ejb3.

<modules>
   <module>ejb3-remove-stateless-ejb3</module>
</modules>

Just as we did with the parent project, we will remove the junit-3.8.1 test library. We will also remove the Test Packages directory for individual tests (select the Files tab, expand the ejb3-remove-stateless-ejb3 (jar) > src folder and remove the test directory marked with a red exclamation mark).

We will configure the project by changing Packaging to ejb. Right-click the mouse, select the Properties menu and in the dialogue box change the Packaging field from jar to ejb.


(click to enlarge screenshot)

Agree to the changes by clicking OK.

Remove the pl.jaceklaskowski.javaee.App category (from the Source Packages section). Finally we will configure the project to include the EJB 3.0 bean. This change requires the direct editing of the pom.xml file. We will add the maven-ejb-plugin to the configuration of this file.

<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-ejb-plugin</artifactId>
   <configuration>
      <ejbVersion>3.0</ejbVersion>
   </configuration>
</plugin>

After modifying the pom.xml file you should see the following:

<?xml version="1.0" encoding="UTF-8"?>
<project>
   <parent>
      <artifactId>ejb3-remove-stateless</artifactId>
      <groupId>pl.jaceklaskowski.javaee</groupId>
      <version>1.0</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <groupId>pl.jaceklaskowski.javaee</groupId>
   <artifactId>ejb3-remove-stateless-ejb3</artifactId>
   <name>ejb3-remove-stateless-ejb3</name>
   <packaging>ejb</packaging>
   <version>1.0</version>
   <url>http://www.JacekLaskowski.pl</url>
   <build>
      <plugins>
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-ejb-plugin</artifactId>
            <configuration>
               <ejbVersion>3.0</ejbVersion>
            </configuration>
         </plugin>
      </plugins>
   </build>
</project>

Creating the sub-project - ejb3-remove-stateless-client

We will create the ejb3-remove-stateless-client project in the same way as we created the previous sub-project. It is very important that the Project Location is the ejb3-remove-stateless parent project directory.

Select the following project settings

  • Project Name: ejb3-remove-stateless-client
  • Project Location: C:\ejb3-remove-stateless
  • Group Id: pl.jaceklaskowski.javaee
  • Version: 1.0
  • Package: pl.jaceklaskowski.javaee


(click to enlarge screenshot)

We will complete the preparation of the project by removing the junit-3.8.1.jar test library (Test Libraries), the pl.jaceklaskowski.javee.App category (Source Packages) as well as pl.jaceklaskowski.javaee.AppTest (Test Packages).

Complete project structure

The project structure is presented as follows:

Creating the EJB bean - Removable

Declaration of dependence of the EJB 3.0 library

We will begin creating the EJB bean by defining the project dependency.

We will add the EJB 3.0 library supplied as org.apache.geronimo.specs:geronimo-ejb_3.0_spec:1.0.

Remote business interface - RemovableRemote

We will create the remote business interface RemovableRemote (category pl.jaceklaskowski.javaee.RemovableRemote) in the ejb3-remove-stateless-ejb3 project.

package pl.jaceklaskowski.javaee;

import javax.ejb.Remote;

@Remote
public interface RemovableRemote {
   public void remove(String message);
}

Bean type - RemovableBean

We will create the bean type RemovableBean (category pl.jaceklaskowski.javaee.RemovableBean) by realizing the RemovableRemote business interface.

package pl.jaceklaskowski.javaee;

import javax.ejb.Stateless;

@Stateless(mappedName="Removable")
public class RemovableBean implements RemovableRemote {
    public void remove(String msg) {
        System.out.println(msg);
    }
}

Using the @Stateless annotation mappedName attribute allows you to assign names which you can use to search the EJB bean through the remote client (more information can be found in How are Global JNDI names assigned to Session / Entity beans?).

Creating the remote client - RemovableClient

We will create the RemovableClient according to the remote access guidelines for beans operating within GlassFish - How do I access a Remote EJB from a stand-alone java client?.

We will begin from the defined dependence on the sub-project - ejb3-remove-stateless-ejb3 (the client uses the sub-project category) through Libraries > Add Library...

After adding the dependency you may see an error message about the unavailability of dependencies in the local repository.


(click to enlarge screenshot)

To solve this problem we need to build the EJB bean - Removable, i.e. build the ejb3-remove-stateless-ejb3 project, and in turn place the library in the m2 local repository. We will build the project by selecting the ejb3-remove-stateless-ejb3 project, right-clicking the mouse and selecting the Build option from the drop-down menu.

Correctly performing this command as well as reloading the ejb3-remove-stateless-client client project (menu Reload Project) will solve the problem.

The next step is to create the client class - pl.jaceklaskowski.javaee.RemovableClient. This step is so wonderfully simple, it�s trivial. The simplicity of the client is down to the GlassFish library - appserv-rt.jar, which includes the JNDI configuration. We should also pay attention to the use of the EJB bean�s name - Removable - which was defined in the bean category through the @Stateless annotation mappedName attribute.

package pl.jaceklaskowski.javaee;

import javax.naming.Context;
import javax.naming.InitialContext;

public class RemovableClient {
    public static void main(String[] args) throws Exception {
        Context ctx = new InitialContext();
        RemovableRemote removable = (RemovableRemote) ctx.lookup("Removable");
        removable.remove("Look at the server's log");
    }
}

We now need to add the project dependencies which are libraries belonging to the GlassFish server - appserv-rt.jar as well as javaee.jar within the system (according to System Dependencies). Look out for dependency on the file system where GlassFish is installed through the variable glassfish.home (by default: c:/apps/glassfish).

<?xml version="1.0" encoding="UTF-8"?>
<project>
    <parent>
        <artifactId>ejb3-remove-stateless</artifactId>
        <groupId>pl.jaceklaskowski.javaee</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <groupId>pl.jaceklaskowski.javaee</groupId>
    <artifactId>ejb3-remove-stateless-client</artifactId>
    <name>ejb3-remove-stateless-client</name>
    <version>1.0</version>
    <properties>
        <glassfish.home>c:/apps/glassfish</glassfish.home>
    </properties>
    <dependencies>
        <dependency>
            <groupId>glassfish</groupId>
            <artifactId>appserv-rt.jar</artifactId>
            <version>LATEST</version>
            <scope>system</scope>
            <systemPath>${glassfish.home}/lib/appserv-rt.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>glassfish</groupId>
            <artifactId>javaee.jar</artifactId>
            <version>LATEST</version>
            <scope>system</scope>
            <systemPath>${glassfish.home}/lib/javaee.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>pl.jaceklaskowski.javaee</groupId>
            <artifactId>ejb3-remove-stateless-ejb3</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <includes>
                        <include>none</include>
                    </includes>
                </configuration>
                <executions>
                    <execution>
                        <id>run RemovableClientTest</id>
                        <phase>integration-test</phase>
                        <configuration>
                            <includes>
                                <include>**/RemovableClientTest.java</include>
                            </includes>
                        </configuration>
                        <goals>
                            <goal>test</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

The interesting fact about the module configuration is the configuration of the maven-surefire-plugin, which is configured in such a way that by default it exclusively performs the tests meeting the none pattern (which in our case means that none of the tests will be performed because the pattern is not met by any of the tests, but more accurately through our single RemovableClientTest), and it is only performed during the completion of the integration-test phase.

Despite the accessibility of the client class we will perform the automatic startup from level m2 with the help of the single test - RemovableClientTest (pl.jaceklaskowski.javaee.RemovableClientTest category) which we will build from the Test Packages folder.

package pl.jaceklaskowski.javaee;

import javax.naming.Context;
import javax.naming.InitialContext;
import org.junit.Test;

public class RemovableClientTest {

    @Test
    public void runRemoteClient() throws Exception {
        Context ctx = new InitialContext();
        RemovableRemote removable = (RemovableRemote) ctx.lookup("Removable");
        removable.remove("Look at the server's log");
    }
}

This type of test will not be started up by default (see: the configuration of the maven-surefire-plugin in pom.xml) because of the need to start up the bean on the GlassFish application server before the test can be started (if the way the tests are carried out is changed then the project cannot be created and it would not be possible to install the bean on the server).

Startup

The project startup depends on the installation of the Removable bean on the GlassFish server, and then the startup of the single RemovableClientTest.

GlassFish server startup

Before we move on to the installation of the bean, we will startup GlassFish with the command asadmin start-domain (I earlier defined the variable PATH to include the GlassFish bin directory).

$ asadmin.bat start-domain domain1
Starting Domain domain1, please wait.
Log redirected to c:\apps\glassfish\domains\domain1\logs\server.log.
Redirecting output to C:/apps/glassfish/domains/domain1/logs/server.log
Domain domain1 is ready to receive client requests. Additional services are being started in background.
Domain [domain1] is running [Sun Java System Application Server 9.1 (build b58d-fcs)]
with its configuration and logs at: [c:\apps\glassfish\domains].
Admin Console is available at [http://localhost:4848].
Use the same port [4848] for "asadmin" commands.
User web applications are available at these URLs:
[http://localhost:8080 https://localhost:8181 ].
Following web-contexts are available:
[/web1  /__wstx-services ].
Standard JMX Clients (like JConsole) can connect to JMXServiceURL:
[service:jmx:rmi:///jndi/rmi://dev:8686/jmxrmi] for domain management purposes.
Domain listens on at least following ports for connections:
[8080 8181 4848 3700 3820 3920 8686 ].
Domain does not support application server clusters and other standalone instances.

Installing the EJB bean - Removable

The installation of the bean should come before its creation. However, this step was effectively completed during the definition of the client dependency (ejb3-remove-stateless-client project). In the ejb3-remove-stateless-ejb3 project target directory there is a file called ejb3-remove-stateless-ejb3-1.0.jar. This is the bean distribution file. This will be installed with the help of the asadmin deploy command.

$ asadmin.bat deploy --user admin ejb3-remove-stateless-ejb3/target/ejb3-remove-stateless-ejb3-1.0.jar
Command deploy executed successfully.

In the administration console of the server (accessible by default through the address http://localhost:4848) we will check that the EJB Removable bean has been installed correctly.


(click to enlarge screenshot)

Remote client startup - RemovableClient

We will begin by building the entire ejb3-remove-stateless project by selecting the Build option from the menu.

Once the command has been started successfully you will see the following notification:

...
------------------------------------------------------------------------
Reactor Summary:
------------------------------------------------------------------------
ejb3-remove-stateless ................................. SUCCESS [1.500s]
ejb3-remove-stateless-ejb3 ............................ SUCCESS [0.610s]
ejb3-remove-stateless-client .......................... SUCCESS [0.921s]
------------------------------------------------------------------------
------------------------------------------------------------------------
BUILD SUCCESSFUL
------------------------------------------------------------------------
...

Of course by choosing the Build option we start the install step in the m2 nomenclature, which at the same time signifies the completion of the integration-test stage as well as the completion of our test.

The immediate startup of the client is effectively the performance of the mvn integration-test command, which in our case uses NetBeans IDE 6.0 as the graphic tool for starting the m2 command - this boils down to selecting the ejb3-remove-stateless-client project, right-clicking the mouse and selecting the Custom > Goals... option from the menu .

A list of m2 stages can be found on the Build Lifecycle Phases page.

Next we will perform the integration-test stage.

Once the test has been started successfully you will see the following notification in the NetBeans IDE:

...
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running pl.jaceklaskowski.javaee.RemovableClientTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.203 sec
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
------------------------------------------------------------------------
BUILD SUCCESSFUL
------------------------------------------------------------------------
...

as well as in the GlassFish diary of events (domains/domain1/logs/server.log file in the GlassFisha home directory)

[#|2007-09-03T22:41:59.750+0200|INFO|sun-appserver9.1|javax.enterprise.system.stream.out|_ThreadID=16;_ThreadName=p:
thread-pool-1; w: 8;|
Look at the server's log|#]

Despite the successful startup of the remote client this is not the final step of the solution. This requires the startup of a test to install the bean. If we try to perform the Build option before its installation we will receive an error message. Suggestions for improvements are welcomed. The next part of the article accompanies the Apache OpenEJB 3.0-SNAPSHOT server.

Related Links

Bookmark this page

del.icio.us furl simpy slashdot technorati digg
Companion
Projects:
MySQL Database Server   Open JDK: an Open SourceJDK   GlassFish Community: an Open Source Application Server    Mobile & Embedded Community    Open Solaris   java.net - The Source for Java Technology Collaboration   Open ESB - The Open Enterprise Service Bus Powered by