// you're reading...

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

So far, we’ve covered Maven deployment of Java EE EAR to Glassfish 3.x, JBoss 5.x & 6.x. In this article, I’m going to show you how to deploy the EAR through Maven to Oracle’s WebLogic (both 10.3.x and 12.x). I truly have to give credit to the WebLogic team as regardless of the area of Maven deployment or Maven Java EE project dependency, WebLogic is by far the easiest and the simplest among all of the Application Servers that I have dealt with in terms of Maven. Although the production licenses are a little pricy, but remember this, what you pay is what you get.

For those who are new to this series, this article is already the 5th part of the series of Building and Deploying Java EE EAR with Maven to Java EE Application Server. You may gain access to all the articles in this series by scrolling down to the bottom of this page, you should be able to see all the links to the rest of the articles. However, you don’t have to follow all of them. If you are only interested in deploying the EAR to Oracle’s WebLogic, all you need to read is Part 1, Part 2 and Part 5 (which is this).

Warning On Compatibility:

The contents outlined in this article was only tested on WebLogic 10.3.x and WebLogic 12c. Please proceed at your own risk.

Preparation:

Creating the WebLogic Server Domain

I always love to get the WebLogic server installation files in the form of .zip from Oracle’s download page. So, assuming that you have the server files in .zip, please extract the files to your preferred directory and this directory shall be call MW_HOME. before moving forward, it is a must to create an environment variable of MW_HOME which points to the server directory.

Moving forward, we need to create the domain directory for the server. To do this, follow the below:

  1. Open the terminal, and make sure that the MW_HOME environment variable was properly defined in the OS.
  2. Change the directory to <MW_HOME>/wlserver/common/bin. Execute the command config.sh for Linux/Unix or config.cmd for Windows. This will bring out the UI for WebLogic domain creation.
  3. Just follow through the screen and for the purpose of this article, just assign the domain name as DummyDemoDomain and the domain directory/location as somewhere other than MW_HOME (Please note that the domain directory must not be the same location as MW_HOME).
  4. Just assign the username as “weblogic” and password as “wlpasswd1234” for now.
  5. Select “development” mode for now and select the JDK.
  6. In the optional configuration page, just select all.
  7. For the rest, just accept the default and click through the screens until you reach the summary page. Just the “create” button to create the domain.
  8. To start the server, go the the terminal and change the directory to <DummyDemoDomain_path> and execute startWebLogic.sh for Linux/Unix or startWebLogic.cmd for Windows.

Configuring the WebLogic Domain

First time console login and DB data source setup (MySQL specific):

To configure the WebLogic domain, follow the below:

  1. Through the web browser, go to http://<your_IP>:7001/console/ (e.g. http://localhost:7001/console/). Login to the console by providing the username and password that you’ve assigned during domain creation. You should be able to see the home page with all the domain configuration links.
  2. The first thing that we need to do is to setup the data source. Just click on the Data Sources link under the “Services” section.
  3. Click “New” and select “Generic Data Sources“. For the purpose of this article, assign the name as “MySQL DB Data Source“, the JNDI as “jndi/DummyDemoMySQLDB” and select the Database Type as “MySQL“. Click “Next“.
  4. Accept the Database Driver as: “MySQL’s Driver (Type 4) Versions: using com.mysql.jdbc.Driver“. Click “Next“.
  5. In the Transaction Options section, enable “Supports Global Transaction” and select “Emulate Two-Phase Commit“. Click “Next” to proceed.
  6. In the Connection Properties section, just key in the relevant details (e.g. Database Name -> DUMMY_DEMO_DB, Host -> localhost, Port -> 3306, etc.). Click “Next“.
  7. In the Test Database Connection section, just click on the “Test Configuration” to see if the DB is functioning. Click “Finish” when done.

Configuring the JMS:

The DummyDemoJavaEE5 app requires a JMS Queue and a Connection Factory. To setup a separate connection factory and a queue, just perform the below:

  1. If you are not back to the “Home” page, just click on the “Home” link of the WebLogic Admin Console.
  2. Under the section Services -> Messaging, click on “JMS Server“.
  3. Now we are about to create a new JMS Server, click on the “New” button and start filling the blanks. Assign the name of the server as “DummyDemo JMS Server” and accept the Persistent Store as “(none)” (You may experiment with the persistent store in later as it allows JDBC or File as a storage avenue). Click “Next“.
  4. In the Select targets section, just select the default, which is “AdminServer” for now. Click “Finish” when done.

