Building and Deploying Java EE EAR with Maven to Java EE Application Server (Part 4) – Deployment To JBoss AS 5.x & JBoss AS 6.x

We’ve discussed the Deployment to Glassfish 3.x in Part 3 of the series. In this article, we’ll do Maven deployment to JBoss AS 5.x and JBoss AS 6.x. For readers regardless if you are new to the series or had been following it, you don’t have to finish reading all the article parts before coming to this, all you have to do is to first complete or understand Part 1 and Part 2 of the series (you can skip Part 3) before carrying out the deployment steps for JBoss Application Server in this article.

This article deals with the deployment to both JBoss AS 5.x and JBoss AS 6.x in the same approach in the perspective of Maven, as we will be using the same Maven plugin in our EAR module for both JBoss AS 5.x and JBoss AS 6.x. I’ll outline to you the necessary preparation and little changes on the codes (only for the integration-test module) in what you have carried over from Part 2 to accommodate the deployment requirements.

Warning On Compatibility:

The contents outlined in the article are NOT compatible with JBoss AS 7.x.

Preparation

JBoss Application Server 5.x & 6.x Setup Brief

The setup is relatively straight forward. This is what we need to do:

  • In this setup, we’ll create a separate server instance/domain name call dummyserver-standard.
  • We’ll create a mysql-ds.xml file to describe the data source properties for the connection to the MySQL database, the DB which is used through out this demo. If you are using other DB, please create a different *-ds.xml file by referring to JBoss’s documentation on data source setup.
  • As for setting up the respective JMS connection factories and queue destination, we’ll deal with this setup separately for both JBoss AS 5.x and JBoss AS 6.x because JBoss AS 6.x uses HornetQ as their messaging module, which is different from JBoss AS 5.x.

Maven Repositories & Dependencies

Before touching the application servers, let’s get the initial things right, this includes the maven repository definition and the correct dependencies on the pom.xml files. Please edit the root pom.xml file, located at <path<DummyDemoJavaEE5/pom.xml and change it to the below contents:

 XML |  copy code |? 
01
<?xml version="1.0" encoding="UTF-8"?>
02
<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/xsd/maven-4.0.0.xsd">
03
    <!-- Basic properties -->
04
    <modelVersion>4.0.0</modelVersion>
05
    <groupId>com.developerscrappad</groupId>
06
    <artifactId>DummyDemoJavaEE5</artifactId>
07
    <version>1.0-SNAPSHOT</version>
08
    <name>DummyDemoJavaEE5</name>
09
 
10
    <!-- Please take note of the packaging type -->
11
    <packaging>pom</packaging>
12
 
13
    <!-- For any sub-modules (one level below), just include it here -->
14
    <modules>
15
        <module>project</module>
16
        <module>integration-test</module>
17
    </modules>
18
 
19
    <repositories>
20
        <repository> 
21
            <id>jboss</id>
22
            <url>https://repository.jboss.org/nexus/</url>
23
        </repository>
24
        <repository> 
25
            <id>eclipse</id>
26
            <url>http://download.eclipse.org/rt/eclipselink/maven.repo</url>
27
        </repository>
28
        <repository>
29
            <id>jboss-3p-release</id>
30
            <url>https://repository.jboss.org/nexus/content/repositories/thirdparty-releases</url>
31
        </repository>
32
        <repository>
33
            <id>jboss-3p-uploads</id>
34
            <url>https://repository.jboss.org/nexus/content/repositories/thirdparty-uploads</url>
35
        </repository>
36
        <repository>
37
            <id>jboss-deprecated</id>
38
            <url>https://repository.jboss.org/nexus/content/repositories/deprecated</url>
39
        </repository>
40
        <repository> 
41
            <id>Atlassian</id>
42
            <url>https://repository.atlassian.com/maven2</url>
43
        </repository>
44
    </repositories>
45
 
46
    <dependencies>
47
        <!-- For testing purposes -->
48
        <dependency>
49
            <groupId>junit</groupId>
50
            <artifactId>junit</artifactId>
51
            <version>4.10</version>
52
            <scope>test</scope>
53
        </dependency>
54
    </dependencies>
55
</project>

Have you notice the increase of repository URLs? In fact, for plain vanilla deployment, we don’t need that much of external repositories to be included, but because we are running the jboss-as-client within the integration-test module, it notoriously relies on many other dependencies and that is why we have to put these repository URLs as part of the reliance for integration test. We’ll look into the integration test later.

Using & Configuring The JBoss-Maven-Plugin

In order to deploy the EAR to the either the JBoss 5.x or 6.x App Server, we need the JBoss-Maven-Plugin. You may go to the plugin’s website and make a detail study of it. Anyway, here’s how to have the plugin configured with a very comprehensive config options which could be used in most deployment scenario. We’ll define the plugin in the DummyDemo-ear’s pom.xml file.

Please edit/replace the <path>/DummyDemoJavaEE5/project/DummyDemo-ear/pom.xml to the below:

 XML |  copy code |? 
001
<?xml version="1.0" encoding="UTF-8"?>
002
<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/xsd/maven-4.0.0.xsd">
003
 
004
    <!-- Basic Properties -->
005
    <modelVersion>4.0.0</modelVersion>
006
    <groupId>com.developerscrappad</groupId>
007
    <artifactId>DummyDemo-ear</artifactId>
008
    <version>1.0-SNAPSHOT</version>
009
    <name>DummyDemo-ear</name>
010
 
011
    <!-- The absolute path to the JBoss Server, please change this... -->
012
    <properties>
013
        <jboss.directory>C:/Java/jboss-5.1.0</jboss.directory>
014
    </properties>
015
 
016
    <!-- Reference the parent -->
017
    <parent>
018
        <artifactId>project</artifactId>
019
        <groupId>com.developerscrappad</groupId>
020
        <version>1.0-SNAPSHOT</version>
