Forums

Home » Liferay Portal » English » 3. Development

Combination View Flat View Tree View
Threads [ Previous | Next ]
toggle
Nick Straguzzi
Using a second JNDI database with a portlet
July 9, 2012 9:31 AM
Answer

Nick Straguzzi

Rank: New Member

Posts: 15

Join Date: May 11, 2012

Recent Posts

Folks:

Anyone have any idea about this one? I'm using Tomcat 6 and LR 6 EE SP2. I've created a Portlet plug-in which needs access to a separate MySQL database defined via JNDI and accessed via Hibernate. At runtime, the portlets in the plugin won't work; they throw an exception "Could not find datasource: jdbc/XXXX" followed by the dreaded "Name jdbc is not bound in this Context".

Again, this is NOT for the LR database. It's for a separate database that my portlets need to access. One would think there is something wrong with my configuration, but, here's the kicker: I've set up both the LR database and my second database via JNDI, and the Liferay database works perfectly.. I'm going crazy trying to figure out why one works and the other doesn't. The essentials:

In Tomcat's context.xml I define both JNDI resources....

 1
 2<Context>
 3    <Resource name="jdbc/LiferayDB" auth="Container" type="javax.sql.DataSource"
 4              maxActive="20" maxIdle="10" maxWait="5000"
 5              removeAbandoned="true" removeAbandonedTimeout="250" validationQuery="SELECT 1"
 6              username="user" password="pwd"
 7              driverClassName="com.mysql.jdbc.Driver"
 8              url="jdbc:mysql://localhost/lportal?useUnicode=true&amp;characterEncoding=UTF-8&amp;useFastDateParsing=false"/>
 9
10    <Resource name="jdbc/XXX" auth="Container" type="javax.sql.DataSource"
11              maxActive="20" maxIdle="10" maxWait="5000"
12              removeAbandoned="true" removeAbandonedTimeout="250" validationQuery="SELECT 1"
13              username="user2" password="pwd2"
14              driverClassName="com.mysql.jdbc.Driver"
15              url="jdbc:mysql://localhost/myOtherDb"/>
16<Context>


Obviously, in portal-ext.properties, I've configured LR to use the first datasource, jdbc/LiferayDB. It does this without any quarrel.

So now for the portlets. Inside my portlet project, I have a custom JAR file containing all of my Hibernate mappings (which, according to the Debug logs, all set up and parse perfectly). That JAR also contains hibernate.cfg.xml, which contains the following properties under the <session-factory>:

1
2<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
3<property name="hibernate.connection.datasource">jdbc/XXX</property>
4<property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>


Finally, within my app's META-INF folder, I have a context.xml file that includes:

1
2<Context>
3  <ResourceLink name="jdbc/XXX" global="jdbc/XXX" type="javax.sql.DataSource">
4</Context>


