- Open Weblogic Admin Console.
- Navigate to Services/Messaging/JMS Modules.
- Click "New" to create a new module. Give the new module name "DemoModule". Then click on "Next". Choose the target server and click on "Next". Click "Finish" and then "Activate Changes" to finish the creation of the module.
- Now it is back on the JMS Modules main page. Click on "DemoModule".
- Click "Edit" and "New". The next page will show a list of resources that can be created. Click on "Foreign Server" and "Next".
- Give the foreign server a name "DemoForeignServer" and click on "Next".
- The next page will show that the target server has been selected. Just click on "Finish" and "Activate Changes".
- Click on "DemoForeignServer". Give the value for "JNDI Initial Context Factory" and "JNDI Connection URL". Note that the JNDI connection URL can be an LDAP url with the format "ldap://......". Click "Save" and "Activate Changes".
- Now on the same page, click on the tab "Connection Factories".
- Click "New". Specify the name, the local JNDI name and the remote JNDI name for the connection factory. The remote JNDI name must be a valid name that is already configured on the actual third party JMS provider. You can use a local JNDI name as you like. Suppose the local JNDI name is "demoLocalForeignConnectionFactoryJNDIName". You can optionally configure a user name and password to secure the foreign factory. Click "OK" and "Activate Changes".
- Click on "Destinations" tab. Click on "New".
- Specify the name, the local JNDI name and the remote JNDI name for the destination for the destination. The remote JNDI name must be a valid name that is already configured on the actual third party JMS provider. You can pick a local JNDI name as you like. Suppose the local JNDI name is "demoLocalForeignDestinationJNDIName". Click "OK" and "Activate Changes".
Sample Spring JMS configuration File
If you are using Springframework, you can configure the JMS beans as in the following file. Note that the message sender and listener use the same destination in this file. In the actual application, they should be different.<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//Spring//DTD Bean//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <!-- Application Context --> <beans> <bean id="jmsQueueConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"> <value>demoLocalForeignConnectionFactoryJNDIName</value> </property> </bean> <bean id="myDestination" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"> <value>demoLocalForeignDestinationJNDIName</value> </property> </bean> <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory"> <ref bean="jmsQueueConnectionFactory" /> </property> <property name="defaultDestination"> <ref bean="myDestination" /> </property> </bean> <bean id="jmsSender" class="com.mycompany.myapp.server.common.jms.JmsSender"> <property name="jmsTemplate"> <ref bean="jmsTemplate" /> </property> </bean> <bean id="messageListener" class="com.mycompany.myapp.server.common.jms.ExampleListener"> </bean> <bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"> <property name="connectionFactory" ref="jmsQueueConnectionFactory" /> <property name="destination" ref="myDestination" /> <property name="sessionAcknowledgeModeName" value="AUTO_ACKNOWLEDGE" /> <property name="messageListener" ref="messageListener" /> <property name="sessionTransacted" value="true" /> </bean> </beans>
Suppose the name of the above file is myapp-spring-jms.xml. Then in the web.xml, add the following parameter:
<context-param> <param-name>contextConfigLocation<param-name> <param-value>/WEB-INF/myapp-spring-jms.xml</param-value> </context-param>
The Sample Message Sender
The sample java class to send the message. This class implements the interface IJmsSender, which is a user defined interface. Its only method is sendMessage(String). The interface is just for the Spring bean configuration purpose. With this interface, other Spring beans can use IJmsSender to inject an instance of JmsSender.package com.mycompany.myapp.server.common.jms; public interface IJmsSender { public void sendMessage(final String message); }
package com.mycompany.myapp.server.common.jms; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.Session; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.jms.core.JmsTemplate; import org.springframework.jms.core.MessageCreator; public class JmsSender implements IJmsSender { private static Log log = LogFactory.getLog(Test.class); private JmsTemplate jmsTemplate; public JmsTemplate getJmsTemplate() { return jmsTemplate; } public void setJmsTemplate(JmsTemplate jmsTemplate) { this.jmsTemplate = jmsTemplate; } public void sendMessage(final String message) { jmsTemplate.send(new MessageCreator() { public Message createMessage(Session session) throws JMSException { log.debug("Creating the message from text " + message); Message textMsg = session.createTextMessage(message); return textMsg; } }); } }
The Sample Message Listener
The samle JMS listener to receive the message:package com.mycompany.myapp.server.common.jms; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageListener; import javax.jms.TextMessage; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class ExampleListener implements MessageListener { private static Log logger = LogFactory.getLog(ExampleListener.class); public void onMessage(Message message) { logger.info("onMessage() message=" + message); if (message instanceof TextMessage) { try { logger.info(((TextMessage) message).getText()); // process message } catch (JMSException ex) { throw new RuntimeException(ex); } } else { logger.info("non-TextMessage"); } } }
A Sample WLST Script to Create the JMS Foreign Server
Note that this file was obtained by editing the script generated by the WLST configToScripy command. Suppose the name of this file is config_tibco.py. It loads the property file config_tibco.py.properties. To run the configuration, first execute C:\bea921\weblogic92\common\bin\wlst.cmd. Then under the prompt wls:/offline> typeexecfile('c:/workshop/myApp/temp/config_tibco.py')
""" @author Copyright (c) 2004-2005 by BEA Systems, Inc. All Rights Reserved. This script will first try to connect to a running server using the values in the properties file. If there is no server running, WLST will start a server with the values in the properties file. You should change these values to suit your environmental needs. After running the script, the server that is started(if started one) will be shutdown. This might exit you from your WLST shell.""" from weblogic.descriptor import BeanAlreadyExistsException from java.lang.reflect import UndeclaredThrowableException from java.lang import System import javax from javax import management from javax.management import MBeanException from javax.management import RuntimeMBeanException import javax.management.MBeanException from java.lang import UnsupportedOperationException def initConfigToScriptRun(): global startedNewServer loadProperties("c:/workshop/myApp/temp/config_tibco.py.properties") hideDisplay() hideDumpStack("true") # try connecting to a running server if it is already running ... if connected=="false": try: URL="t3://"+adminServerListenAddress+":"+adminServerListenPort connect(userName, passWord, URL) except WLSTException: print 'No server is running at '+URL+', the script will start a new server' hideDumpStack("false") if connected=="false": print 'Starting a brand new server at '+URL+' with server name '+adminServerName print 'Please see the server log files for startup messages available at '+domainDir # If a config.xml exists in the domainDir, WLST will use that config.xml to bring up the server. # If you would like WLST to overwrite this directory, you should specify overWriteRootDir='true' as shown below # startNewServer(adminServerName, domName, URL, userName, passWord,domainDir, overWriteRootDir='true') _timeOut = Integer(TimeOut) # If you want to specify additional JVM arguments, set them using startServerJvmArgs in the property file or below _startServerJvmArgs=startServerJvmArgs if (_startServerJvmArgs=="" and (System.getProperty("java.vendor").find("Sun")>=0 or System.getProperty("java.vendor").find("Hewlett")>=0)): _startServerJvmArgs = " -XX:MaxPermSize=128m" if overWriteRootDir=='true': startServer(adminServerName, domName, URL, userName, passWord,domainDir, timeout=_timeOut.intValue(), overWriteRootDir='true', block='true', jvmArgs=_startServerJvmArgs) else: startServer(adminServerName, domName, URL, userName, passWord,domainDir, timeout=_timeOut.intValue(), block='true', jvmArgs=_startServerJvmArgs) startedNewServer=1 print "Started Server. Trying to connect to the server ... " connect(userName, passWord, URL) if connected=='false': stopExecution('You need to be connected.') def startTransaction(): edit() startEdit() def endTransaction(): startEdit() save() activate(block="true") from javax.management import InstanceAlreadyExistsException from java.lang import Exception from jarray import array def endOfConfigToScriptRun(): global startedNewServer #Save the changes you have made # shutdown the server you have started if startedNewServer==1: print 'Shutting down the server that is started... ' shutdown(force='true', block='true') print 'Done executing the script.' def create_JMSSystemResource_0(path, beanName): cd(path) try: print "creating mbean of type JMSSystemResource ... " theBean = cmo.lookupJMSSystemResource(beanName) if theBean == None: cmo.createJMSSystemResource(beanName) except java.lang.UnsupportedOperationException, usoe: pass except weblogic.descriptor.BeanAlreadyExistsException,bae: pass except java.lang.reflect.UndeclaredThrowableException,udt: pass def create_ForeignServer_4(path, beanName): cd(path) try: print "creating mbean of type ForeignServer ... " theBean = cmo.lookupForeignServer(beanName) if theBean == None: cmo.createForeignServer(beanName) except java.lang.UnsupportedOperationException, usoe: pass except weblogic.descriptor.BeanAlreadyExistsException,bae: pass except java.lang.reflect.UndeclaredThrowableException,udt: pass def create_ForeignDestination_6(path, beanName): cd(path) try: print "creating mbean of type ForeignDestination ... " theBean = cmo.lookupForeignDestination(beanName) if theBean == None: cmo.createForeignDestination(beanName) except java.lang.UnsupportedOperationException, usoe: pass except weblogic.descriptor.BeanAlreadyExistsException,bae: pass except java.lang.reflect.UndeclaredThrowableException,udt: pass def create_ForeignConnectionFactory_8(path, beanName): cd(path) try: print "creating mbean of type ForeignConnectionFactory ... " theBean = cmo.lookupForeignConnectionFactory(beanName) if theBean == None: cmo.createForeignConnectionFactory(beanName) except java.lang.UnsupportedOperationException, usoe: pass except weblogic.descriptor.BeanAlreadyExistsException,bae: pass except java.lang.reflect.UndeclaredThrowableException,udt: pass def setAttributesFor_TibcoForeignServer_13(): cd("/JMSSystemResources/myAppTibcoJMSModule/JMSResource/myAppTibcoJMSModule/ForeignServers/TibcoForeignServer") print "setting attributes for mbean type ForeignServer" set("InitialContextFactory", "com.tibco.tibjms.naming.TibjmsInitialContextFactory") set("DefaultTargetingEnabled", "true") set("Name", "TibcoForeignServer") set("ConnectionURL", "ldap://a_valid_url_here") def setAttributesFor_myAppTibcoFCF_17(): cd("/JMSSystemResources/myAppTibcoJMSModule/JMSResource/myAppTibcoJMSModule/ForeignServers/TibcoForeignServer/ForeignConnectionFactories/myAppTibcoFCF") print "setting attributes for mbean type ForeignConnectionFactory" set("LocalJNDIName", "jms/testTibcoFCF") set("Name", "myAppTibcoFCF") set("RemoteJNDIName", "a_valid_remote_JNDI_ForConnectionFactory") def setAttributesFor_testTibcoQueueForeignDestination_15(): cd("/JMSSystemResources/myAppTibcoJMSModule/JMSResource/myAppTibcoJMSModule/ForeignServers/TibcoForeignServer/ForeignDestinations/testTibcoQueueForeignDestination") print "setting attributes for mbean type ForeignDestination" set("LocalJNDIName", "jms/testTibcoQueueDestination") set("Name", "testTibcoQueueForeignDestination") set("RemoteJNDIName", "a_valid_remote_JNDI_for_destination") def setAttributesFor_myAppTibcoJMSModule_11(): cd("/JMSSystemResources/myAppTibcoJMSModule") print "setting attributes for mbean type JMSSystemResource" refBean0 = getMBean("/Servers/myAppAdminServer") theValue = jarray.array([refBean0], Class.forName("weblogic.management.configuration.TargetMBean")) cmo.setTargets(theValue) try: initConfigToScriptRun() startTransaction() create_JMSSystemResource_0("/", "myAppTibcoJMSModule") create_ForeignServer_4("/JMSSystemResources/myAppTibcoJMSModule/JMSResource/myAppTibcoJMSModule", "TibcoForeignServer") create_ForeignDestination_6("/JMSSystemResources/myAppTibcoJMSModule/JMSResource/myAppTibcoJMSModule/ForeignServers/TibcoForeignServer", "testTibcoQueueForeignDestination") create_ForeignConnectionFactory_8("/JMSSystemResources/myAppTibcoJMSModule/JMSResource/myAppTibcoJMSModule/ForeignServers/TibcoForeignServer", "myAppTibcoFCF") setAttributesFor_myAppTibcoJMSModule_11() setAttributesFor_TibcoForeignServer_13() setAttributesFor_testTibcoQueueForeignDestination_15() setAttributesFor_myAppTibcoFCF_17() endTransaction() finally: endOfConfigToScriptRun()
Sample Property File for WLST Script
#WLST ConfigToScript Default Properties file #Mon Mar 29 09:53:26 EDT 2010 exitonerror=false adminServerListenAddress=localhost adminServerName=myAppAdminServer domName=myAppwls9loc overWriteRootDir=false TimeOut=240000 startedNewServer=0 domainDir=C:/bea921/user_projects/domains/myAppwls9loc userName=wlsadmin passWord=wlsadmin1 adminServerListenPort=7001 startServerJvmArgs=
Reference
1. http://download.oracle.com/docs/cd/E13222_01/wls/docs92/ConsoleHelp/taskhelp/jms_modules/foreign_servers/ConfigureForeignServers.html2. http://forum.springsource.org/showthread.php?t=34180