Tribune

Home » Liferay Portal » English » 3. Development

Vista Combinata Vista Piatta Vista ad Albero
Discussioni [ Precedente | Successivo ]
toggle
Bob Dietrich
6.1 CE GA2 Tomcat bundle issue with JNDI resources
15 gennaio 2013 2.17
Risposta

Bob Dietrich

Punteggio: Regular Member

Messaggi: 218

Data di Iscrizione: 15 maggio 2005

Messaggi recenti

I believe there is an issue with Liferay 6.1 CE GA2 and the Tomcat bundle. Specifically, it seems to have broken the use of JNDI resources by servlets and portlets. I found this in a portlet that worked in GA1 but not in GA2.

Clarification: The example uses SQL embedded in a JSP to demonstrate the failure of GA2 in the simplest possible way. It's a horrible practice!

I created a simple war file that uses JNDI per the instructions in Tomcat 7 JNDI Datasource How-To, using MySQL. I did this to eliminate any issues with Liferay, Hibernate or other libraries. The resulting war file consists of three files (plus two jars). The war file is attached, but you'll have to set your own username and password to get it to work. The MySQL drivers have also been placed in both lib and lib/ext just to eliminate any classpath issues.

If you copy the war file to the webapp directory of Liferay 6.1 CE GA1 or vanilla copies of Tomcat 7.0.23 (same as GA1) or Tomcat 7.0.27 (same as GA2) or even Tomcat 7.0.32, you can open http://localhost:8080/test/test.jsp and get the results you would expect. However, if you do the same thing with Liferay 6.1 CE GA2, you get the following exception:
1javax.servlet.jsp.JspException: Unable to get connection, DataSource invalid: "java.sql.SQLException: No suitable driver found for jdbc/MySqlDS"
2    org.apache.taglibs.standard.tag.common.sql.QueryTagSupport.getConnection(QueryTagSupport.java:318)
3    org.apache.taglibs.standard.tag.common.sql.QueryTagSupport.doStartTag(QueryTagSupport.java:201)
4    org.apache.jsp.test_jsp._jspx_meth_sql_005fquery_005f0(test_jsp.java:119)
5    org.apache.jsp.test_jsp._jspService(test_jsp.java:72)

The three files are context.xml (you may need to copy this as test.xml to conf/Catalina/localhost), web.xml, and test.jsp.

context.xml:
 1<?xml version='1.0' encoding='utf-8'?>
 2<Context>
 3 <Resource name="jdbc/MySqlDS" auth="Container"
 4            type="javax.sql.DataSource"
 5            factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
 6            driverClassName="com.mysql.jdbc.Driver"
 7            username="user"
 8            password="password"
 9            url="jdbc:mysql://localhost:3306/lportal?useUnicode=true&amp;characterEncoding=UTF-8&amp;relaxAutoCommit=true"
10            maxActive="200" maxIdle="30" maxWait="10000"
11            minIdle="3"
12            testWhileIdle="true" testOnBorrow="true"
13            timeBetweenEvictionRunsMillis="120000"
14            minEvictableIdleTimeMillis="600000"
15            validationQuery="select 1"
16        />
17    <!-- Default set of monitored resources -->
18    <WatchedResource>WEB-INF/web.xml</WatchedResource>
19</Context>

web.xml:
 1<?xml version="1.0" encoding="UTF-8"?>
 2<web-app version="3.0"
 3    xmlns="http://java.sun.com/xml/ns/javaee"
 4    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 5    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
 6    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
 7  <display-name></display-name>
 8  <resource-ref>
 9      <description>DB Connection</description>
10      <res-ref-name>jdbc/MySqlDS</res-ref-name>
11      <res-type>javax.sql.DataSource</res-type>
12      <res-auth>Container</res-auth>
13  </resource-ref>
14  <welcome-file-list>
15    <welcome-file>test.jsp</welcome-file>
16  </welcome-file-list>
17</web-app>

test.jsp:
 1<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
 2<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
 3
 4<sql:query var="rs" dataSource="jdbc/MySqlDS">
 5select foodItemId, name_, points from fooditem
 6</sql:query>
 7
 8<html>
 9  <head>
10    <title>DB Test</title>
11  </head>
12  <body>
13
14  <h2>Results</h2>
15 
16<c:forEach var="row" items="${rs.rows}">
17    Id ${row.foodItemId}<br/>
18    Name ${row.name_}<br/>
19    Points ${row.points}<br/>
20</c:forEach>
21
22  </body>
23</html>

I suppose I could be doing something wrong, but I certainly don't know what that is. Thanks.
Allegati: test.war (385,5k)
Bob Dietrich
RE: 6.1 CE GA2 Tomcat bundle issue with JNDI resources
14 gennaio 2013 14.02
Risposta

Bob Dietrich

Punteggio: Regular Member

Messaggi: 218

Data di Iscrizione: 15 maggio 2005

Messaggi recenti

Forgot to mention I also tried it with the patched CE version (lcepatchers.org).
Juan Gonzalez
RE: 6.1 CE GA2 Tomcat bundle issue with JNDI resources
15 gennaio 2013 1.11
Risposta

Juan Gonzalez

LIFERAY STAFF

Punteggio: Liferay Legend

Messaggi: 1980