Next, we need to create a separate JMS Module. To do this, perform the following:

  1. Back to the “Home” page, select “JMS Modules” in the section of Services -> Messaging.
  2. Click on the “New” button, in the Name field, just type “DummyDemo JMS Module“. Click “Next“.
  3. As for the target servers, select “AdminServer” for now. Click “Next“.
  4. Here, it will ask you whether to add resources to the JMS system module? Enable it and click “Finish“.
  5. Then, you’ll be leaded to the resources page. Click on the “New” button.
  6. Let’s add a connection factory by selecting the Connection Factory radio button and click “Next“.
  7. Assign these values to the fields and leave the rest as default:
    • name: “TestQueueConnectionFactory
    • JNDI: “jms/TestQueueConnectionFactory

    Click “Next“.

  8. Select “AdminServer” as the target server. Click “Finish“.
  9. Now, you are brought back to the resources page, click on the “New” button again, this time, we’ll create the queue.
  10. Select the “Queue” radio button and click “Next“.
  11. Assign these values to the fields and leave the rest as default:
    • Name: “TestQueue
    • JNDI Name: “jms/TestQueue

    Click “Next“.

  12. In the subdeployment section, click on the “Create a New Subdeployment” button. Accept the default name and click “Ok”.
  13. Then, the list of targets will appear at the bottom of the page. Select the “DummyDemo JMS Server” that we’ve created just now, and click on the “Finish” button.

and…that’s it for the WebLogic config.

Compiling & Making The WebLogic Maven Plugin Available

You must be thinking…”WHAT?! Do I need to do this myself??? Isn’t there any public repository for downloading the plugin?”, well…actually, you can’t find the WebLogic Maven Plugin in any of the public Maven repositories…not at the moment. Oracle did not publish any of their intellectual properties to be made available in any 3rd party public repository, which I believe it has something to do with their licensing restriction. But, anyway, it shouldn’t stop you from getting things up and running.

The below steps are necessary to get the WebLogic Maven Plugin jar file created and be made available to your Maven’s local repository, so that it could be made as a dependency for any of your own Maven projects.

Compiling the WebLogic Maven Plugin

You may read more about the WebLogic Maven Plugin from Oracle’s documentation site here. But for the sake of getting things done as fast as possible, I’ll just outline the step-by-step guide in doing this.

  1. Again make sure the MW_HOME system variable defined and the java command is in the path.
  2. In the terminal, change the directory to <MW_HOME>/wlserver/server/lib/ and execute the command:
    java -jar wljarbuilder.jar -profile weblogic-maven-plugin
    
  3. Once the jar file is produced in the same directory, we need to extract the pom.xml file that was packaged inside the jar file so that it could be used as a plugin install descriptor for Maven. To do this, just type:
    jar xvf weblogic-maven-plugin.jar \
    META-INF/maven/com.oracle.weblogic/weblogic-maven-plugin/pom.xml
  4. The pom.xml file was extracted with all of the subdirectories. Now, you just have to copy the pom.xml out from the subdirectories of META-INF/maven/com.oracle.weblogic/weblogic-maven-plugin/ to the same directory as the weblogic-maven-plugin.jar.

Now if were to take a look at the extracted pom.xml, it will look like this:

 XML |  copy code |? 
01
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
02
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
03
  <modelVersion>4.0.0</modelVersion>
04
  <groupId>com.oracle.weblogic</groupId>
05
  <artifactId>weblogic-maven-plugin</artifactId>
06
  <packaging>maven-plugin</packaging>
07
  <version>10.3.6.0</version>
08
  <name>Maven Mojo Archetype</name>
09
  <url>http://maven.apache.org</url>
10
  <dependencies>
11
    <dependency>
12
      <groupId>org.apache.maven</groupId>
13
      <artifactId>maven-plugin-api</artifactId>
14
      <version>2.0</version>
15
    </dependency>
16
 </dependencies>
17
</project>

It is important to take note of the <version> value. This is the version number that identifies every WebLogic Maven Plugin for specific WebLogic Server version. So, every time when you need to deploy to a new WebLogic server which is of a different version, you will need to recompile the WebLogic Plugin again with a different version number and install into the your own local Maven repository or the shared Sonatype’s Nexus or the JFrog’s Artifactory repository if you have any (which is recommended). For those that need guidance in installing the jar to your local Maven’s repository, just read on.