021
    </parent>
022
 
023
    <!-- The packaging value of any EAR module should be "ear" -->
024
    <packaging>ear</packaging>
025
 
026
    <!--
027
        The dependencies for EAR module should include all thoese sub-modules
028
        that are needed to be packaged into the ear file like the below...
029
    -->
030
    <dependencies>
031
        <dependency>
032
            <groupId>com.developerscrappad</groupId>
033
            <artifactId>DummyDemo-ejb</artifactId>
034
            <version>1.0-SNAPSHOT</version>
035
            <type>ejb</type>
036
        </dependency>
037
        <dependency>
038
            <groupId>com.developerscrappad</groupId>
039
            <artifactId>DummyDemo-web</artifactId>
040
            <version>1.0-SNAPSHOT</version>
041
            <type>war</type>
042
        </dependency>
043
        <dependency>
044
            <groupId>com.developerscrappad</groupId>
045
            <artifactId>DummyDemo-appclient</artifactId>
046
            <version>1.0-SNAPSHOT</version>
047
            <type>app-client</type>
048
        </dependency>
049
        <dependency>
050
            <groupId>com.developerscrappad</groupId>
051
            <artifactId>DummyDemo-api</artifactId>
052
            <version>1.0-SNAPSHOT</version>
053
            <type>jar</type>
054
        </dependency>
055
    </dependencies>
056
 
057
    <build>
058
        <plugins>
059
            <plugin>
060
                <groupId>org.apache.maven.plugins</groupId>
061
                <artifactId>maven-compiler-plugin</artifactId>
062
                <version>2.0.2</version>
063
                <configuration>
064
                    <source>1.5</source>
065
                    <target>1.5</target>
066
                </configuration>
067
            </plugin>
068
            <!--
069
                The ear plugin must include the definition for "modules",
070
                for any modules that are needed to be included in the EAR file,
071
                you need to specify them one by one, e.g. "ejbModule", "webModule",
072
                "jarModule" and "appClientModule".
073
            -->
074
            <plugin>
075
                <groupId>org.apache.maven.plugins</groupId>
076
                <artifactId>maven-ear-plugin</artifactId>
077
                <version>2.6</version>
078
                <configuration>
079
                    <version>5</version>
080
                    <defaultLibBundleDir>lib</defaultLibBundleDir>
081
                    <modules>
082
                        <ejbModule>
083
                            <groupId>com.developerscrappad</groupId>
084
                            <artifactId>DummyDemo-ejb</artifactId>
085
                        </ejbModule>
086
                        <webModule>
087
                            <groupId>com.developerscrappad</groupId>
088
                            <artifactId>DummyDemo-web</artifactId>
089
                            <context-root>/DummyDemo-web</context-root>
090
                        </webModule>
091
                        <jarModule>
092
                            <groupId>com.developerscrappad</groupId>
093
                            <artifactId>DummyDemo-api</artifactId>
094
                        </jarModule>
095
                        <appClientModule>
096
                            <groupId>com.developerscrappad</groupId>
097
                            <artifactId>DummyDemo-appclient</artifactId>
098
                        </appClientModule>
099
                    </modules>
100
                </configuration>
101
            </plugin>
102
 
103
            <!-- JBoss App Server -->
104
            <plugin>
105
                <groupId>org.codehaus.mojo</groupId>
106
                <artifactId>jboss-maven-plugin</artifactId>
107
                <version>1.5.0</version>
108
                <executions>
109
                    <execution>
110
                        <id>jboss-undeploy</id>
111
                        <goals>
112
                            <goal>undeploy</goal>
113
                        </goals>
114
                        <phase>clean</phase>
115
                    </execution>
116
                    <execution>
117
                        <id>jboss-deploy</id>
118
                        <goals>
119
                            <goal>deploy</goal>
120
                        </goals>
121
                        <phase>package</phase>
122
                    </execution>
123
                </executions>
124
                <configuration>
125
                    <jbossHome>${jboss.directory}</jbossHome>
126
                    <serverName>dummyserver-standard</serverName>
127
                    <hostName>localhost</hostName>
128
                    <port>8080</port>
129
                    <fileNames>
130
                        <fileName>${basedir}/target/DummyDemo-ear-1.0-SNAPSHOT.ear</fileName>
131
                    </fileNames>
132
                </configuration>
133
            </plugin>
134
        </plugins>
135
    </build>
136
 
137
</project>

pom.xml Explained:
Looking at the edited pom.xml, I have defined a property at the top called jboss.directory, with the value that points to the absolute path of the JBoss App Server directory. Please change this value accordingly. Moving down to the plugin section, both the “deploy” and “undeploy” plugin goals will only be executed during the package phase (I want to make the EAR deployed to the application server just after packing everything to the EAR file) and the clean build cycle respectively.

As for the plugin configurations, there are many options to be configured, which you can find them at the plugin page. But as for now, the above is sufficient. However, do take note on a few options listed below:

OptionDescription
jbossHomeThe value of <jbossHome> has to be of the absolute path of the directory that the JBoss Application Server resides. Here, we can directly assign the value from ${jboss.directory}.
serverNameThe name of the server instance/domain that this plugin should be referring. For this demo project, the value should be dummyserver-standard.
hostNameThe IP address of the hostname of the target application server.
portThe port number for the application server’s admin-console or jmx-console, which usually is defaulted to 8080.
fileNames -> fileNameThe absolute path of the EAR to be pickup for deployment.

JBoss: Creating The Server Domain/Instance

I prefer to do this manually without relying on automation from the JBoss-Maven-Plugin. We will use the “standard” server instance configuration from either JBoss AS 5.x or JBoss AS 6.x in this demo. So, just perform the following:

  1. Please create a new directory by the name of “dummyserver-standard” in the location
    <JBOSS_HOME>/server/
    
  2. Copy all the contents of <JBOSS_HOME>/server/standard and place it in the new “dummyserver-standard” directory that you have just created.