Data di Iscrizione: 28 ottobre 2008

Messaggi recenti

No, there isn't any issue in Liferay 6.1 and JNDI.

Why do you use that tags to access DB from jsp?

Your context.xml seems ok, but other changes aren't required.

Just add this property to your portal-ext.properties with your jndi:

jdbc.default.jndi.name=

and that's all.

BTW, is a very very very bad practice to execute SQL like that.
Juan Gonzalez
RE: 6.1 CE GA2 Tomcat bundle issue with JNDI resources
15 gennaio 2013 1.12
Risposta

Juan Gonzalez

LIFERAY STAFF

Punteggio: Liferay Legend

Messaggi: 1980

Data di Iscrizione: 28 ottobre 2008

Messaggi recenti

And be sure to put mysql driver jar into tomcat's classpath.
Bob Dietrich
RE: 6.1 CE GA2 Tomcat bundle issue with JNDI resources
15 gennaio 2013 2.23
Risposta

Bob Dietrich

Punteggio: Regular Member

Messaggi: 218

Data di Iscrizione: 15 maggio 2005

Messaggi recenti

Juan, thanks for replying. My apologies; apparently I didn't make it clear that the JNDI failure was for a portlet connecting to MySQL, not the portal itself.

To clarify the other points:
  1. There is definitely an issue. This very simple servlet does *not* fail in vanilla Tomcat or GA1, but does fail in GA2. The behavior of the bundled Tomcat has changed in GA2.
  2. As I pointed out, this is solely an example to show the failure, eliminating libraries that might cloud the issue. Agreed, putting DB code in a JSP is horrible and I've never done it.
  3. The jdbc.default.jndi.name= only affects the Liferay portal connection to the database through JNDI. Just to make sure, however, I tested with it and the code still failed.
  4. The MySQL driver is in Tomcat's class path (overkill: in both lib and lib/ext)
I'll add a clarification to the original posting.

I should also point out that if you look at Tomcat using PSI-Probe, under GA2 PSI-Probe indicates an error for the resource in test: "This resource is misconfigured and runtime information is not available". This does not happen in GA1 or vanilla Tomcat.
Juan Gonzalez
RE: 6.1 CE GA2 Tomcat bundle issue with JNDI resources
15 gennaio 2013 4.11
Risposta

Juan Gonzalez

LIFERAY STAFF

Punteggio: Liferay Legend

Messaggi: 1980

Data di Iscrizione: 28 ottobre 2008

Messaggi recenti

Oh I understand.

To access from external Liferay database just follow this:

http://www.liferay.com/community/wiki/-/wiki/Main/Connect+to+a+Database+with+Plugins+SDK
Hitoshi Ozawa
RE: 6.1 CE GA2 Tomcat bundle issue with JNDI resources
15 gennaio 2013 4.18
Risposta

Hitoshi Ozawa

Punteggio: Liferay Legend

Messaggi: 7954

Data di Iscrizione: 23 marzo 2010

Messaggi recenti

I think liferay.com just plugged a security bug to make it unable to access database directly from jsp.
Bob Dietrich
RE: 6.1 CE GA2 Tomcat bundle issue with JNDI resources
15 gennaio 2013 13.22
Risposta

Bob Dietrich

Punteggio: Regular Member

Messaggi: 218

Data di Iscrizione: 15 maggio 2005

Messaggi recenti

Thanks, but the wiki instructions involve Spring and ServiceBuilder, neither of which were used by the portlet where I discovered this problem.
Bob Dietrich
RE: 6.1 CE GA2 Tomcat bundle issue with JNDI resources
15 gennaio 2013 13.25
Risposta

Bob Dietrich

Punteggio: Regular Member

Messaggi: 218

Data di Iscrizione: 15 maggio 2005

Messaggi recenti

Hitoshi Ozawa:
I think liferay.com just plugged a security bug to make it unable to access database directly from jsp.
Thanks, but the JSP example, horrible as it is, is dying when trying to make the JNDI connection. The same thing happened in my portlet that accesses the database through Java, not the JSP.
Hitoshi Ozawa
RE: 6.1 CE GA2 Tomcat bundle issue with JNDI resources
15 gennaio 2013 13.54
Risposta

Hitoshi Ozawa

Punteggio: Liferay Legend

Messaggi: 7954

Data di Iscrizione: 23 marzo 2010

Messaggi recenti

Sorry, but you'll have to use Spring + Hibernate now. I think the main problem is Liferay.com does not have a Developer Specification Design Manual. I brought this up once and they just showed me a coding guideline. There's different ways to do things but it's depressing when they suddenly drop support on one of them.
Bob Dietrich
RE: 6.1 CE GA2 Tomcat bundle issue with JNDI resources
28 gennaio 2013 23.43
Risposta

Bob Dietrich

Punteggio: Regular Member

Messaggi: 218

Data di Iscrizione: 15 maggio 2005

Messaggi recenti

Interesting conjecture.

Filed as LPS-32640
Jose F. Fernandez
RE: 6.1 CE GA2 Tomcat bundle issue with JNDI resources
29 agosto 2013 9.21
Risposta

Jose F. Fernandez

Punteggio: New Member

Messaggi: 3

Data di Iscrizione: 31 luglio 2013

Messaggi recenti

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!!!