Installing the WebLogic Maven Plugin to Maven’s Local Repository

In the same directory as the weblogic-maven-plugin.jar and the pom.xml file, execute the following command:

mvn install:install-file -Dfile=weblogic-maven-plugin.jar -DpomFile=pom.xml

Using and Configuring the WebLogic-Maven-Plugin

After installing the weblogic-maven-plugin.jar to your Maven repository, it is easy to use it off the shelf. Looking back to the DummyDemo-ear module written in Part 1 and Part 2 of the series, 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
    <!-- Reference the parent -->
012
    <parent>
013
        <artifactId>project</artifactId>
014
        <groupId>com.developerscrappad</groupId>
015
        <version>1.0-SNAPSHOT</version>
016
    </parent>
017
 
018
    <!-- The packaging value of any EAR module should be "ear" -->
019
    <packaging>ear</packaging>
020
 
021
    <!--
022
        The dependencies for EAR module should include all thoese sub-modules
023
        that are needed to be packaged into the ear file like the below...
024
    -->
025
    <dependencies>
026
        <dependency>
027
            <groupId>com.developerscrappad</groupId>
028
            <artifactId>DummyDemo-ejb</artifactId>
029
            <version>1.0-SNAPSHOT</version>
030
            <type>ejb</type>
031
        </dependency>
032
        <dependency>
033
            <groupId>com.developerscrappad</groupId>
034
            <artifactId>DummyDemo-web</artifactId>
035
            <version>1.0-SNAPSHOT</version>
036
            <type>war</type>
037
        </dependency>
038
        <dependency>
039
            <groupId>com.developerscrappad</groupId>
040
            <artifactId>DummyDemo-appclient</artifactId>
041
            <version>1.0-SNAPSHOT</version>
042
            <type>app-client</type>
043
        </dependency>
044
        <dependency>
045
            <groupId>com.developerscrappad</groupId>
046
            <artifactId>DummyDemo-api</artifactId>
047
            <version>1.0-SNAPSHOT</version>
048
            <type>jar</type>
049
        </dependency>
050
    </dependencies>
051
 
052
    <build>
053
        <plugins>
054
            <plugin>
055
                <groupId>org.apache.maven.plugins</groupId>
056
                <artifactId>maven-compiler-plugin</artifactId>
057
                <version>2.0.2</version>
058
                <configuration>
059
                    <source>1.5</source>
060
                    <target>1.5</target>
061
                </configuration>
062
            </plugin>
063
            <!--
064
                The ear plugin must include the definition for "modules",
065
                for any modules that are needed to be included in the EAR file,
066
                you need to specify them one by one, e.g. "ejbModule", "webModule",
067
                "jarModule" and "appClientModule".
068
            -->
069
            <plugin>
070
                <groupId>org.apache.maven.plugins</groupId>
071
                <artifactId>maven-ear-plugin</artifactId>
072
                <version>2.6</version>
073
                <configuration>
074
                    <version>5</version>
075
                    <defaultLibBundleDir>lib</defaultLibBundleDir>
076
                    <modules>
077
                        <ejbModule>
078
                            <groupId>com.developerscrappad</groupId>
079
                            <artifactId>DummyDemo-ejb</artifactId>
080
                        </ejbModule>
081
                        <webModule>
082
                            <groupId>com.developerscrappad</groupId>
083
                            <artifactId>DummyDemo-web</artifactId>
084
                            <context-root>/DummyDemo-web</context-root>
085
                        </webModule>
086
                        <jarModule>
087
                            <groupId>com.developerscrappad</groupId>
088
                            <artifactId>DummyDemo-api</artifactId>
089
                        </jarModule>
090
                        <appClientModule>
091
                            <groupId>com.developerscrappad</groupId>
092
                            <artifactId>DummyDemo-appclient</artifactId>
093
                        </appClientModule>
094
                    </modules>
095
                </configuration>
096
            </plugin>
097
 
098
            <!-- Weblogic App Server -->
099
            <plugin> 
100
                <groupId>com.oracle.weblogic</groupId> 
101
                <artifactId>weblogic-maven-plugin</artifactId>
102
 
103
                <!-- PLEASE CHANGE THIS ACCORDINGLY !!! -->
104
                <version>12.1.1.0</version>
105
 
106
                <configuration> 
107
                    <adminurl>t3://localhost:7001</adminurl>
108
                    <user>weblogic</user> 