(And for the record, I have also tried copying the global <Resource> definition into the app's local context.xml, plus tried without any context.xml whatsoever.

The relevant stacktrace:

 1
 216:06:46,945 INFO  [NamingHelper:49] JNDI InitialContext properties:{}
 316:06:46,947 ERROR [DatasourceConnectionProvider:78] Could not find datasource: jdbc/XXX
 4javax.naming.NameNotFoundException: Name jdbc is not bound in this Context
 5    at org.apache.naming.NamingContext.lookup(NamingContext.java:770)
 6    at org.apache.naming.NamingContext.lookup(NamingContext.java:153)
 7    ...
 8
 9XXX-Hibernate session factory could not be created: org.hibernate.HibernateException: Could not find datasource
1016:06:46,955 ERROR [render_portlet_jsp:154] javax.naming.NameNotFoundException: Name jdbc is not bound in this Context
11    at org.apache.naming.NamingContext.lookup(NamingContext.java:770)
12    at org.apache.naming.NamingContext.lookup(NamingContext.java:153)
13    at org.apache.naming.SelectorContext.lookup(SelectorContext.java:152)
14    at javax.naming.InitialContext.lookup(InitialContext.java:392)
15    at org.hibernate.connection.DatasourceConnectionProvider.configure(DatasourceConnectionProvider.java:75)
16    at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:143)
17    at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:84)
18    at org.hibernate.cfg.SettingsFactory.createConnectionProvider(SettingsFactory.java:459)
19    at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:90)
20    at org.hibernate.cfg.Configuration.buildSettingsInternal(Configuration.java:2863)
21    at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2859)
22    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1870)
23    at my.local.HibernateUtil.<clinit>(HibernateUtil.java:23)
24    at my.local.portlet.modulemenu.ModuleMenu.doView(ModuleMenu.java:67)
25    at com.liferay.portal.kernel.portlet.LiferayPortlet.doDispatch(LiferayPortlet.java:205)
26    at com.liferay.util.bridges.mvc.MVCPortlet.doDispatch(MVCPortlet.java:309)
27    at javax.portlet.GenericPortlet.render(GenericPortlet.java:233)
28    at com.liferay.portlet.FilterChainImpl.doFilter(FilterChainImpl.java:100)
29    at com.liferay.portal.kernel.portlet.PortletFilterUtil.doFilter(PortletFilterUtil.java:64)
30    at com.liferay.portal.kernel.servlet.PortletServlet.service(PortletServlet.java:93)


Finally, my mental state:

1
2AAAAARRRRRGGGGGGGGHHHHHHHHHH!!!!!!!!!!


Any help would be gleefully appreciated.

Regards,
Nick
Thomas Berg
RE: Using a second JNDI database with a portlet
July 9, 2012 1:18 PM
Answer

Thomas Berg

Rank: Regular Member

Posts: 121

Join Date: September 7, 2009

Recent Posts

Try defining your resource in Tomcats server.xml (as a global resource):

tomcat/conf/server.xml:

 1  <GlobalNamingResources>
 2    <!-- Editable user database that can also be used by
 3         UserDatabaseRealm to authenticate users
 4    -->
 5    <Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/>
 6   
 7    <Resource name="jdbc/XXX" auth="Container" type="javax.sql.DataSource"
 8              maxActive="20" maxIdle="10" maxWait="5000"
 9              removeAbandoned="true" removeAbandonedTimeout="250" validationQuery="SELECT 1"
10              username="user2" password="pwd2"
11              driverClassName="com.mysql.jdbc.Driver"
12              url="jdbc:mysql://localhost/myOtherDb"/>   
13  </GlobalNamingResources>


Put this in tomcat/conf/context.xml

1<ResourceLink name="jdbc/XXX" global="jdbc/XXX" type="javax.sql.DataSource">


HTH

/ Thomas
Nick Straguzzi
RE: Using a second JNDI database with a portlet
July 9, 2012 2:18 PM
Answer

Nick Straguzzi

Rank: New Member

Posts: 15

Join Date: May 11, 2012

Recent Posts

Thank you so much Thomas. That combination did the trick.

Best regards,
Nick
Huy Vo
RE: Using a second JNDI database with a portlet
July 30, 2012 3:22 AM
Answer

Huy Vo

Rank: New Member

Posts: 3

Join Date: July 10, 2012

Recent Posts

Follow the guidline but still failed
1Could not find datasource: jdbc/XXX
, please help me solve this problem
note:I using liferay version 6.1 to development porlet with technical JSF+hibernte
Hitoshi Ozawa
RE: Using a second JNDI database with a portlet
July 30, 2012 7:08 AM
Answer

Hitoshi Ozawa

Rank: Liferay Legend

Posts: 7990

Join Date: March 23, 2010

Recent Posts

Thomas's steps should work because I'm doing the same thing. What did you do?
Huy Vo
RE: Using a second JNDI database with a portlet
July 30, 2012 7:52 PM
Answer

Huy Vo

Rank: New Member

Posts: 3

Join Date: July 10, 2012

Recent Posts