JBoss: Configuring the DB Data Source

Since we are using the MySQL DB for this demo, just create the mysql-ds.xml file with the below contents and put it into the <JBOSS_HOME>/server/dummyserver-standard/deploy/ directory.

 XML |  copy code |? 
01
<?xml version="1.0" encoding="UTF-8"?>
02
<datasources>
03
    <local-tx-datasource>
04
        <jndi-name>jndi/DummyDemoMySQLDB</jndi-name>
05
 
06
        <!-- Please change the url accordingly -->
07
        <connection-url>jdbc:mysql://localhost:3306/DUMMY_DEMO_DB</connection-url>
08
        <driver-class>com.mysql.jdbc.Driver</driver-class>
09
 
10
        <user-name>root</user-name> <!-- Please change this accordingly -->
11
        <password>your_password</password> <!-- Please change this accordingly -->
12
 
13
        <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>
14
        <metadata>
15
            <type-mapping>mySQL</type-mapping>
16
        </metadata>
17
    </local-tx-datasource>
18
</datasources>

Don’t forget the place the JDBC driver in the <JBOSS_HOME>/server/dummyserver-standard/lib/ directory.

JBoss: Configuring the JMS Queue and Connection Factory

We need to create both Queue Connection Factory and the Queue destination for the DummyDemoJavaEE5 application. To do this, just following the instructions below:

JBoss AS 5.x Specific

  1. Go to the directory <JBOSS_HOME>/server/dummyserver-standard/deploy/messaging/ and edit the file connection-factories.xml, keep the current default contents as it is, but insert the below within the <server> tag:
     XML |  copy code |? 
    01
    <!-- Queue Connection Factory -->
    02
        <mbean code="org.jboss.jms.server.connectionfactory.ConnectionFactory"
    03
               name="jboss.messaging.connectionfactory:service=TestQueueConnectionFactory"
    04
               xmbean-dd="xmdesc/ConnectionFactory-xmbean.xml">
    05
            <constructor>
    06
                <arg type="java.lang.String" value="TestQueueConnectionFactory"/>
    07
            </constructor>
    08
            <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
    09
            <depends optional-attribute-name="Connector">jboss.messaging:service=Connector,transport=bisocket</depends>
    10
            <depends>jboss.messaging:service=PostOffice</depends>
    11
            <attribute name="PrefetchSize">150</attribute>
    12
            <attribute name="DupsOKBatchSize">5000</attribute>
    13
            <attribute name="SupportsFailover">false</attribute>
    14
            <attribute name="SupportsLoadBalancing">false</attribute>
    15
            <attribute name="SlowConsumers">false</attribute>
    16
            <attribute name="JNDIBindings">
    17
                <bindings>
    18
                    <binding>jms/TestQueueConnectionFactory</binding>
    19
                </bindings>
    20
            </attribute>
    21
        </mbean>

    Safe the changes.
  2. Now, edit the destionations-service.xml file in the <JBOSS_HOME>/server/dummyserver-standard/deploy/messaging/ directory. Keep the default contents as it is, but insert the below portion within the <server> tag:
     XML |  copy code |? 
    01
    <!-- Queue -->
    02
        <mbean code="org.jboss.jms.server.destination.QueueService"
    03
               name="jboss.messaging.destination:service=Queue,name=TestQueue"
    04
               xmbean-dd="xmdesc/Queue-xmbean.xml">
    05
            <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
    06
            <attribute name="DLQ">
    07
                jboss.messaging.destination:service=Queue,name=PrivateDLQ
    08
            </attribute>
    09
            <attribute name="ExpiryQueue">
    10
                jboss.messaging.destination:service=Queue,name=PrivateExpiryQueue
    11
            </attribute>
    12
            <attribute name="JNDIName">jms/TestQueue</attribute>
    13
            <attribute name="RedeliveryDelay">1500</attribute>
    14
            <attribute name="MaxDeliveryAttempts">5</attribute>
    15
            <attribute name="FullSize">50000</attribute>
    16
            <attribute name="PageSize">5000</attribute>
    17
            <attribute name="DownCacheSize">2500</attribute>
    18
            <attribute name="MaxSize">75000</attribute>
    19
            <attribute name="SecurityConfig">
    20
                <security>
    21
                    <role name="guest" read="true" write="true"/>
    22
                    <role name="publisher" read="true" write="true" create="false"/>
    23
                </security>
    24
            </attribute>
    25
        </mbean>

This will do for now on JBoss 5.x.

** For more information, please visit: Quick Note: How To Setup JMS Queue/Topic & Connection Factory On JBoss 5.x

JBoss AS 6.x Specific

Beginning from JBoss AS 6.x, the JBoss team had adopted the HornetQ as the messaging engine for JBoss AS. Just follow the below to get the queue and connection factory up and running:

  1. Change the working directory to <JBOSS_HOME>/server/dummyserver-standard/deploy/
  2. Create a file call dummy-hornetq-jms.xml (any jms related configuration file must have the filename suffix of -hornetq-jms.xml) and have the xml contents as the below:
     XML |  copy code |? 
    01
    <configuration xmlns="urn:hornetq"
    02
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    03
                   xsi:schemaLocation="urn:hornetq /schema/hornetq-jms.xsd">
    04
     
    05
        <!-- Queue Connection Factory -->
    06
        <connection-factory name="TestQueueConnectionFactory">
    07
            <xa>false</xa>
    08
            <connectors>
    09
                <connector-ref connector-name="netty"/>
    10
            </connectors>
    11
            <entries>
    12
                <entry name="jms/TestQueueConnectionFactory"/>
    13
            </entries>
    14
        </connection-factory>
    15
     
    16
        <!-- Queue Destination -->
    17
        <queue name="TestQueue">
    18
            <entry name="jms/TestQueue"/>
    19
        </queue>
    20
     
    21
    </configuration>

