why use JndiObjectFactoryBean to config JNDI datasource did not work?
Solution 1
The actual lookup in JndiObjectFactoryBean is done in the lifecycle callback method. Either call the method explictly in your @Bean method like this (workaround)
@Bean
public DataSource dataSource(){
JndiObjectFactoryBean jndiObjectFactoryBean =new JndiObjectFactoryBean();
jndiObjectFactoryBean.setJndiName("jdbc/SpittrDS");
jndiObjectFactoryBean.setResourceRef(true);
jndiObjectFactoryBean.setProxyInterface(DataSource.class);
jndiObjectFactoryBean.afterPropertiesSet();
return (DataSource) jndiObjectFactoryBean.getObject(); //NULL!!!
}
Or the better approach. Let your @Bean method return the JndiObjectFactoryBean and manage its lifecyle. Then in your dependent beans that require a DataSource inject the datasource created from the factory
@Bean
public JndiObjectFactoryBean dataSource(){
JndiObjectFactoryBean jndiObjectFactoryBean =new JndiObjectFactoryBean();
jndiObjectFactoryBean.setJndiName("jdbc/SpittrDS");
jndiObjectFactoryBean.setResourceRef(true);
jndiObjectFactoryBean.setProxyInterface(DataSource.class);
return jndiObjectFactoryBean;
}
//in your dependnecy
@Bean
public SomeBean someBean(DataSource dataSource){
//use the injected datasource shich comes from the factory
}
Solution 2
I landed here without realizing this was a problem I had faced in the past - Error Casting Spring's JndiObjectFactoryBean to ConnectionFactory for Solace-MQ JMS
So a workaround (not the preferred way) is to call afterPropertiesSet() on jndiObjectFactoryBean before attempting to getObject()
@Bean
public DataSource dataSource(){
JndiObjectFactoryBean jndiObjectFactoryBean =new JndiObjectFactoryBean();
jndiObjectFactoryBean.setJndiName("jdbc/SpittrDS");
jndiObjectFactoryBean.setResourceRef(true);
jndiObjectFactoryBean.setProxyInterface(DataSource.class);
jndiObjectFactoryBean.afterPropertiesSet();
return (DataSource) jndiObjectFactoryBean.getObject(); //NOT NULL
}
![TIMFUNNY](https://i.stack.imgur.com/sI467.jpg?s=256&g=1)
Comments
-
TIMFUNNY almost 2 years
when I uss Java-base to config my JNDI. Spring 4.2.5.
But If I use JndiObjectFactoryBean to config.when I want to get the
datasource
,the object will be null.@Bean public DataSource dataSource(){ JndiObjectFactoryBean jndiObjectFactoryBean =new JndiObjectFactoryBean(); jndiObjectFactoryBean.setJndiName("jdbc/SpittrDS"); jndiObjectFactoryBean.setResourceRef(true); jndiObjectFactoryBean.setProxyInterface(DataSource.class); return (DataSource) jndiObjectFactoryBean.getObject(); //NULL!!! }
But if change the method to this,it work well.
@Bean public DataSource dataSource(){ final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup(); dsLookup.setResourceRef(true); DataSource dataSource = dsLookup.getDataSource("java:comp/env/jdbc/SpittrDS"); return dataSource; }
I do not know where is the problem.
Tomcat 9.0 context.xml
<Context> <!-- Default set of monitored resources. If one of these changes, the --> <!-- web application will be reloaded. --> <WatchedResource>WEB-INF/web.xml</WatchedResource> <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource> <!-- Uncomment this to disable session persistence across Tomcat restarts --> <!-- <Manager pathname="" /> --> <Resource name="jdbc/SpittrDS" auth="Container" type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/spittrds" username="root" password="1" maxActive="100" maxIdle="20" minIdle="5" maxWait="10000"/> </Context>
-
TIMFUNNY about 8 yearsI want to know why this method
jndiObjectFactoryBean.getObject()
returnnull
-
ekem chitsiga about 8 yearsAs i said the actual lookup is done in the afterPropertiesSet method which Spring calls after the bean has been created. Before that call the object wont have been retrieved from JNDI.
-
Mrinal about 6 yearsIf I have multiple Data sources, then how to select specific one in someBean() ?
-
hello_earth over 2 yearscheck out also here for people struggling with Spring trying to initialize data sources too early, when they cannot yet be looked up via JNDI (it seems) - i couldn't get this to work, but it seems warmer there: stackoverflow.com/questions/32776410/…