109
                    <password>wlpasswd1234</password> 
110
                    <upload>true</upload> 
111
                    <action>deploy</action> 
112
                    <remote>false</remote>
113
                    <verbose>true</verbose>
114
                    <source>${basedir}/target/DummyDemo-ear-1.0-SNAPSHOT.ear</source> 
115
                    <name>DummyDemo-ear-1.0-SNAPSHOT.ear</name> 
116
                </configuration> 
117
                <executions> 
118
                    <execution>
119
                        <id>wl-deploy</id>
120
                        <phase>package</phase> 
121
                        <goals> 
122
                            <goal>deploy</goal> 
123
                        </goals> 
124
                    </execution>
125
                    <execution>
126
                        <id>wl-undeploy</id>
127
                        <goals>
128
                            <goal>undeploy</goal>
129
                        </goals>
130
                        <phase>clean</phase>
131
                    </execution>
132
                </executions> 
133
            </plugin> 
134
        </plugins>
135
    </build>
136
 
137
</project>

pom.xml Explained
Looking at the modified pom.xml, the WebLogic Maven Pluging will be used at the <plugin> section. We will still tie the deployment to the Application Server at the “package” build phase and the undeploy from the Application Server at the “clean” build phase. For the configuration section, there are many options available as documented in Oracle’s website, but the above is sufficient for now.

However, I still need to highlight to you that the <version> value of the plugin must match the version of the plugin installed to the Maven repository and the WebLogic Server version used by you. For example, if you are developing on WebLogic Server Version 12.1.1, the weblogic-maven-plugin version and the plugin used in the pom.xml of DummyDemo-ear must be 12.1.1.

A brief explanation on the config options used here (I’ll just explain the important ones):

Option Description
adminurl This is the URL to the running WebLogic server, with the “t3″ protocol as prefix and the default port of 7001. If you run on your local machine, the URL should be t3://localhost:7001/
username The WebLogic admin username
password The WebLogic admin password
remote If the target deployment server is located remotely, please set the value to “true“. But if you are just deploying it on a local server, set it to “false“.
source The location of the target EAR file for deployment.
name Name of the deployed application (not necessary to be the name of the EAR file).

The Right Dependency For Integration Test

One of the beautiful things about running integration test against WebLogic is that the dependencies are clean and you mostly likely only require the weblogic-maven-plugin.jar for all the necessary Java EE libraries. Since the jar is already present in the local Maven repository, it doesn’t need to perform a remote download through the net during compilation and the process is speedier.

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

 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"
03
         xmlns="http://maven.apache.org/POM/4.0.0"
04
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
05
 
06
    <!-- Basic Properties -->
07
    <modelVersion>4.0.0</modelVersion>
08
    <groupId>com.developerscrappad</groupId>
09
    <artifactId>integration-test</artifactId>
10
    <version>1.0-SNAPSHOT</version>
11
    <name>integration-test</name>
12
 
13
    <!-- Reference the parent -->
14
    <parent>
15
        <groupId>com.developerscrappad</groupId>
16
        <artifactId>DummyDemoJavaEE5</artifactId>
17
        <version>1.0-SNAPSHOT</version>
18
    </parent>
19
 
20
    <!-- Define the necessary dependencies for running the integration test -->
21
    <dependencies>
22
        <dependency>
23
            <groupId>com.oracle.weblogic</groupId>
24
            <artifactId>weblogic-maven-plugin</artifactId>
25
            <version>12.1.1.0</version>
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 **/utest/ 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
        </plugins>
71
    </build>
72
</project>

Some changes in JNDI names for calling Session Beans

Calling remote session beans from WebLogic is some what weird as compare to Glassfish 3.x or JBoss 5.x & 6.x. Taking the com.developerscrappad.ejb.BMPFacade for example in the DummyDemo-ejb module as an example, the bean class has annotations like the below:

 Java(TM) 2 Platform Standard Edition 5.0 |  copy code |? 
1
@Stateless( name = "BMPFacade", mappedName = "ejb/BMPFacade" )
2
@TransactionManagement( TransactionManagementType.BEAN )
3
public class BMPFacade implements IBMPFacadeLocal, IBMPFacadeRemote {
4
    // The rest of the implementation...
5
}