This is for the JBoss AS 6.x.

** For more information on setting up Queues, Topic and Connection Factories on JBoss AS 6.x, please visit: Quick Note: How To Setup JMS Queue/Topic & Connection Factory On JBoss 6.x

The Right Dependency For Integration Test

Before deployment and performing the integration test, I would just want to highlight to you that we will be using the jboss-as-client as the depending library for running the integration test. If you check on mvnrepository.com, the jboss-as-client as several versions. For JBoss AS 5.1.0, we’ll use jboss-as-client version 5.1.0.GA; for JBoss AS 6.1.0, we’ll use the version 6.1.0.Final for the jboss-as-client.

Please edit the pom.xml in <path>/DummyDemoJavaEE5/integration-test/ with the below contents:

JBoss AS 5.1.0 Specific:

 XML |  copy code |? 
01
<?xml version="1.0"?>
02
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
03
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
04
 
05
    <!-- Basic Properties -->
06
    <modelVersion>4.0.0</modelVersion>
07
    <groupId>com.developerscrappad</groupId>
08
    <artifactId>integration-test</artifactId>
09
    <version>1.0-SNAPSHOT</version>
10
    <name>integration-test</name>
11
 
12
    <!-- Reference the parent -->
13
    <parent>
14
        <groupId>com.developerscrappad</groupId>
15
        <artifactId>DummyDemoJavaEE5</artifactId>
16
        <version>1.0-SNAPSHOT</version>
17
    </parent>
18
 
19
    <!-- Define the necessary dependencies for running the integration test -->
20
    <dependencies>
21
        <dependency>
22
            <groupId>org.jboss.jbossas</groupId>
23
            <artifactId>jboss-as-client</artifactId>
24
            <version>5.1.0.GA</version>
25
            <type>pom</type>
26
            <scope>test</scope>
27
        </dependency>
28
        <dependency>
29
            <groupId>com.developerscrappad</groupId>
30
            <artifactId>DummyDemo-ejb</artifactId>
31
            <version>1.0-SNAPSHOT</version>
32
            <type>ejb</type>
33
            <scope>test</scope>
34
        </dependency>
35
    </dependencies>
36
 
37
    <build>
38
        <plugins>
39
            <!--
40
                Sine this is an integration test module, the Failsafe plugin is now use.
41
                It will only pickup the integration files from the **/itest/ directory
42
                when running the integration-test. Please do not confuse this with unit test.
43
            -->
44
            <plugin>
45
                <groupId>org.apache.maven.plugins</groupId>
46
                <artifactId>maven-failsafe-plugin</artifactId>
47
                <version>2.12.4</version>
48
                <executions>
49
                    <execution>
50
                        <id>failsafe1</id>
51
                        <goals>
52
                            <goal>integration-test</goal>
53
                        </goals>
54
                        <phase>integration-test</phase>
55
                    </execution>
56
                    <execution>
57
                        <id>failsafe2</id>
58
                        <goals>
59
                            <goal>verify</goal>
60
                        </goals>
61
                        <phase>verify</phase>
62
                    </execution>
63
                </executions>
64
                <configuration>
65
                    <includes>
66
                        <include>**/itest/*.java</include>
67
                    </includes>
68
                </configuration>
69
            </plugin>
70
 
71
            <!--
72
                The surefire plugin is for unit testing purposes.
73
                For unit test, it will only pickup files within the **/utest/ directory.
74
                So, make sure you know where to place your unit test java files.
75
            -->
76
            <plugin>
77
                <groupId>org.apache.maven.plugins</groupId>
78
                <artifactId>maven-surefire-plugin</artifactId>
79
                <version>2.12.4</version>
80
                <executions>
81
                    <execution>
82
                        <id>sf1</id>
83
                        <goals>
84
                            <goal>test</goal>
85
                        </goals>
86
                        <phase>test</phase>
87
                    </execution>
88
                </executions>
89
                <configuration>
90
                    <includes>
91
                        <include>**/utest/*.java</include>
92
                    </includes>
93
                </configuration>
94
            </plugin>
95
        </plugins>
96
    </build>
97
</project>

JBoss AS 6.1.0 Specific:

 XML |  copy code |? 
001
<?xml version="1.0"?>
002
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
003
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
004
 
005
    <!-- Basic Properties -->
006
    <modelVersion>4.0.0</modelVersion>
007
    <groupId>com.developerscrappad</groupId>
008
    <artifactId>integration-test</artifactId>
009
    <version>1.0-SNAPSHOT</version>
010
    <name>integration-test</name>
011
 
012
    <!-- Reference the parent -->
013
    <parent>
014
        <groupId>com.developerscrappad</groupId>
015
        <artifactId>DummyDemoJavaEE5</artifactId>
016
        <version>1.0-SNAPSHOT</version>
017
    </parent>
018
 
019
    <!-- Define the necessary dependencies for running the integration test -->
020
    <dependencies>
021
        <dependency>
022
            <groupId>org.jboss.jbossas</groupId>
023
            <artifactId>jboss-as-client</artifactId>
024
            <version>6.1.0.Final</version>
025
            <type>pom</type>
026
            <scope>test</scope>
027
        </dependency>
028
        <dependency>
029
            <groupId>org.jboss.jbossas</groupId>
030
            <artifactId>jboss-as-hornetq-int</artifactId>
031
            <version>6.1.0.Final</version>
032
            <scope>test</scope>
033
        </dependency>
034
        <dependency>
035
            <groupId>com.developerscrappad</groupId>
036
            <artifactId>DummyDemo-ejb</artifactId>
037
            <version>1.0-SNAPSHOT</version>
038
            <type>ejb</type>
039
            <scope>test</scope>
040
        </dependency>
041
    </dependencies>
042
 
043
    <build>
044
        <plugins>
045
            <!--
046
                Sine this is an integration test module, the Failsafe plugin is now use.
047
                It will only pickup the integration files from the **/itest/ directory
