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.
- A queue manager accessible from a client connection
- A “server queue” Q1
- A reply to queue CP0000
- 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
- An existing JNDI repository configured with a connection factory and “server queue”.
- 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.
- 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.
- A webLogic server. I used WebLogic Server Version: 220.127.116.11.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.
- Within the MDB configuration definitions.
- 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
Name : SystemModule-0
Target: select from the pull down, Adminserver
Select “Would you like to add resources to this JMS system module?”
Select the JMS module you just created (SystemModule-0)
Summary of resources
Select: Foreign server
JNDI Initial Context Factory: com.sun.jndi.fscontext.RefFSContextFactory
JNDI Connection URL: file:/home/colinpaice/JNDI-Directory
credential leave emtpy
Click ‘Connection Factories’ tab
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
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
then back to the orignal window and issue
./wls12213/user_projects/domains/base_domain/startWebLogic.sh 1>a 2>b
The application, here, was based on the IBM provided sample for MQ on WAS
in the directory MDB
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
PUBLIC ‘-//BEA Systems, Inc.//DTD WebLogic 8.1.0 EJB//EN’
<!– I think the value of this ejb-name matches the value in META-INF/ejb-jar.xml ->
<!– define the number of listener threads that can be used, maximum and initial –>
<!– JNDI defintitions →
<!– Specify the class needed to process the JNDI repository –>
<!– specify which JNDI repository to use –>
<!– look in the JNDI file for the definitions with JMSQ1 –>
<!– look in the JNDI file for the connection factory → MQ channel etc–>
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
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
enter the path to the directory with your jar file
select jar file
Install as application
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
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
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.