我的症状类似于: How to create JNDI context in Spring Boot with Embedded Tomcat Container
我创建了一个 github 存储库来重新创建我的问题:https ://github.com/Rkiouak/spring-boot-embedded-tomcat-hibernate-jndi (请注意,您可能需要手动添加 oracle 依赖项,因为 oracle 会阻止发布其jar 到公共 maven 存储库)
克隆 repo,进入它并 mvn clean && mvn package && java -jar target/spring-boot-sample-tomcat-jndi-0.1.0-SNAPSHOT.jar 将重现 NameNotFound execption。
任何人都可以帮助我了解需要更改哪些配置才能使用 tomcat 8 和带有 jndi 的最新 spring-boot 版本(可能使休眠变得复杂)?
问题的详细描述:
先前答案的解决方案对我不起作用,我怀疑新版本中存在依赖问题,或者与休眠方式/何时执行 jndi 查找有关。
但是,我已经克隆了https://github.com/wilkinsona/spring-boot-sample-tomcat-jndi,将其 Spring Boot 依赖项更新为 LATEST,更新了由此新版本产生的 tomcat 包/导入并从 Tomcat 7到Tomcat 8并让它运行。
我怀疑我的问题略有不同,尽管出现的异常是相同的。
我收到的例外是:
Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:244)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:208)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:189)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:51)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:94)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:217)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:189)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.handleTypes(MetadataBuildingProcess.java:352)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:111)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:83)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:418)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:87)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:692)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:724)
at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:372)
at org.springframework.orm.hibernate4.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:454)
at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:439)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
... 47 more
Caused by: org.hibernate.engine.jndi.JndiException: Unable to lookup JNDI name [java:comp/env/jdbc/MyDataSource]
at org.hibernate.engine.jndi.internal.JndiServiceImpl.locate(JndiServiceImpl.java:100)
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.configure(DatasourceConnectionProviderImpl.java:98)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:94)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:217)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:189)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.buildJdbcConnectionAccess(JdbcEnvironmentInitiator.java:145)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:66)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:88)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:234)
... 65 more
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:818)
at org.apache.naming.NamingContext.lookup(NamingContext.java:152)
at org.apache.naming.SelectorContext.lookup(SelectorContext.java:134)
at javax.naming.InitialContext.lookup(Unknown Source)
at org.hibernate.engine.jndi.internal.JndiServiceImpl.locate(JndiServiceImpl.java:97)
... 74 more
我正在将一个遗留的 Struts 应用程序迁移到 Spring MVC,最好是使用嵌入式 tomcat 的 spring boot。最终,我计划将这些 jndi 资源查找更改为(至少我所知道的)传统定义的数据源,但此时希望避免该步骤。
我正在导入一个 applicationContext.xml 资源:
@Configuration
@ComponentScan
@EnableAutoConfiguration
@ImportResource("classpath:context/applicationContext.xml")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public TomcatEmbeddedServletContainerFactory tomcatFactory() {
return new TomcatEmbeddedServletContainerFactory() {
@Override
protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(
Tomcat tomcat) {
tomcat.enableNaming();
return super.getTomcatEmbeddedServletContainer(tomcat);
}
@Override
protected void postProcessContext(Context context) {
ContextResource resource = new ContextResource();
ContextResourceLink resourceLink = new ContextResourceLink();
resource.setName("jdbc/MyDataSource");
resource.setProperty("global", "jdbc/MyDataSource");
resource.setType("javax.sql.DataSource");
resource.setProperty("driverClassName", "oracle.jdbc.driver.OracleDriver");
resource.setProperty("url", "jdbc:yourDb");
resource.setAuth("Container");
context.getNamingResources().addResource(resource);
resourceLink.setName("jdbc/MyDataSource");
resourceLink.setType("javax.sql.DataSource");
resourceLink.setProperty("driverClassName", "oracle.jdbc.driver.OracleDriver");
resourceLink.setProperty("url", "jdbc:connectionString");
context.getNamingResources().addResourceLink(resourceLink);
System.out.println("\n\n\ncontext naming resources\n"+context.getResourceOnlyServlets()+"\n\n\n");
}
};
}
@Bean(destroyMethod="")
public DataSource jndiDataSource() throws IllegalArgumentException, NamingException {
System.out.println("\n\n\nIn jndiDataSource\n\n\n");
JndiObjectFactoryBean bean = new JndiObjectFactoryBean();
bean.setJndiName("java:comp/env/jdbc/MyDataSource");
bean.setProxyInterface(oracle.jdbc.driver.OracleDriver.class);
bean.setLookupOnStartup(false);
bean.afterPropertiesSet();
return (DataSource)bean.getObject();
}
}
资源 applicationContext.xml 引用了一个 hibernateContext.xml,它引用了一个 hibernate.cfg.xml 文件,如下所示:
<hibernate-configuration>
<session-factory>
<property name="connection.datasource">java:comp/env/jdbc/MyDataSource</property>
<property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
<property name="show_sql">false</property>
<property name="format_sql">true</property>
<property name="hibernate.max_fetch_depth">2</property>
.....
我没有看到 println 从
@Bean(destroyMethod="")
public DataSource jndiDataSource()...
豆。我确实看到了:
Name = MyDataSource Ignoring unknown property: value of "jdbc/MyDataSource" for "global" property
并认识到这不是一个有效或有用的设置,但这是我尝试过的事情之一。
任何有关确定 1) 原因和 2) 解决方案的帮助将不胜感激——我以前没有使用过 JNDI 资源,并且此应用程序的背景是 WAS。
我查看了大多数堆栈溢出问题,这些问题与spring-boot,hibernate,jndi,name not found的某种组合模糊匹配,并阅读了tomcat资源定义文档,但无法将其拼凑在一起。 .
如果我遗漏了任何内容,请告诉我