Configuring Oracle WebLogic to use MQ Message Drive Beans

I wanted to use webLogic web server from Oracle to look into a performance problem with Java Message Driven Beans using IBM MQ. Setting this up was harder than I expected, because of lack of documentation. Some documentation gave half the story – but nothing gave the complete story.
It took me several days to configure Oracle webLogic server with IBM MQ. I went down many rabbit holes, and had many problems, before finding that, once you know what to ignore, it is not too difficult.
I used

  1. A queue manager accessible from a client connection
  2. A “server queue” Q1
  3. A reply to queue CP0000
  4. A MDB application – I used an IBM IVT file as the basis of my program. This was an existing MDB jar file which had some a webLogic configuration file added to the .jar file
  5. An existing JNDI repository configured with a connection factory and “server queue”.
    1.  My definitions were stored in a file file:/home/colinpaice/JNDI-Directory and this needs the java class com.sun.jndi.fscontext.RefFSContextFactory to access it.
    2.  The JNDI repository had a connection factory CF1 which points to the channel definition, and a queue definition JMSQ1 mapping to queue Q1 in the queue manager.
  6.  A webLogic server. I used WebLogic Server Version: 12.2.1.3.0, also called 12c. I created a new domain, and used this. I logged onto the admin console using URL http://127.0.0.1:7001/console/ .

Note: The JNDI repository is configured in two places.

  1. Within the MDB configuration definitions.
  2.  Within MDB java program logic

Create a profile script for webLogic

I created a configuration script,  here, where I defined Java overrides and gave the webLogic server access to the MQ libraries.
I configured it to use JMX (Java Management eXtensions) which allow you to use a utility called jconsole to display information about what is happening within the web server.

I used the cd command to get to the weblogic directory and used
.    sh profile.sh
to execute the profile

Start the webLogic server

From the weblogic directory
./wls12213/user_projects/domains/colin/startWebLogic.sh 1>a 2>b
1>a and 2>b is useful so you can use another command window to search for lines in the output.

Go to the webLogic admin console in a web browser http://127.0.0.1:7001/console.

Setting up the JMS Server

You do not need to define a webLogic JMS Server to use IBM MQ.

Understanding terms and concepts

I used the webLogic Admin console, taking default names when offered.
A group of deployable MQ resources are defined within a “JMS Module”. You can define different modules and deploy them in different places.

I found that sometimes when I changed the configuration (for example to correct a spelling mistake) the server ignored the update till I restarted the server – despite the web server saying there were no pending changes.

It was safer to restart the server after I changed the configuration. It felt like that when an application is deployed, it remembers the configuration at the time of deployment, rather than looking it up each time.

WebLogic adds another level of indirection to the application. It took me a while to sort this out.

1. The application uses the name of a connection factory, MYCF
2. MYCF is looked up in the “JMS Modules” “ForeignConnectionFactory” “Local JNDI Name” to give the “Remote JNDI Name” (REMCF).
3. “ForeignConnectionFactory”.General gives the location of the JNDI repository to use.
4. The “Remote JNDI Name” (REMCF) is looked up in the JNDI repository to give the channel name and other parameters. (Are you keeping up?)

I found it easiest to call everything the same name eg CF1, and it made understanding the configuration much easier.

My application prints out information about the connection factory. So I could see
com.ibm.mq.jms.MQConnectionFactor – it was MQ, not the webLogic connection factory
XMSC_WMQ_CHANNEL :- SYSTEM.DEF.SVRCONN
XMSC_WMQ_QUEUE_MANAGER :- QMA

Define MQ resources to webLogic.

Home -> Messaging → JMS Modules

New

Name : SystemModule-0
Next

Target: select from the pull down, Adminserver
Next
Select “Would you like to add resources to this JMS system module?”
Finish

Select the JMS module you just created (SystemModule-0)
Summary of resources
New
Select: Foreign server
Next

Name: ForeignServer-0

Finish

Click ForeignServer-0

JNDI Initial Context Factory: com.sun.jndi.fscontext.RefFSContextFactory
JNDI Connection URL: file:/home/colinpaice/JNDI-Directory
credential leave emtpy
Save

Click ‘Connection Factories’ tab
New
Name: ForeignConnectionFactory-0
LocalJNDI name: CF1
This is what my application running on webLogic will use. See the weblogic-ejb-jar.xml file below.

Remote JNDI name: CF1
This is the name in the JNDI repostitory
user name webLogic
The user name that is used to logon to admin console
password
Confirm password

Save

You can use “view changes and restarts” to see what webLogic thinks needs to be restarted.