In both Glassfish and JBoss, we could just get the remote bean instance through a simple JNDI name of “ejb/BMPFacade” and cast it to IBMPFacadeRemote. But for WebLogic, the calling JNDI name would have to be appended with the full package class name of the remote interface, e.g. “ejb/BMPFacade#com.developerscrappad.intf.IBMPFacadeRemote“.

So, in order to accomodate this behaviour, we’ll have to change the JNDI_NAME static variable in the remote interfaces as it is used to be accessed by integration test classes for conveniently invoking the remote bean.

Please edit the below classes in <path>DummyDemoJavaEE5/project/DummyDemo-ejb/src/main/java to the below:

Codes for com.developerscrappad.intf.IBMPFacadeRemote:

 Java(TM) 2 Platform Standard Edition 5.0 |  copy code |? 
1
package com.developerscrappad.intf;
2
 
3
import javax.ejb.Remote;
4
 
5
@Remote
6
public interface IBMPFacadeRemote extends IBMPFacadeLocal {
7
    public static final String JNDI_NAME = "ejb/BMPFacade#" + IBMPFacadeRemote.class.getName();
8
}

Codes for com.developerscrappad.intf.ICMPFacadeRemote:

 Java(TM) 2 Platform Standard Edition 5.0 |  copy code |? 
1
package com.developerscrappad.intf;
2
 
3
import javax.ejb.Remote;
4
 
5
@Remote
6
public interface ICMPFacadeRemote extends ICMPFacadeLocal {
7
    public static final String JNDI_NAME = "ejb/CMPFacade#" + ICMPFacadeRemote.class.getName();
8
}

Some 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
		//This is specific to Weblogic, please change the environment variables for different app server accordingly.
023
        env = new Properties();
024
        env.setProperty(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
025
        env.setProperty(Context.PROVIDER_URL, "t3://localhost:7001");
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
		//This is specific to Weblogic, please change the environment variables for different app server accordingly.
022
        env = new Properties();
023
        env.setProperty(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
024
        env.setProperty(Context.PROVIDER_URL, "t3://localhost:7001");
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

 Java(TM) 2 Platform Standard Edition 5.0 |  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
        //This is specific to Weblogic, please change the environment variables for different app server accordingly.
033
        env = new Properties();
034
        env.setProperty(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
035
        env.setProperty(Context.PROVIDER_URL, "t3://localhost:7001");
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
}

Bug Alert !!!

Before you proceed any further, there is a bug that affects entity classes when being deploy to WebLogic 10.3.x. Please read this article on Quick Fix: Weblogic 10.3.x – How To Solve "org.apache.openjpa.persistence.InvalidStateException: Detected reentrant flush…" and attend to the change on the Entity classes before moving forward. WebLogic 12c is fine.

EAR Deployment Step-By-Step

Ok, now that you’ve gotten everything in order and the WebLogic server is assumed to be running. Just follow the below steps to deploy the EAR file.

Step 1: Deploying the EAR File to the WebLogic Application Server

If anything goes wrong from here, 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 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. 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 WebLogic 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 2: How to Undeploy or Redeploy the EAR to WebLogic Server

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 WebLogic Server.

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

Summary on Part 5

Besides the part in getting WebLogic Maven Plugin to be compiled and loaded into the Maven’s repository, I love the straight forward and clean dependency of using the WebLogic Maven Plugin as it is not only a plugin for communicating with the Application Server for deployment, it consists of many Java EE depending libraries to be used as one jar in the Java EE project. Unlike Glassfish or JBoss, which we have to define stacks of repositories and dependencies, WebLogic’s way of doing things is clean, neat and worked out of the box.

I hope you’ve find this article useful and glad to have you reading.

To Be Continue…

From this point onwards, I should be able to find time to document the way to deploy the Java EE EAR file to IBM’s WebSphere through Maven. So stay tune and thank you for reading.

Related Articles:

Previous Posts

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[...]

Making sense of EJB3.x Transaction Attributes – Part 4 (NEVER)

Making sense of EJB3.x Transaction Attributes – Part 4 (NEVER)

September 5th, 2012

This is the last part in the series of "Making sense of EJB3.x Transaction Attributes". So far, we'v[...]

Making sense of EJB3.x Transaction Attributes – Part 3 (Difference Between SUPPORTS and NOT_SUPPORTED)

Making sense of EJB3.x Transaction Attributes – Part 3 (Difference Between SUPPORTS and NOT_SUPPORTED)

September 5th, 2012

Oracle had extensively documented the behavior of each transaction attributes in the Java EE documen[...]