048
                when running the integration-test. Please do not confuse this with unit test.
049
            -->
050
            <plugin>
051
                <groupId>org.apache.maven.plugins</groupId>
052
                <artifactId>maven-failsafe-plugin</artifactId>
053
                <version>2.12.4</version>
054
                <executions>
055
                    <execution>
056
                        <id>failsafe1</id>
057
                        <goals>
058
                            <goal>integration-test</goal>
059
                        </goals>
060
                        <phase>integration-test</phase>
061
                    </execution>
062
                    <execution>
063
                        <id>failsafe2</id>
064
                        <goals>
065
                            <goal>verify</goal>
066
                        </goals>
067
                        <phase>verify</phase>
068
                    </execution>
069
                </executions>
070
                <configuration>
071
                    <includes>
072
                        <include>**/itest/*.java</include>
073
                    </includes>
074
                </configuration>
075
            </plugin>
076
 
077
            <!--
078
                The surefire plugin is for unit testing purposes.
079
                For unit test, it will only pickup files within the **/utest/ directory.
080
                So, make sure you know where to place your unit test java files.
081
            -->
082
            <plugin>
083
                <groupId>org.apache.maven.plugins</groupId>
084
                <artifactId>maven-surefire-plugin</artifactId>
085
                <version>2.12.4</version>
086
                <executions>
087
                    <execution>
088
                        <id>sf1</id>
089
                        <goals>
090
                            <goal>test</goal>
091
                        </goals>
092
                        <phase>test</phase>
093
                    </execution>
094
                </executions>
095
                <configuration>
096
                    <includes>