I found it safer to restart the server, as sometimes changes were not picked up. Ctrl-c from the command window running the webLogic server seems to work, but it is better to use a different window and use
./wls12213/user_projects/domains/base_domain/bin/stopWebLogic.sh
then back to the orignal window and issue

./wls12213/user_projects/domains/base_domain/startWebLogic.sh 1>a 2>b

The application

The application, here, was based on the IBM provided sample for MQ on WAS

in the directory MDB
… META-INF/
… META-INF/MANIFEST.MF
… META-INF/weblogic-ejb-jar.xml
… META-INF/ejb-jar.xml
… ejbs/
… ejbs/IVTMDB.class
… ejbs/IVTMDB.java
…javax.ejb-api-3.2.jar

The ejb-jar.xml file is here.

Each web server seems to have their own way of configuring application. JBoss web server has its own file, and WAS has configuration information in the server.xml file. The webLogic file is given below

… META-INF/weblogic-ejb-jar.xml had

<?xml version=”1.0″?>
<!DOCTYPE weblogic-ejb-jar
PUBLIC ‘-//BEA Systems, Inc.//DTD WebLogic 8.1.0 EJB//EN’
http://www.bea.com/servers/wls810/dtd/weblogic-ejb-jar.dtd’&gt;

<weblogic-ejb-jar>

<weblogic-enterprise-bean>
<!– I think the value of this ejb-name matches the value in META-INF/ejb-jar.xml ->
<ejb-name>WMQ_IVT_MDB</ejb-name>

<message-driven-descriptor>
<!– define the number of listener threads that can be used, maximum and initial –>
<pool>
<max-beans-in-free-pool>10</max-beans-in-free-pool>
<initial-beans-in-free-pool>3</initial-beans-in-free-pool>
</pool>

<!– JNDI defintitions →
<!– Specify the class needed to process the JNDI repository –>
<initial-context-factory>com.sun.jndi.fscontext.RefFSContextFactory

</initial-context-factory>
<!– specify which JNDI repository to use –>
<provider-url>file:/home/colinpaice/JNDI-Directory</provider-url>

<!– look in the JNDI file for the definitions with JMSQ1 –>
<destination-jndi-name>JMSQ1</destination-jndi-name>

<!– look in the JNDI file for the connection factory → MQ channel etc–>
<connection-factory-jndi-name>CF1</connection-factory-jndi-name>

</message-driven-descriptor>
</weblogic-enterprise-bean>
</weblogic-ejb-jar>

Compile the program

javac -cp /opt/mqm/java/lib/*:javax.ejb-api-3.2.jar: ejbs/IVTMDB.java

The javax.ejb-api-3.2.jar came from
https://download.jar-download.com/cache_jars/javax.ejb/javax.ejb-api/3.2/jar_files.zip

Build the jar file

jar -cvf MDB3.jar ejbs/IVTMDB.class META-INF/weblogic-ejb-jar.xml META-INF/ejb-jar.xml

jar -tvf MDB3.jar gave

0 Fri Aug 02 07:08:38 BST 2019 META-INF/
69 Fri Aug 02 07:08:38 BST 2019 META-INF/MANIFEST.MF
3572 Fri Aug 02 07:05:10 BST 2019 ejbs/IVTMDB.class
1197 Wed Jul 31 17:43:08 BST 2019 META-INF/weblogic-ejb-jar.xml
3696 Tue Jul 30 15:16:52 BST 2019 META-INF/ejb-jar.xml

Deploy the MDB

Using the webLogic admin console
Home → Deployment resources → Deployments

Install
enter the path to the directory with your jar file
select jar file
Install as application
Next
Name MDB3
Finish

Check the webLogic error log for problems.

For example, the log showed

<BEA-160228><AppMerge failed to merge your application. If you are running AppMerge on the command-line, merge again with the -verbose option for more details. See the error message(s) below.>

I went into a command window.
Set up the environment using
.      ./wls12213/wlserver/server/bin/setWLSEnv.sh
and ran

java weblogic.appmerge -verbose ~/temp/MDB/MDB3.jar
I fixed any problems.

( If you get Error: Could not find or load main class weblogic.appmerge, you did not enter the setWLSEnv.sh command properly, check the . before the command.)

When it successfully deployed, the webLogic log had
EJBCreate
EJBCreate
EJBCreate
This was 3 instances ( as defined in the weblogic-ejb-jar.xml file) of my program starting up and printing out a message.

Try it out!

My JNDI file had JMSQ1 → Q1.  I ran a program to put a message, to queue Q1, specifying a reply to queue, and it worked!

I put a message to Q1, and a response was returned.

Thanks to Paul Titherage who gave me good advice on getting the Java program compiled, and other pointers to the correct path.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s