import org.apache.catalina.Context; import org.apache.catalina.deploy.ContextResource; import org.apache.catalina.startup.Tomcat; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer; import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer; import org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer; import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer; import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ImportResource; @Configuration @EnableAutoConfiguration @ComponentScan @ImportResource("classpath:applicationContext.xml") public class Application { public static void main(String[] args) throws Exception { new SpringApplicationBuilder() .showBanner(false) .sources(Application.class) .run(args); } @Bean public TomcatEmbeddedServletContainerFactory tomcatFactory() { return new TomcatEmbeddedServletContainerFactory() { @Override protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer( Tomcat tomcat) { tomcat.enableNaming(); return super.getTomcatEmbeddedServletContainer(tomcat); } }; } @Bean public EmbeddedServletContainerCustomizer embeddedServletContainerCustomizer() { return new EmbeddedServletContainerCustomizer() { @Override public void customize(ConfigurableEmbeddedServletContainer container) { if (container instanceof TomcatEmbeddedServletContainerFactory) { TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory = (TomcatEmbeddedServletContainerFactory) container; tomcatEmbeddedServletContainerFactory.addContextCustomizers(new TomcatContextCustomizer() { @Override public void customize(Context context) { ContextResource mydatasource = new ContextResource(); mydatasource.setName("jdbc/mydatasource"); mydatasource.setAuth("Container"); mydatasource.setType("javax.sql.DataSource"); mydatasource.setScope("Sharable"); mydatasource.setProperty("driverClassName", "oracle.jdbc.driver.OracleDriver"); mydatasource.setProperty("url", "jdbc:oracle:thin:@mydomain.com:1522:myid"); mydatasource.setProperty("username", "myusername"); mydatasource.setProperty("password", "mypassword"); context.getNamingResources().addResource(mydatasource); } }); } } }; } }
I'm using spring boot and trying to startup with an embedded tomcat that creates a JNDI context for my datasources:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> <version>1.1.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <version>1.1.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-oracle</artifactId> <version>1.0.0.RELEASE</version> </dependency> If I remove the @ImportResource my application starts up just fine. I can connect to the tomcat instance. I can check all of my actuator endpoints. Using JConsole, I can connect to the application I can see my datasource in the MBeans (Catalina -> Resource -> Context -> "/" -> localhost -> javax.sql.DataSource -> jdbc/mydatasource)
I also have MBeans showing up, via JConsole, here (Tomcat -> DataSource -> / -> localhost -> javax.sql.DataSource -> jdbc/mydatasource)
However, when I @ImportResource what is actually looking for mydatasource via JNDI, it's not finding it.
<bean id="myDS" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="java:comp/env/jdbc/mydatasource"/> </bean> The relevant part of my imported xml file
The ContextResource that I'm configuring above is with the exact same parameters that I was using in the context.xml that is getting deployed when the application is deployed to a tomcat container. My imported beans and my application are working properly when deployed to a tomcat container.
So it appears that I have a context now, but it doesn't appear that the naming is right. I've tried to various combinations of the resource name, but can't seem to generate a "comp" bound in this context.
Caused by: javax.naming.NameNotFoundException: Name [comp/env/jdbc/mydatasource] is not bound in this Context. Unable to find [comp]. at org.apache.naming.NamingContext.lookup(NamingContext.java:819) at org.apache.naming.NamingContext.lookup(NamingContext.java:167) at org.apache.naming.SelectorContext.lookup(SelectorContext.java:156) at javax.naming.InitialContext.lookup(InitialContext.java:392) at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:155) at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:87) at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:152) at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:179) at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:95) at org.springframework.jndi.JndiObjectLocator.lookup(JndiObjectLocator.java:106) at org.springframework.jndi.JndiObjectFactoryBean.lookupWithFallback(JndiObjectFactoryBean.java:231) at org.springframework.jndi.JndiObjectFactoryBean.afterPropertiesSet(JndiObjectFactoryBean.java:217) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549) ... 30 more