Hi forum!
- I config JNDI step by step such as:
+ step 1: this tomcat forder add code in file ROOT.xml :
 1<Resource
 2       name="jdbc/LiferayPool"
 3       auth="Container"
 4       type="javax.sql.DataSource"
 5       driverClassName="com.mysql.jdbc.Driver"
 6       url="jdbc:mysql://localhost/lportal?useUnicode=true&amp;characterEncoding=UTF-8"
 7       username="root"
 8       password="root"
 9       maxActive="100"
10       maxIdle="30"
11       maxWait="10000"
12    />

+step 2: add code below in file context.xml this forder tomcat
1<ResourceLink global="jdbc/LiferayPool" name="jdbc/LiferayPool" type="javax.sql.DataSource" />

+ step 3: add code in file portal-setup-wizard.properties
1jdbc.default.jndi.name=jdbc/LiferayPool

+ step 4: this application porlet , i add code in file hibernate.cfg.xml
 1<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
 2        <property name="hibernate.connection.datasource">jdbc/LiferayPool</property>
 3        <property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
 4        <property name="hibernate.search.autoregister_listeners">false</property>       
 5        <property name="hibernate.current_session_context_class">thread</property>
 6        <property name="hibernate.connection.release_mode">auto</property>
 7        <property name="hibernate.show_sql">false</property>
 8        <property name="hibernate.bytecode.use_reflection_optimizer">false</property>
 9        <property name="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</property>

+ step 5: add code in file web.xml to application porlet (/docroot/WEB-INF/web.xml)
1<resource-ref>
2        <description>MySQL Datasource</description>
3        <res-ref-name>
4            jdbc/LiferayPool            
5        </res-ref-name>
6        <res-type>javax.sql.DataSource</res-type>
7        <res-auth>Container</res-auth>
8    </resource-ref>

- Then I restart server tomcat ok, build and deploy application porlet thorw error such as:
1Initial SessionFactory creation failed.org.hibernate.service.jndi.JndiException: Unable to lookup JNDI name [jdbc/LiferayPool]
202:30:52,509 ERROR [PortletServlet:97] javax.portlet.PortletException: doBridgeDispatch failed:  error from Bridge in executing the request
3javax.portlet.PortletException: doBridgeDispatch failed:  error from Bridge in executing the request

 1
 2
 3    at org.hibernate.service.jndi.internal.JndiServiceImpl.locate(JndiServiceImpl.java:68)
 4    at org.hibernate.service.jdbc.connections.internal.DatasourceConnectionProviderImpl.configure(DatasourceConnectionProviderImpl.java:116)
 5    at org.hibernate.service.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:75)
 6    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:159)
 7    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:131)
 8    at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.buildJdbcConnectionAccess(JdbcServicesImpl.java:223)
 9    at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:89)
10    at org.hibernate.service.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:75)
11    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:159)
12    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:131)
13    at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:71)
14    at org.hibernate.cfg.Configuration.buildSettingsInternal(Configuration.java:2277)
15    at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2273)
16    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1742)
17    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1782)
18    at com.liferay.faces.util.HibernateUtil.<clinit>(HibernateUtil.java:24)
19    ... 215 more
20Caused by: javax.naming.NameNotFoundException: Name jdbc is not bound in this Context

Please help me solve this problem,
Thank forum verry much!
Satya Narayana
RE: Using a second JNDI database with a portlet
December 21, 2012 5:12 AM
Answer

Satya Narayana

Rank: New Member

Posts: 2

Join Date: January 4, 2012

Recent Posts

Have you given below entry in liferay portal-ext.properties in catalina home. If not give it, it works.

jdbc.default.jndi.name=jdbc/LiferayPool

There is ssecond approach, u can define your jndi resource in context.xml also and give refrence in ur web app like below

<resource-ref>
<description>MySQL Datasource</description>
<res-ref-name>jdbc/LiferayPool</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>

Thanks,
Satya.
Sushil Saini
RE: Using a second JNDI database with a portlet
December 22, 2012 2:54 PM
Answer

