JNDI properties (java.naming.factory.initial & java.naming.provider.url) not getting set through Spring's PropertyPlaceholderConfigurer

StackOverflow https://stackoverflow.com/questions/22646004

Question

I have configured the following PropertyPlaceholderConfigurer

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="file:///opt/myproject/jndi.properties" />
</bean>

And my JNDI template bean looks like

<bean id="myJndiTemplate" class="org.springframework.jndi.JndiTemplate">
    <property name="environment">
        <props>
            <prop key="java.naming.factory.initial">${factory}</prop>
            <prop key="java.naming.provider.url">${url}</prop>
        <props>
    </property>
</bean>

jndi.properties file has two keys defined.

factory=org.webmethods.jms.naming.WmJmsNamingCtxFactory
url=wmjmsnaming://MY_BROKER@abc.com:7001

When i deploy this on weblogic and start the application, i see the following trace

nested exception is javax.naming.NoInitialContextException: Cannot instantiate class: ${factory} [Root exception is java.lang.ClassNotFoundExcep
tion: ${factory}]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:529)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:628)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
        at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389)
        at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294)
        at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
        at weblogic.servlet.internal.EventsManager$FireContextListenerAction.run(EventsManager.java:481)
        at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
        at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
        at weblogic.servlet.internal.EventsManager.notifyContextCreatedEvent(EventsManager.java:181)
        at weblogic.servlet.internal.WebAppServletContext.preloadResources(WebAppServletContext.java:1868)
        at weblogic.servlet.internal.WebAppServletContext.start(WebAppServletContext.java:3154)
        at weblogic.servlet.internal.WebAppModule.startContexts(WebAppModule.java:1518)
        at weblogic.servlet.internal.WebAppModule.start(WebAppModule.java:484)

Spring isn't replacing ${factory} witht he value from the properties file but considers ${factory} as the value and thus shows a class not found exception. If i hardcode the factory class name and the url, it works fine. I am not sure whats missing here as i am not able to figure out whats really the issue.

Appreciate any help or pointers on this.

Était-ce utile?

La solution 2

You can also use springs PropertiesFactoryBean like this

<bean class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="location" value="file:///opt/myproject/jndi.properties" />
</bean>

Autres conseils

I found another simpler approach that doesn't need an extra class. i used org.springframework.beans.factory.config.PropertiesFactoryBean to load the jndi.properties

The jndiTemplate bean looks something like this.

<bean id="myJndiTemplate" class="org.springframework.jndi.JndiTemplate">
    <property name="environment">
        <bean class="org.springframework.beans.factory.config.PropertiesFactoryBean">
             <property name="location" value="file:///opt/myproject/jndi.properties" />
        </bean>
    </property>
</bean>

I managed to find a workaround solution which did work for me. Created my own JndiTemplate and read the jndi.properties file explicitly from the server. The custom class looks something like this

public class MyJndiTemplate extends JndiTemplate {

    @Override
    protected Context createInitialContext() throws NamingException {
        Properties jndiProperties =  new Properties();
        final File file = new File("/opt/myproject/jndi.properties");
        try {
            jndiProperties.load(new FileInputStream(file));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new InitialContext(jndiProperties);
    }
}

and then use this class in the spring context xml like this

<bean id="myJndiTemplate" class="com.MyJndiTemplate">

Hope this helps anyone facing the same issue.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top