I’ve spent several days, off and on, wrestling with a chicken-and-egg configuration issue.
I have an application that uses Spring 2.0 and is deployed to Tomcat 5.5. We make heavy use of Tomcat’s JNDI for configuring things like our database connections.
We’re adding JMS functionality to our application; at this point, we merely need to send events to an existing Tibco EMS 4.4 Topic.
Following the various online tutorials, I was able to use Spring to make my JMS code very lightweight. I was pretty happy with things overall, until I encountered the final problem of setting up the configuration.
The Tibco EMS Server provides its own JNDI services, which I need to connect to the correct topic connection factory. I can use Spring’s JndiTemplate to configure this additional JNDI connection, but I kept hitting one problem. In every environment I’m going to deploy to, the value for java.naming.provider.url will be different. Because JndiTemplate is using
for setting the environment, I can’t use a separate JNDI lookup to populate that value out of Tomcat’s JNDI.
I needed to abstract this value out of my war file, into a configuration file that can stay on each server, so I don’t have to change it every time. This is an application that gets deployed fresh each new revision, and the client wasn’t going to be happy to have to extract the war file and then edit a config file, when that’s never been needed in the past. In addition, each server we’re deploying to already has a JNDI configuration for the Tibco EMS server. But, no matter how I tried, I could not find a way to configure the Tomcat JNDI to let me access those values from the Spring configuration file within the application.
The solution I found that finally worked was to use a PropertyPlaceholderConfigurer that pointed to a file in the tomcat conf directory. The final hurdle I had to jump was the correct configuration. If I used property=”location” value=”${catalina.home}/conf/jms.properties”, Spring would attempt to resolve the value from the servlet container by prepending a slash in front of the catalina.home directory. If I attempted to use a relative path, tomcat wouldn’t allow me open and read the file. I finally hit on prefixing the path with “file:” which was the magic to let Spring know I meant an absolute file path.
I am annoyed I have to add a configuration file, but at least it’s one more place where we can set the value and forget about it for future deployments.
In case anybody hits this combination of problems, here’s what finally worked:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd"> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>file:${catalina.home}/conf/jms.properties</value> <value>/WEB-INF/jdbc.properties</value> </list> </property> </bean> <bean id="messageSender" class="com.stevideter.spring.jms.MessageSender"> <property name="jmsTemplate" ref="jmsTemplate" /> </bean> <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory" ref="topicConnectionFactory" /> <property name="defaultDestinationName"> <jee:jndi-lookup jndi-name="java:comp/env/jms/eventdestname"/> </property> <property name="pubSubDomain" value="true" /> </bean> <bean id="topicConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiTemplate" ref="jndiTemplate"/> <property name="jndiName" value="FTTopicConnectionFactory"/> </bean> <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate"> <property name="environment"> <props> <prop key="java.naming.factory.initial"> com.tibco.tibjms.naming.TibjmsInitialContextFactory </prop> <prop key="java.naming.provider.url"> ${jms.jndicontexturl} </prop> </props> </property> </bean> </beans>
September 3rd, 2008 at 5:53 am
Hi Stevi,
I have been struggling for last couple of days to configure TIBCO EMS from WebSphere environment. This is the configurations.
I get invalid username and password error when I try to post message to corresponding Topic. I have tried various things w/o any success.
com.tibco.tibjms.naming.TibjmsInitialContextFactory
tcp://EMS-UAT-001.aholdusa.com:26874,tcp://EMS-UAT-002.aholdusa.com:26874
tibusr
tibusr
Please let me know if you see anything obvious here. Also, I do not want to create JNDI entry in WebSphere environment. It should be done through config file at runtime.
Thanks,
- Vikas Kadam
vikas.kadam@ahold.com
September 3rd, 2008 at 8:30 am
Vikas,
Are you able to log into the EMS servers directly using those passwords (e.g. using the EMS Administration Tool)?
How are you setting the username and password into the session?
Based on the error, that’s where I’d start looking, but don’t know if this is useful to what you’ve already tried.
September 5th, 2008 at 11:14 am
[...] a comment to my previous post about configuring JMS via Spring, Vikas Kadam asked about configuring a connection to a secure TIBCO EMS topic or queue. As fate [...]