I need some help getting Hibernate 4 working with Weblogic. We had an application that worked fine with weblogic using Hibernate 3.6.10. When we upgraded to Hibernate 4.3.11, it would no longer find the Weblogic JNDI datasource. The same application works fine with Tomcat. We are testing with Weblogic version 10.3.6.0 (11g). The package is a WAR file.
We use some indirection in our lookup so that we can use deployment plans to provide the link from the internal logical datasource name to the actual Weblogic datsource.
The code that creates the session is shown below (java):
private SessionFactory startHibernateTransaction()
{
SessionFactory hibernateSessionFactory = null;
ServiceRegistry serviceRegistry;
Configuration configuration = new Configuration();
configuration.configure(“StandAloneHibernate.cfg.xml”);
serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
hibernateSessionFactory = configuration.buildSessionFactory(serviceRegistry);
// starts hibernate transaction (needed to use iterator())
hibernateSessionFactory.getCurrentSession().beginTransaction();
return hibernateSessionFactory;
}
The Hibernate configuration file is:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.datasource">java:comp/env/dwDatasource</property>
<property name="hibernate.dialect">CustomDialect</property>
<property name="current_session_context_class">thread</property>
<property name="show_sql">false</property>
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<mapping resource="hibernate/ShpSettingsMst.hbm.xml"></mapping>
</session-factory>
</hibernate-configuration>
Our web.xml file (abridged):
<?xml version="1.0" encoding="UTF-8"?>
<!-- $Id: //Tuxedo/RELEASE/Product/Fast_Forward/DashboardServlet/src/main/webapp/WEB-INF/web.xml#3 $ -->
<!-- Copyright 2015 Ellucian Company L.P. and its affiliates. -->
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
...
<resource-ref>
<description>Data source</description>
<res-ref-name>dwDatasource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
Our weblogic.xml:
<?xml version="1.0"?>
<!-- $Id: //Tuxedo/RELEASE/Product/Fast_Forward/DashboardServlet/src/main/webapp/WEB-INF/weblogic.xml#1 $ -->
<!-- Copyright 2015 Ellucian Company L.P. and its affiliates. -->
<weblogic-web-app xmlns="http://www.bea.com/ns/weblogic/90" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<container-descriptor>
<prefer-web-inf-classes>true</prefer-web-inf-classes>
<!-- Enables weblogic to use ServletContext.realPath(...) to locate local configuration files -->
<show-archived-real-path-enabled>true</show-archived-real-path-enabled>
</container-descriptor>
<resource-description>
<res-ref-name>dwDatasource</res-ref-name>
<jndi-name>jdbc/EGdwDatasource</jndi-name>
</resource-description>
</weblogic-web-app>
The Weblogic datasource is defined with a JNDI name of “jdbc/EGdwDatasource”.
If I put just “jdbc/EGdwDatasource” into the StandAloneHibernate.cfg.xml file (no “java:comp/env/”), then it finds the datasource. However, we need the indirection since we would like to use a deployment plan to alter the datasource without having to change the WAR file.
I have tried many different combinations for the res-ref-name, including “jdbc/dwDatasource”. I have tried leaving off the “comp/env” (e.g. “java:dwDatsource”).
I enabled JNDI debugging in weblogic, and see some interesting output, although, without the code, I don’t really know what it is telling me. I see for example:
<Mar 29, 2017 10:32:21 PM EDT> <Debug> <JNDI> <BEA-000000> <+++ bind(app/webapp/dashboard.war/1049307908/comp/env/dwDatasource, javax.naming.LinkRef) succeeded>
When it fails, I see the message:
Caused by: javax.naming.NameNotFoundException: While trying to look up /comp.env.dwDatasource in /app/webapp/dashboard.war/1049307908.; remaining name '/comp/env/dwDatasource'
Given those two statements, it looks like it should find the entry. Here is the error and stack trace:
29-Mar-2017 10:32:26:316 EDT [[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'] ERROR ContextLoader.initWebApplicationContext(351): Context initialization failed
org.hibernate.engine.jndi.JndiException: Unable to lookup JNDI name [java:comp/env/dwDatasource]
at org.hibernate.engine.jndi.internal.JndiServiceImpl.locate(JndiServiceImpl.java:117)
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.configure(DatasourceConnectionProviderImpl.java:115)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:111)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:234)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:206)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.buildJdbcConnectionAccess(JdbcServicesImpl.java:260)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:94)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:111)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:234)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:206)
at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1887)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1845)
at net.hedtech.degreeworks.settings.dao.ShpSettingsDaoStandalone.startHibernateTransaction(ShpSettingsDaoStandalone.java:125)
at net.hedtech.degreeworks.settings.dao.ShpSettingsDaoStandalone.get(ShpSettingsDaoStandalone.java:44)
at net.hedtech.degreeworks.settings.util.TracingPlaceholderConfigurer.setupCrypto(TracingPlaceholderConfigurer.java:787)
at net.hedtech.degreeworks.settings.util.TracingPlaceholderConfigurer.loadPropertiesFromFactories(TracingPlaceholderConfigurer.java:257)
at net.hedtech.degreeworks.settings.util.TracingPlaceholderConfigurer.postProcessBeanFactory(TracingPlaceholderConfigurer.java:181)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:284)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:166)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:681)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:523)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:444)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:326)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
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)
at weblogic.application.internal.flow.ModuleStateDriver$3.next(ModuleStateDriver.java:425)
at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:52)
at weblogic.application.internal.flow.ModuleStateDriver.start(ModuleStateDriver.java:119)
at weblogic.application.internal.flow.ScopedModuleDriver.start(ScopedModuleDriver.java:200)
at weblogic.application.internal.flow.ModuleListenerInvoker.start(ModuleListenerInvoker.java:247)
at weblogic.application.internal.flow.ModuleStateDriver$3.next(ModuleStateDriver.java:425)
at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:52)
at weblogic.application.internal.flow.ModuleStateDriver.start(ModuleStateDriver.java:119)
at weblogic.application.internal.flow.StartModulesFlow.activate(StartModulesFlow.java:27)
at weblogic.application.internal.BaseDeployment$2.next(BaseDeployment.java:671)
at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:52)
at weblogic.application.internal.BaseDeployment.activate(BaseDeployment.java:212)
at weblogic.application.internal.SingleModuleDeployment.activate(SingleModuleDeployment.java:44)
at weblogic.application.internal.DeploymentStateChecker.activate(DeploymentStateChecker.java:161)
at weblogic.deploy.internal.targetserver.AppContainerInvoker.activate(AppContainerInvoker.java:79)
at weblogic.deploy.internal.targetserver.BasicDeployment.activate(BasicDeployment.java:184)
at weblogic.deploy.internal.targetserver.BasicDeployment.activateFromServerLifecycle(BasicDeployment.java:361)
at weblogic.management.deploy.internal.DeploymentAdapter$1.doActivate(DeploymentAdapter.java:51)
at weblogic.management.deploy.internal.DeploymentAdapter.activate(DeploymentAdapter.java:200)
at weblogic.management.deploy.internal.AppTransition$2.transitionApp(AppTransition.java:30)
at weblogic.management.deploy.internal.ConfiguredDeployments.transitionApps(ConfiguredDeployments.java:240)
at weblogic.management.deploy.internal.ConfiguredDeployments.activate(ConfiguredDeployments.java:169)
at weblogic.management.deploy.internal.ConfiguredDeployments.deploy(ConfiguredDeployments.java:123)
at weblogic.management.deploy.internal.DeploymentServerService.resume(DeploymentServerService.java:180)
at weblogic.management.deploy.internal.DeploymentServerService.start(DeploymentServerService.java:96)
at weblogic.t3.srvr.SubsystemRequest.run(SubsystemRequest.java:64)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)
Caused by: javax.naming.NameNotFoundException: While trying to look up /comp.env.dwDatasource in /app/webapp/dashboard.war/1049307908.; remaining name '/comp/env/dwDatasource'
at weblogic.jndi.internal.BasicNamingNode.newNameNotFoundException(BasicNamingNode.java:1139)
at weblogic.jndi.internal.ApplicationNamingNode.lookup(ApplicationNamingNode.java:144)
at weblogic.jndi.internal.WLEventContextImpl.lookup(WLEventContextImpl.java:254)
at weblogic.jndi.internal.WLContextImpl.lookup(WLContextImpl.java:412)
at weblogic.jndi.factories.java.ReadOnlyContextWrapper.lookup(ReadOnlyContextWrapper.java:45)
at weblogic.jndi.internal.AbstractURLContext.lookup(AbstractURLContext.java:135)
at javax.naming.InitialContext.lookup(InitialContext.java:415)
at org.hibernate.engine.jndi.internal.JndiServiceImpl.locate(JndiServiceImpl.java:114)
... 59 more
There is an issue in the Hibernate, https://hibernate.atlassian.net/browse/HHH-7012, that might apply. It’s main focus was Tomcat, and the resolution was to use a version of Tomcat that fixed its JNDI lookup. It mentioned that the change Hibernate made in 4 was to use the lookup method that takes a JNDI Name object, instead of the one that uses a String.
Help with a solution or just how to debug this further would be greatly appreciated.
Update: I was able to get this to work if I substituted in my own JndiService. I cloned Hibernate's and changed their lookup to use the String instead of Name. Theirs is:
JndiServiceImpl
public Object locate(String jndiName) {
final InitialContext initialContext = buildInitialContext();
final Name name = parseName( jndiName, initialContext );
try {
return initialContext.lookup( name );
}
catch ( NamingException e ) {
Mine is
public Object locate(String jndiName)
{
final InitialContext initialContext = buildInitialContext();
try
{
return initialContext.lookup(jndiName);
}
catch (NamingException e)
However, I'd rather not have a custom JndiService implementation, so if anyone knows of any other solution, please let me know.