097
                        <include>**/utest/*.java</include>
098
                    </includes>
099
                </configuration>
100
            </plugin>
101
        </plugins>
102
    </build>
103
</project>

A little changes in integration test codes:

Not forgetting the context environment properties in the integration test classes, we have to change the environment properties of the below files at the constructor. I have place the modified unit test files found in <path>/DummyDemoJavaEE/integration-test/src/test/com/developerscrappad/itest/ at the below:

Codes for com.developerscrappad.itest.BMPIntegrationTest.java

 Java(TM) 2 Platform Standard Edition 5.0 |  copy code |? 
001
package com.developerscrappad.itest;
002
 
003
import com.developerscrappad.entity.AppTable1Model;
004
import com.developerscrappad.entity.AppTable2Model;
005
import com.developerscrappad.entity.AppTable3Model;
006
import com.developerscrappad.intf.IBMPFacadeRemote;
007
import com.developerscrappad.intf.ICMPFacadeRemote;
008
import java.util.Properties;
009
import javax.naming.Context;
010
import javax.naming.InitialContext;
011
import org.junit.After;
012
import org.junit.Before;
013
import org.junit.Test;
014
import static org.junit.Assert.*;
015
 
016
public class BMPIntegrationTest {
017
 
018
    private Properties env;
019
    private Context ctx;
020
 
021
    public BMPIntegrationTest() {
022
        env = new Properties();
023
        env.setProperty( "java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory" );
024
        env.setProperty( "java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces" );
025
        env.setProperty( Context.PROVIDER_URL, "jnp://localhost:1099" );
026
    }
027
 
028
    @Before
029
    public void setUp() throws Exception {
030
        ctx = new InitialContext( env );
031
    }
032
 
033
    @After
034
    public void tearDown() throws Exception {
035
        IBMPFacadeRemote bmpFacade = ( IBMPFacadeRemote ) ctx.lookup( IBMPFacadeRemote.JNDI_NAME );
036
        bmpFacade.cleanupTables();
037
    }
038
 
039
    @Test
040
    public void testBMPProcessCommit() throws Exception {
041
        AppTable1Model model1 = new AppTable1Model();
042
        model1.setContents( "contents1" );
043
 
044
        AppTable2Model model2 = new AppTable2Model();
045
        model2.setContents( "contents2" );
046
 
047
        AppTable3Model model3 = new AppTable3Model();
048
        model3.setContents( "contents3" );
049
 
050
        IBMPFacadeRemote bmpFacade = ( IBMPFacadeRemote ) ctx.lookup( IBMPFacadeRemote.JNDI_NAME );
051
        bmpFacade.executeBMPProcess( model1, model2, model3 );
052
 
053
        ICMPFacadeRemote cmpFacade = ( ICMPFacadeRemote ) ctx.lookup( ICMPFacadeRemote.JNDI_NAME );
054
        model1 = cmpFacade.findAppTable1ByContents( "contents1" );
055
        assertEquals( "contents1", model1.getContents() );
056
 
057
        model2 = cmpFacade.findAppTable2ByContents( "contents2" );
058
        assertEquals( "contents2", model2.getContents() );
059
 
060
        model3 = cmpFacade.findAppTable3ByContents( "contents3" );
061
        assertEquals( "contents3", model3.getContents() );
062
    }
063
 
064
    @Test
065
    public void testBMPProcessRollback() throws Exception {
066
        AppTable1Model model1 = new AppTable1Model();
067
        model1.setContents( "contents1" );
068
 
069
        AppTable2Model model2 = new AppTable2Model();
070
        model2.setContents( "contents2" );
071
 
072
        AppTable3Model model3 = new AppTable3Model();
073
        model3.setContents( "contents3" );
074
 
075
        IBMPFacadeRemote bmpFacade = ( IBMPFacadeRemote ) ctx.lookup( IBMPFacadeRemote.JNDI_NAME );
076
        bmpFacade.executeBMPProcess( model1, model2, model3 );
077
 
078
        model1 = new AppTable1Model();
079
        model1.setContents( "contents1.1" );
080
 
081
        model2 = new AppTable2Model();
082
        model2.setContents( "contents2.2" );
083
 
084
        model3 = new AppTable3Model();
085
        model3.setContents( "contents3" );
086
 
087
        try {
088
            bmpFacade.executeBMPProcess( model1, model2, model3 );
089
            fail();
090
        } catch ( Exception ex ) {
091
            //absorb
092
        }
093
 
094
        ICMPFacadeRemote cmpFacade = ( ICMPFacadeRemote ) ctx.lookup( ICMPFacadeRemote.JNDI_NAME );
095
 
096
        try {
097
            model1 = cmpFacade.findAppTable1ByContents( "contents1.1" );
098
            fail();
099
        } catch ( Exception ex ) {
100
            //absorb
101
        }
102
 
103
        model1 = cmpFacade.findAppTable1ByContents( "contents1" );
104
        assertEquals( "contents1", model1.getContents() );
105
 
106
        try {
107
            model2 = cmpFacade.findAppTable2ByContents( "contents2.2" );
108
            fail();
109
        } catch ( Exception ex ) {
110
            //absorb
111
        }
112
 
113
        model2 = cmpFacade.findAppTable2ByContents( "contents2" );
114
        assertEquals( "contents2", model2.getContents() );
115
 
116
        model3 = cmpFacade.findAppTable3ByContents( "contents3" );
117
        assertEquals( "contents3", model3.getContents() );
118
    }
119
}

Codes for com.developerscrappad.itest.CMPIntegrationTest.java

 Java(TM) 2 Platform Standard Edition 5.0 |  copy code |? 
001
package com.developerscrappad.itest;
002
 
003
import com.developerscrappad.entity.AppTable1Model;
004
import com.developerscrappad.entity.AppTable2Model;
005
import com.developerscrappad.entity.AppTable3Model;
006
import com.developerscrappad.intf.ICMPFacadeRemote;
007
import java.util.Properties;
008
import javax.naming.Context;
009
import javax.naming.InitialContext;
010
import org.junit.After;
011
import org.junit.Before;
012
import org.junit.Test;
013
import static org.junit.Assert.*;
014
 
015
public class CMPIntegrationTest {
016
 
017
    private Properties env;
018
    private Context ctx;
019
 
020
    public CMPIntegrationTest() {
021
        env = new Properties();
022
        env.setProperty( "java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory" );
023
        env.setProperty( "java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces" );
024
        env.setProperty( Context.PROVIDER_URL, "jnp://localhost:1099" );
025
    }
026
 
027
    @Before
028
    public void setUp() throws Exception {
029
        ctx = new InitialContext( env );
030
    }
031
 
032
    @After
033
    public void tearDown() throws Exception {
034
        ICMPFacadeRemote cmpFacade = ( ICMPFacadeRemote ) ctx.lookup( ICMPFacadeRemote.JNDI_NAME );
035
        cmpFacade.cleanupTables();
036
    }
037
 
038
    @Test
039
    public void testCMPProcessCommit() throws Exception {
040
        AppTable1Model model1 = new AppTable1Model();
041
        model1.setContents( "contents1" );
042
 
043
        AppTable2Model model2 = new AppTable2Model();
044
        model2.setContents( "contents2" );
045
 
046
        AppTable3Model model3 = new AppTable3Model();
047
        model3.setContents( "contents3" );
048
 
049
        ICMPFacadeRemote cmpFacade = ( ICMPFacadeRemote ) ctx.lookup( ICMPFacadeRemote.JNDI_NAME );
050
        cmpFacade.executeCMPProcess( model1, model2, model3 );
051
 
052
        model1 = cmpFacade.findAppTable1ByContents( "contents1" );
053
        assertEquals( "contents1", model1.getContents() );
054
 
055
        model2 = cmpFacade.findAppTable2ByContents( "contents2" );
056
        assertEquals( "contents2", model2.getContents() );
057
 
058
        model3 = cmpFacade.findAppTable3ByContents( "contents3" );
059
        assertEquals( "contents3", model3.getContents() );
060
    }
061
 
062
    @Test
063
    public void testCMPProcessRollback() throws Exception {
064
        AppTable1Model model1 = new AppTable1Model();
065
        model1.setContents( "contents1" );
066
 
067
        AppTable2Model model2 = new AppTable2Model();
068
        model2.setContents( "contents2" );
069
 
070
        AppTable3Model model3 = new AppTable3Model();
071
        model3.setContents( "contents3" );
072
 
073
        ICMPFacadeRemote cmpFacade = ( ICMPFacadeRemote ) ctx.lookup( ICMPFacadeRemote.JNDI_NAME );
074
        cmpFacade.executeCMPProcess( model1, model2, model3 );
075
 
076
        model1 = new AppTable1Model();
077
        model1.setContents( "contents1.1" );
078
 
079
        model2 = new AppTable2Model();
080
        model2.setContents( "contents2.2" );
081
 
082
        model3 = new AppTable3Model();
083
        model3.setContents( "contents3" );
084
 
085
        try {
086
            cmpFacade.executeCMPProcess( model1, model2, model3 );
087
            fail();
088
        } catch ( Exception ex ) {
089
            //absorb
090
        }
091
 
092
        try {
093
            model1 = cmpFacade.findAppTable1ByContents( "contents1.1" );
094
            fail();
095
        } catch ( Exception ex ) {
096
            //absorb
097
        }
098
 
099
        model1 = cmpFacade.findAppTable1ByContents( "contents1" );
100
        assertEquals( "contents1", model1.getContents() );
101
 
102
        try {
103
            model2 = cmpFacade.findAppTable2ByContents( "contents2.2" );
104
            fail();
105
        } catch ( Exception ex ) {
106
            //absorb
107
        }
108
 
109
        model2 = cmpFacade.findAppTable2ByContents( "contents2" );
110
        assertEquals( "contents2", model2.getContents() );
111
 
112
        model3 = cmpFacade.findAppTable3ByContents( "contents3" );
113
        assertEquals( "contents3", model3.getContents() );
114
    }
115
}

Codes for com.developerscrappad.itest.MDBIntegrationTest

 XML |  copy code |? 
001
package com.developerscrappad.itest;
002
 
003
import com.developerscrappad.intf.IBMPFacadeRemote;
004
import com.developerscrappad.intf.ICMPFacadeRemote;
005
import java.util.Properties;
006
import java.util.logging.Level;
007
import java.util.logging.Logger;
008
import javax.jms.Connection;
009
import javax.jms.ConnectionFactory;
010
import javax.jms.Destination;
011
import javax.jms.JMSException;
012
import javax.jms.Message;
013
import javax.jms.MessageProducer;
014
import javax.jms.Session;
015
import javax.jms.TextMessage;
016
import javax.naming.Context;
017
import javax.naming.InitialContext;
018
import javax.naming.NamingException;
019
import org.junit.After;
020
import org.junit.AfterClass;
021
import org.junit.Before;
022
import org.junit.BeforeClass;
023
import org.junit.Test;
024
import static org.junit.Assert.*;
025
 
026
public class MDBIntegrationTest {
027
 
028
    private Properties env;
029
    private Context ctx;
030
 
031
    public MDBIntegrationTest() {
032
        env = new Properties();
033
        env.setProperty( "java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory" );
034
        env.setProperty( "java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces" );
035
        env.setProperty( Context.PROVIDER_URL, "jnp://localhost:1099" );
036
    }
037
 
038
    @BeforeClass
039
    public static void setUpClass() {
040
    }
041
 
042
    @AfterClass
043
    public static void tearDownClass() {
044
    }
045
 
046
    @Before
047
    public void setUp() throws Exception {
048
        ctx = new InitialContext( env );
049
    }
050
 
051
    @After
052
    public void tearDown() throws Exception {
053
        IBMPFacadeRemote bmpFacade = ( IBMPFacadeRemote ) ctx.lookup( IBMPFacadeRemote.JNDI_NAME );
054
        bmpFacade.cleanupTables();
055
    }
056
 
057
    @Test
058
    public void testMDB() {
059
        try {
060
            sendJMSMessageToQueue( "mdbcontents" );
061
            Thread.sleep( 10000 );
062
 
063
            ICMPFacadeRemote cmpFacade = ( ICMPFacadeRemote ) ctx.lookup( ICMPFacadeRemote.JNDI_NAME );
064
 
065
            try {
066
                cmpFacade.findAppTable1ByContents( "Hello mdbcontents" );
067
            } catch ( Exception ex ) {
068
                fail();
069
            }
070
        } catch ( Exception ex ) {
071
            ex.printStackTrace();
072
            fail();
073
        }
074
    }
075
 
076
    private Message createJMSMessageForjmsQueue( Session session, String messageData ) throws JMSException {
077
        // TODO create and populate message to send
078
        TextMessage tm = session.createTextMessage();
079
        tm.setText( messageData );
080
 
081
        return tm;
082
    }
083
 
084
    private void sendJMSMessageToQueue( String messageData ) throws NamingException, JMSException {
085
        ConnectionFactory cf = ( ConnectionFactory ) ctx.lookup( "jms/TestQueueConnectionFactory" );
086
        Connection conn = null;
087
        Session s = null;
088
 
089
        try {
090
            conn = cf.createConnection();
091
            s = conn.createSession( false, s.AUTO_ACKNOWLEDGE );
092
            Destination destination = ( Destination ) ctx.lookup( "jms/TestQueue" );
093
            MessageProducer mp = s.createProducer( destination );
094
            mp.send( createJMSMessageForjmsQueue( s, messageData ) );
095
        } finally {
096
            if ( s != null ) {
097
                try {
098
                    s.close();
099
                } catch ( JMSException e ) {
100
                    Logger.getLogger( this.getClass().getName() ).log( Level.WARNING, "Cannot close session", e );
101
                }
102
            }
103
            if ( conn != null ) {
104
                conn.close();
105
            }
106
        }
107
    }
108
}

Making Things Happen Step-By-Step

We will begin the Step 1 by starting the server instance. This applies to both JBoss AS 5.x and JBoss AS 6.x. If you study the JBoss-Maven-Plugin’s functionality, it has capabilities to configure the server instance, but as I have mentioned earlier, it is better for us to create and configure the server instance manually instead of depending on the plugin. The plugin now is to use just for deployment and undeployment on the server. Just following through the below to deploy the EAR.

** Multiple terminal encouraged…

Step 1: Starting the Server Instance/Domain

The JBoss-Maven-Plugin allows you to start the server instace by executing “mvn jboss:start” within the DummyDemo-ear module. But, I will not excourage that as we can’t possibly see the output traces of the server log, so we’ll start the server instance/domain through the command prompt from <JBOSS_HOME> itself.

  1. Change the working directory to <JBOSS_HOME>/bin/.
  2. To start the server instance, execute “run -c dummyserver-standard“.
  3. Just wait for the server to be started and correct any startup configuration error if you encounter any.

Step 2: Deploying the EAR File to the JBoss Application Server

This is a very “sensitive” step and the failure rate is usually high. If anything goes wrong, I would highly suggest that you revisit all procedures mentioned above or back track Part 1 and Part 2 of the series. Anyway, to deploy the EAR file, follow the steps below:

Full Deployment Including Running The Integration Test

  1. Please change the working directory to <path>/DummyDemoJavaEE5/.
  2. Execute the “mvn install” command. This command will start the JBoss domain (if it is not started) and it will deploy the EAR to the application server, and then, it will run the integration tests within the integration-test module.
  3. Just wait for Maven to download the dependencies through the internet (may take a long time…). But if things broke down due to network failure or if you have difficult resolving dependencies, I’ll use the “-U” flag to perform this again, e.g. “mvn install -U
  4. If it deploys properly, you should be able to see the below in the terminal:
    ...
    [INFO] Reactor Summary:
    [INFO]
    [INFO] DummyDemoJavaEE5 .................................. SUCCESS [0.090s]
    [INFO] project ........................................... SUCCESS [0.006s]
    [INFO] DummyDemo-api ..................................... SUCCESS [0.023s]
    [INFO] DummyDemo-ejb ..................................... SUCCESS [0.033s]
    [INFO] DummyDemo-web ..................................... SUCCESS [0.035s]
    [INFO] DummyDemo-appclient ............................... SUCCESS [0.052s]
    [INFO] DummyDemo-ear ..................................... SUCCESS [3.529s]
    [INFO] integration-test .................................. SUCCESS [0.018s]
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    ...

    If you have successfully completed this step, CONGRATULATIONS, your EAR file had been deployed and tested!

For Development Deployment (Without Running The Integration Test)

During development, we don’t need to always run the integration test for every single deployment, to achieve this while at your development with the JBoss App Server running, just perform the following:

  1. Change the working directory to <path>/DummyDemoJavaEE5/project/.
  2. For first time deployment of the EAR, just execute the command “mvn package” or “mvn install“.

Step 3: How to Undeploy or Redeploy the EAR to JBoss AS

In the midst of development, there will always be time when we need to redeploy the application again and again. To do that, just execute this at the <path>/DummyDemoJavaEE5/project/ working directory:

To UN-DEPLOY:
Just use the command: “mvn clean“. Since the the “undeploy” plugin goal was tagged with “clean” build-phase (just check on <path>/DummyDemoJavaEE5/project/DummyDemo-ear/pom.xml), when ever you execute the “clean” build cycle, it will perform the undeployment.

** Please take note that this command will fail if there is nothing to be undeploy on the JBoss App Server.

To RE-DEPLOY (only when there is an existing deployment in the JBoss app server):
Execute “mvn clean install” or “mvn clean package” at the terminal.

Summary on Part 4

Deployment to JBoss AS 5.x and JBoss AS 6.x through the JBoss-Maven-Plugin is pretty straight forward. The only thing that might caused annoyance is the long download time of dependency libraries when using the jboss-as-client for integration test. Overall, just make sure you have the right repository URLs, the right pom.xml in the DummyDemo-ear module and the integration-test module, you should do fine.

To Be Continue…

From here, I’ll be working on the Maven deployment on JBoss AS 7.x or Weblogic, which ever one comes first. So, stay tune.

Proceed To Part 5:

Building and Deploying Java EE EAR with Maven to Java EE Application Server (Part 5) – Deployment To WebLogic 10.3.x & Weblogic 12.x

Related Articles:

Max Lam

Born and currently resides in Malaysia, a seasoned Java developer whom had held positions as Senior Developer, Consultant and Technical Architect in various enterprise software development companies.

Facebook Twitter LinkedIn Google+ 

Previous Posts

Building and Deploying Java EE EAR with Maven to Java EE Application Server (Part 2) – Where to put your source codes and pom.xml (EJB, MDB, Web & Enterprise Application Client)
Building and Deploying Java EE EAR with Maven to Java EE Application Server (Part 1) – Project Directory Structure & Module Generation Through archetype:generate

Building and Deploying Java EE EAR with Maven to Java EE Application Server (Part 1) - Project Directory Structure & Module Generation Through archetype:generate

December 1st, 2012

Maven wasn’t very popular and wide used when it was first released, but after version 2, it had ga[...]

Java LDAP/JNDI: 2 Ways Of Decoding And Using The objectGUID From Windows Active Directory

Java LDAP/JNDI: 2 Ways Of Decoding And Using The objectGUID From Windows Active Directory

October 13th, 2012

Windows Active Directory is a good way for many corporations to be used as a means of user managemen[...]

Quick Note: Unable To Perform LDAP Wildcard “*” Search On Windows Active Directory

Quick Note: Unable To Perform LDAP Wildcard "*" Search On Windows Active Directory

October 9th, 2012

In case you are searching high and low for a solution or an answer to why Windows Active Directory d[...]

Java JNDI/LDAP: Windows Active Directory Authentication, Organizational Unit, Group & Other Information Access

Java JNDI/LDAP: Windows Active Directory Authentication, Organizational Unit, Group & Other Information Access

October 4th, 2012

In today's IT environment, most mid-size corporation and above will have some form of centralized em[...]

MySQL Cluster NDB 7.2 on Solaris 10 Part 3 – Testing The Cluster

MySQL Cluster NDB 7.2 on Solaris 10 Part 3 - Testing The Cluster

September 22nd, 2012

We are back again to have fun with our cluster that we've setup written in our previous articles on [...]

MySQL Cluster NDB 7.2 on Solaris 10 Part 2 – Starting, Distributed Synchronized Users Management And Stopping The Cluster

MySQL Cluster NDB 7.2 on Solaris 10 Part 2 - Starting, Distributed Synchronized Users Management And Stopping The Cluster

September 18th, 2012

This is the continuation from the previous part of the tutorial MySQL Cluster NDB 7.2 on Solaris 10 [...]

MySQL Cluster NDB 7.2 on Solaris 10 Part 1 – How To Install, Setup and Configure

MySQL Cluster NDB 7.2 on Solaris 10 Part 1 - How To Install, Setup and Configure

September 18th, 2012

If you have landed on this page, we believe you might either had a bumpy ride in getting the MySQL c[...]

Quick Fix: How to Solve “Unable to read the logging configuration” on Netbeans7 with JBoss6

Quick Fix: How to Solve "Unable to read the logging configuration" on Netbeans7 with JBoss6

September 8th, 2012

This is just a quick fix post for those whom are having this problem when running JBoss 6.x with Net[...]