Sushil Saini

Rank: Regular Member

Posts: 102

Join Date: July 27, 2011

Recent Posts

Hi Huy,.... In the step 1. you have mentioned you are putting the configuration in the ROOT.xml. I think, it should go in the tomcat/conf/server.xml file.
Baogang Liu
RE: Using a second JNDI database with a portlet
August 15, 2013 2:12 AM
Answer

Baogang Liu

Rank: New Member

Posts: 10

Join Date: August 14, 2013

Recent Posts

I meet the same problem when using "broadleaf commerce portlet demo site https://github.com/BroadleafCommerce/DemoSite-portlet" in liferay-portal-tomcat-6.2.0-ce-b1-20130801091812389.zip. I am not sure whether the root cause is from liferay or broadleaf. I also posted my question in broadleaf forum http://forum.broadleafcommerce.org/viewtopic.php?f=14&t=2108&p=5928.

Liferay logs:

"Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'blMergedDataSources' defined in resource loaded from byte array: Cannot resolve reference to bean 'webSecureDS' while setting bean property 'sourceMap' with key [TypedStringValue: value [jdbc/webSecure], target type ]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'webSecureDS': Invocation of init method failed; nested exception is javax.naming.NameNotFoundException: Name [jdbc/secure] is not bound in this Context. Unable to find .
Jose F. Fernandez
RE: Using a second JNDI database with a portlet
August 29, 2013 9:21 AM
Answer

Jose F. Fernandez

Rank: New Member

Posts: 3

Join Date: July 31, 2013

Recent Posts

I'm facing to issues with JNDI when Liferay is deployed in a Tomcat installation. If I undeploy Liferay I can see the JNDI datasources with Psi-probe, when Liferay is running, no JNDI datasources are shown, nor can be accesed. The root cause of the exception is:

Caused by: javax.naming.NameNotFoundException: Name java:comp/env/jdbc/aperte-reports is not bound in this Context

In my case, the problem is caused by the Liferay security manager, when overrides the context, all JNDI entries are lost.
If you have a plugin that enables the security manager, you will get that problem (mine was a carousel portlet), if you don't have such a portlet, with the default configuration, security manager will not be activated, so no problem!

Look for that text in your log:
14:24:29,225 INFO [localhost-startStop-1][PACLPolicyManager:90] Activating PACL policy manager
14:24:29,226 INFO [localhost-startStop-1][PACLPolicyManager:146] Overriding the current security manager to enable plugin security management
14:24:29,232 INFO [localhost-startStop-1][PortalSecurityManager:179] Overriding the initial context factory builder

If you have this, you will have problems with JNDI (no datasources will be shown by Psy-Probe, and other plugins that use JNDI such as Aperte Reports will stop to work)

If you have experienced these problems, you can disable Liferay security manager in portal-ext.properties, adding:
portal.security.manager.strategy=none

Hope will be helpfull for someone, I could not find a solution for this and have to debug code by hours after lot of time lost with configuration settings, trying different versions of Tomcat, etc. etc.

All is working now!!!
David H Nebinger
RE: Using a second JNDI database with a portlet
August 29, 2013 9:37 AM
Answer

David H Nebinger

Rank: Liferay Legend

Posts: 6268

Join Date: September 1, 2006

Recent Posts

First of all, this thread was started long before the security manager came along, so your comment doesn't apply.

Back on point...

The security manager blocks the portlet from accessing things that it doesn't declare it is accessing. If you don't declare that you're going after something (such as a JNDI resource), it's not going to be able to.

The JNDI resources are not lost, you just have no access to them.

You can leave security manager enabled, just change your security-manager-enabled flag to "generate" and you'll be able to see the things that you need to enable to get to the resources.
Jose F. Fernandez
RE: Using a second JNDI database with a portlet
August 29, 2013 10:48 AM
Answer

Jose F. Fernandez

Rank: New Member

Posts: 3

Join Date: July 31, 2013

Recent Posts

Thank you David!!

As you can see, I'm replying to Baogang Liu, which commented a few days ago, not to the main question of the thread, wich gets responded and resolved a year ago...
Perhaps the other comments should be made ​​in a new thread, but they are here, so here I answered, sorry!

The problem I see with security manager is that once activated by a plugin, affects others, for example, in my case, Carousel Portlet plugin activates it, but it affects Aperte Reports, therefore, until you completely disable security manager, the plugin that looks JNDI and not employ security manager does not work.

The security manager is affecting too other webapps deployed, maybe that is the desired effect for you, but I want to be able to monitor the Tomcat instance and Datasources usage with Psi-probe, and if security manager is active, Psi-probe can't lookup JNDI datasources... what have I to configure to enable that?

Thank you!!!
Baogang Liu
RE: Using a second JNDI database with a portlet
August 29, 2013 7:49 PM
Answer

Baogang Liu

Rank: New Member

Posts: 10

Join Date: August 14, 2013

Recent Posts

Thanks Jose and David. With below way, the jndi problem when using broadleaf in liferay-portal-tomcat-6.2.0-ce-b2-20130815141757862.zip disappear.

"disable Liferay security manager in portal-ext.properties, adding: portal.security.manager.strategy=none"

But for below things, can you give some advice:

1. If not set "portal.security.manager.strategy=none", there is no jndi problem when using broadleaf in liferay-portal-tomcat-6.2.0-ce-m3-20121226162932032.zip and liferay-portal-tomcat-6.1.1-ce-ga2-20120731132656558.zip. When using broadleaf in liferay-portal-tomcat-6.2.0-ce-m6-20130614143518319.zip, liferay-portal-tomcat-6.2.0-ce-b1-20130801091812389.zip or liferay-portal-tomcat-6.2.0-ce-b2-20130815141757862.zip, there is jndi problem.

Can we guess that the built-in example in liferay m6/b1/b2 enables liferay security manager but m3 not?

2. I searched 'security-manager-enabled' in all the xml/properties files in liferay b2 folder and lieray m3 folder with liferay build-in app and broadleaf deployed, and found "security-manager-enabled=false" in liferay-plugin-package_6_1_0.properties and liferay-plugin-package_6_2_0.properties under \liferay-portal-6.2.0-ce-xx\tomcat-7.0.40\Webapps\Root\Dtd\. I did not find a place where "security-manager-enabled=true".

I changed "false" to "generate", the jndi problem in liferay b2 still exist. The jndi problem in liferay m3 does not exist even if I does not change any config.

Where is the config which enables security-manager?

3. Using liferay-portal-tomcat-6.2.0-ce-b2-20130815141757862.zip, In the past I test several ways as mentioned in http://forum.broadleafcommerce.org/viewtopic.php?f=14&t=2108&p=5928, including define below content in tomcat/conf/web.xml and broadleaf-portlet's web.xml, did not solve the jndi problem.

<res-ref-name>jdbc/secure</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>

So, when security manager is enabled, how an app refer to a jndi defined either in this app or in tomcat globa jindi? The much clear statement on this question should be Jose's description:

"The problem I see with security manager is that once activated by a plugin, affects others, for example, in my case, Carousel Portlet plugin activates it, but it affects Aperte Reports, therefore, until you completely disable security manager, the plugin that looks JNDI and not employ security manager does not work. '

The security manager is affecting too other webapps deployed, maybe that is the desired effect for you......"
Baogang Liu
RE: Using a second JNDI database with a portlet
August 29, 2013 8:04 PM
Answer

Baogang Liu

Rank: New Member

Posts: 10

Join Date: August 14, 2013

Recent Posts

BTW, I submitted a new post in the past, as below link. No one reply in that post. So I wrote comments to that post to point to this post.

http://www.liferay.com/zh/community/forums/-/message_boards/message/27633700 NameNotFoundException' in m6/b1/b2 but NO problem in liferay 6.2.0m3