Howto add a jdbc (jndi) datasource to the embedded tomcat in GWT

1,225 views
Skip to first unread message

draxi...@gmail.com

unread,
Jun 7, 2006, 4:27:12 PM6/7/06
to Google Web Toolkit
Hello group,

I've been playing a bit around with GWT and am now trying to move from
the "Hello World" phase to some timid useful applications.

However I am struggling to find out how I can inform the embedded
tomcat in GWT to accept a datasource definition so that I can pick it
up in my backend by calling:

Context ctx = null;

try {
ctx = new InitialContext();
_source = (DataSource)ctx.lookup("java:comp/env/jdbc/myDB");
} catch (NamingException ne) {
...
}

I _can_ do it for a "normal" tomcat I control, by adding the resource
definitions in the server.xml file, but GWT does not seem to have this
file and no matter what I do, I seem to be unable to instruct the
embedded tomcat in a way that I can define and pick up my datasource.

Has anyone been able to connect to a jdbc datasource within the
embedded tomcat and is willing to give a short step-by-step howto on
where to put what files? It seems that I'm not the only one struggling
with that and I feel a verbose documentation is direly needed as this
request surely isn't exotic for any webapp that does actually fetch its
data from a database.

Thanks in advance

one...@gmail.com

unread,
Jun 7, 2006, 4:47:07 PM6/7/06
to Google Web Toolkit
Remember, the client part of your code (which is written using GWT) is
converted into HTML and JavaScript. Thinking about it in that way, how
would you do what you want to do in HTML and JavaScript? The answer,
of course, is you can't.

What you do in 'normal' tomcat is read the data in a servlet and write
it into your JSP page during a request. With GWT and AJAX you make a
request to a service (which extends servlet) and fill in your
form/table/whatever in the callback with the data returned.

If you are familiar with MVC, then GWT is the View, the service is the
Controller and the data sent between them is the Model.

draxi...@gmail.com

unread,
Jun 7, 2006, 5:06:51 PM6/7/06
to Google Web Toolkit

That is what I meant with backend. The code that tries to pick up the
datasource _is_ a servlet extending the GWT's RemoteServiceServlet
class and all the stubs I need to declare are there. This works. My
Webapp is calling the service on the Tomcat.

What does not work is that I can connect to my database in the
service/servlet on the Tomcat. I can do it easily on any "normal"
standalone Tomcat where I deploy a .war, but I cannot do this in GWT's
hosted mode with the embedded Tomcat there. I just cannot find where to
put the xml definitions of the datasources (I need more than one) so
that the service works when in hosted mode.

Hosted mode is so damn fine to start and develop, but it's kind of
pointless debugging an application with no ability to connect to the
database. I probably could hardcode the datasources username/password
and connector strings in the servlet/service but that is simply going
back to the ice-age and I wish to refrain from doing so.

tim.i...@gmail.com

unread,
Jun 7, 2006, 5:37:30 PM6/7/06
to Google Web Toolkit
If you find a solution to this problem let me know, I'm struggling with
the same issue.

imbrue

unread,
Jun 7, 2006, 7:02:35 PM6/7/06
to Google Web Toolkit
I had similar issues and since my server side code and configuration is
pretty extensive, I new it would be a real pain to try and configure
the internal tomcat which runs in hosted mode. Instead, I wanted a way
for hosted mode to run my client-side java and let my own external
Tomcat setup run my server side code. I'm successfully doing this now
and can debug the client code while running server code in a server
completely under my control. Here is the thread that discusses how I
got there:
http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/5120be0c0b56202/883df4b6657830ac

eduard...@gmail.com

unread,
Jun 7, 2006, 7:28:08 PM6/7/06
to Google Web Toolkit

georgeuoa

unread,
Jun 8, 2006, 3:50:29 AM6/8/06
to Google Web Toolkit
That's a configuration issue with the hosted tomcat. What I did:

* copy my entire WEB-INF to the tomcat/webapps/ROOT/WEB-INF
* merge my web.xml with the web.xml there
* added nearly all contents from the WEB-INF/lib to the classpath of
the shell. If you are running from eclipse, that means editing the
runtime for the shell (Run... Create,manage, and run configurations)

I say nearly because some conflicted with the tomcat/shell
classloaders, so you are on a trial and error path here.

G.

br...@google.com

unread,
Jun 8, 2006, 5:30:14 PM6/8/06
to Google Web Toolkit
I tried to distill a step-by-step approach to using an external Tomcat
server here:
http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/338c4b765d7dfc39

-- Bruce

mku...@googlemail.com

unread,
Jun 22, 2006, 8:42:26 AM6/22/06
to Google Web Toolkit
HI draxinusom,
did u find any solution to your questions " how I can inform the
embedded
tomcat in GWT to accept a datasource definition " and " Has

anyone been able to connect to a jdbc datasource within the
embedded tomcat and is willing to give a short step-by-step howto on
where to put what files? " ..if so, please post the step-by-step
approach...i too facing this problem...
Actually i have setted by datasource information in server.xml of
external tomcat and want to access those data using context ,lookup and
OracleDataSource ds = (OracleDataSource) envContext.lookup("jdbc/db");
like this...but iam unable to connect to my database..i have already
added my ojdbc14.jar to my project....i have read all posts in this
group...oops still iam facing this problem...
i have written plain code using class.forname and
drivermanager.getConnetion...oops thats also not working ..In this
case, i have succefully loaded the driver and failed to connect to my
database..i just ran that code with simple java application that works
fine.so there is no problem with my connection url..here also i have
added ojdbc14.jar to my project...

please anyone help me to get results from database..iam desperately
waiting for database results...

Thanks in advance

Regards
MK

rbon...@sardiniapoint.it

unread,
Jun 22, 2006, 9:05:56 AM6/22/06
to Google Web Toolkit
I've no problem to use GWT with hibernate (JDBC or JNDI) no problem
I can send an example project

Let me now

Rinaldo

mku...@googlemail.com

unread,
Jun 22, 2006, 9:12:16 AM6/22/06
to Google Web Toolkit
Thanks for ur quick response..but i have no idea about hibernate...is
it easy to learn...before this gwt i worked on struts and myeclipse..we
just moved to work on gwt..i have to develope one desktop application
with much of database results and so manu screens containing database
results... so i have created a demoproject with database connection
from shell and imported into eclipse..then my problem started...so give
me the detaied explanation of my problems...

rbonazzo

unread,
Jun 22, 2006, 9:56:43 AM6/22/06
to Google Web Toolkit
Hibernate is a nice product not difficult to use and MyEclipse have a
lot of tool to create alla the classes you need.
But for your question
Made the connection in the servlet for example:
public class SchedaCasaServiceImpl extends RemoteServiceServlet
implements
SchedaCasaService {

/**
*
*/
private static final long serialVersionUID = 1L;

private Abitazioni[] DATI_CASA;

private static final Case[] NO_PEOPLE = new Case[0];

public SchedaCasaServiceImpl() {
TextLogger.info("Inizio oooooooo");
AbitazioniDAO abitMng = new AbitazioniDAO(); //Manager for my table
DATI_CASA = abitMng.getAllAbitazioni(); //
generateRandomCase();
}

private void generateRandomCase() {
TextLogger.info("Dentro generate trovate " + DATI_CASA.length);

for (int i = 0; i < DATI_CASA.length; i++) {
Case casa = new Case();//single record
casa.setCodiceCasa(DATI_CASA[i].getCodiceCasa());
casa.setNomeCasa(DATI_CASA[i].getNomeCasa());
casa.setLocalita("" + DATI_CASA[i].getIdLocalita());
lstCase.add(casa);
}
}

public Case[] getCase(int startIndex, int maxCount) {
int peopleCount = DATI_CASA.length;

int start = startIndex;
if (start >= peopleCount) {
return NO_PEOPLE;
}

int end = Math.min(startIndex + maxCount, peopleCount);
if (start == end) {
return NO_PEOPLE;
}

int resultCount = end - start;
Case[] results = new Case[resultCount];
for (int from = start, to = 0; to < resultCount; ++from, ++to) {
results[to] = (Case) lstCase.get(from);
}
TextLogger.info("startIndex = " + startIndex);
TextLogger.info("maxCount = " + maxCount);
return results; //return an array of record
}

private final List lstCase = new ArrayList();
}


As you can see I modify the Dynatable example
Hope that can help you

Regards

Rinaldo

Anthony

unread,
Jun 22, 2006, 12:53:01 PM6/22/06
to Google Web Toolkit
One distinction that might help: you don't connect to the database from
the GWT client, you connect to a servlet that then connects to the
database.

This is what we are doing with our mortgage calculator you can see
running live on our website here:
http://www.cohomefinder.com/Colorado-mortgage.htm

When you choose the market rate drop down on the mortgage calculator,
it connects to a servlet that pulls the mortgage rates from the
database.

We've provided documentation and source code for this example here:
http://www.mooreds.com/weblog/archives/000355.html

Hope this helps!

Anthony
Colorado HomeFinder
www.COhomefinder.com

adam

unread,
Jun 22, 2006, 4:16:21 PM6/22/06
to Google Web Toolkit
I'm surprised that nobody is capable of answering this question. I am
having the same problem; I need to access a JNDI datasource definition
for integration with hibernate as well, and I cannot manage to get the
embedded Tomcat to access the JNDI datasource definition. I'd rather
not use an external instance of Tomcat, since I can debug more easily
with the embedded instance.

I think that Rinaldo might have an answer, but I think he posted the
wrong code. We want to be able to open a datasource using code like

Context ctx = new InitialContext();
DataSource source = (DataSource)ctx.lookup("java:comp/env/jdbc/myDB");

Just to clarify, this is code in the RemoteServiceServlet subclass, so
this code *runs on the server*, in the embedded tomcat servlet
container.

I really hope there's some way to do this.

Adam

imbrue

unread,
Jun 22, 2006, 4:38:15 PM6/22/06
to Google Web Toolkit
I'm certainly no expert, but it is my understanding that the
configuration options for the Servlet Container in the hosted shell
(tomcat) are very limited. All you can do is essentially add a servlet
mapping through the use of the <servlet> tag in your module definition
(.gwt.xml) file. There isn't any way currently to specify to this
tomcat instance that you want it to put anything into a JNDI context so
that it can subsequently be looked up via your ctx.lookup call. There
isn't any equivalent to the web.xml configuration available to a normal
Servlet Container setup.

I think (or suspect anyway) that Google plans on adding additional
configuration capability for the hosted tomcat instance, but this isn't
yet available.

Is there anyway that you can get to your required DataSource without
relying on JNDI? Or, could you use a DataManager (old JDBC 1.x) class
instead?

imbrue

unread,
Jun 22, 2006, 4:39:16 PM6/22/06
to Google Web Toolkit
Sorry, DataManager should be DriverManager instead. This was a typo in
my last post.

Eric

unread,
Jun 22, 2006, 4:57:15 PM6/22/06
to Google Web Toolkit

adam wrote:
> I'm surprised that nobody is capable of answering this question. I am
> having the same problem; I need to access a JNDI datasource definition
> for integration with hibernate as well, and I cannot manage to get the
> embedded Tomcat to access the JNDI datasource definition. I'd rather
> not use an external instance of Tomcat, since I can debug more easily
> with the embedded instance.

I struggled with this, and finally happened on the right combination
today. Here's what I had to do:

1. Add the file tomcat/conf/gwt/localhost/ROOT.xml, with the contents:

<Context docBase="ROOT" path="" reloadable="true">
<Resource name="jdbc/demogwt" auth="Container"
type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/demogwt">
<parameter>
<name>factory</name>

<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
</parameter>

<!-- your other parameters here -->
</ResourceParams>
</Context>

2. Add a couple of libraries to my project (and launcher
configuration!). These are the commons-dbcp.jar and
commons-pool.jar... both required to get DBCP working.


That's all I had to do. Took a couple of hours of hacking to get it
working, though.

-eric

rbonazzo

unread,
Jun 23, 2006, 3:33:35 AM6/23/06
to Google Web Toolkit
Hi to all,
with hibernate you don't have to use

Context ctx = new InitialContext();
DataSource source = (DataSource)ctx.lookup("java:comp/env/jdbc/myDB")

I dont' find a way to post a zip file with a part of my project

so I try to explain it with my bad english
package:
com.sp.schedacasa.client (here all the widget, Service,ServiceAsync as
explained in google doc and some post in the forum)

com.sp.schedacasa.server (the servlet and the Hibernate Session
factory,...)
com.sp.schedacasa.server.db.tabelle (here the hibernate.cfg.xml, the
hbm.xml and all the other file generate by hibernate)
here is my hibernate config
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>

<session-factory>
<property name="connection.datasource">java:MySqlDS</property>
<property
name="jndi.url">jdbc:mysql://localhost:3306/rslocal?useUnicode=true&amp;amp;autoReconnect=true</property>
<property name="connection.username">rsAdmin</property>
<property name="connection.password">rsAdmin</property>
<property
name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="connection.pool_size">20</property>
<property name="cglib.use_reflection_optimizer">true</property>
<property
name="jndi.class">org.jboss.cache.transaction.DummyContextFactory</property>
<property name="hibernate.dbcp.maxActive">8</property>
<property name="hibernate.dbcp.maxIdle">8</property>
<property name="hibernate.dbcp.max Wait">-1</property>
<property name="hibernate.dbcp.whenExhaustedAction">1</property>
<property name="hibernate.dbcp.test OnReturn">true</property>
<property name="hibernate.dbcp.ps.maxActive">8</property>
<property name="hibernate.dbcp.ps.maxIdle">8</property>
<property name="hibernate.dbcp.ps.maxWait">1800000</property>
<property name="hibernate.dbcp.ps.whenExhaustedAction">1</property>
<property
name="hibernate.jdbc.use_get_generated_keys">true</property>
<mapping
resource="com/sp/schedacasa/server/db/tabelle/Abitazioni.hbm.xml" />
<mapping
resource="com/sp/schedacasa/server/db/tabelle/Localita.hbm.xml" />
</session-factory>

</hibernate-configuration>

and my HibernateSessionFactory

package com.sp.schedacasa.server;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

/**
* Configures and provides access to Hibernate sessions, tied to the
current
* thread of execution. Follows the Thread Local Session pattern, see
* {@link http://hibernate.org/42.html}.
*/
public class HibernateSessionFactory {

/**
* Location of hibernate.cfg.xml file. NOTICE: Location should be on
the
* classpath as Hibernate uses #resourceAsStream style lookup for its
* configuration file. That is place the config file in a Java package
- the
* default location is the default Java package. <br>
* <br>
* Examples: <br>
* <code>CONFIG_FILE_LOCATION = "/hibernate.conf.xml".
* CONFIG_FILE_LOCATION = "/com/foo/bar/myhiberstuff.conf.xml".</code>
*/
private static String CONFIG_FILE_LOCATION =
"com/sp/schedacasa/server/db/tabelle/hibernate.cfg.xml";

/** Holds a single instance of Session */
private static final ThreadLocal threadLocal = new ThreadLocal();

/** The single instance of hibernate configuration */
private static final Configuration cfg = new Configuration();

/** The single instance of hibernate SessionFactory */
private static SessionFactory sessionFactory;

/**
* Returns the ThreadLocal Session instance. Lazy initialize the
* <code>SessionFactory</code> if needed.
*
* @return Session
* @throws HibernateException
*/
public static Session currentSession() throws HibernateException {
Session session = (Session) threadLocal.get();

if (session != null && !session.isOpen())
session = null;
if (session == null) {
if (sessionFactory == null) {
try {
cfg.configure(CONFIG_FILE_LOCATION);
sessionFactory = cfg.buildSessionFactory();
} catch (Exception e) {
System.err
.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
session = sessionFactory.openSession();
threadLocal.set(session);
}

return session;
}

/**
* Close the single hibernate session instance.
*
* @throws HibernateException
*/
public static void closeSession() throws HibernateException {
Session session = (Session) threadLocal.get();
threadLocal.set(null);

if (session != null) {
session.close();
}
}

/**
* Default constructor.
*/
private HibernateSessionFactory() {
}

}

Hope that's can help you

Regards

Rinaldo

mku...@googlemail.com

unread,
Jun 23, 2006, 6:46:51 AM6/23/06
to Google Web Toolkit
Hi Eric ,

I just followed ur 2 steps ..but iam getting
javax.naming.NamingException: Cannot create resource instance..i tried
a lot...i have just created root.xml in
myproject/tomcat/cpnf/gwt/localhost/root.xml . I think we don't need to
add common-pool and dvcp jar bcoz by deafult we get it eith
naming-factory-dbcp.jar...
I have added the following data in myproject/tomcat/cpnf/gwt/web.xml to
avoid that error...oops nothing...
<resource-ref>
<description> DB Connection </description>
<res-ref-name> jdbc/mydb </res-ref-name>
<res-type> javax.sql.DataSource </res-type>
<res-auth> Container </res-auth>
</resource-ref>...

mku...@googlemail.com

unread,
Jun 23, 2006, 6:58:45 AM6/23/06
to Google Web Toolkit
One more thing..Altenatively i am trying to connect to database with
jdbc classes...My java application in eclipse ide is look like this

import java.sql.*;
public class connection {
public static void main(String[] args) throws SQLException {
try{
Connection con=null;
String driverName="oracle.jdbc.driver.OracleDriver";
Class.forName(driverName);
con=DriverManager.getConnection("jdbc:oracle:thin:@oserver1:1521:milton","greg","greg");
Statement stmt=con.createStatement();
ResultSet rs=stmt.executeQuery("select * from linked_records");
while(rs.next()){
int s =rs.getInt(2);System.out.println(s);
}
}
catch(ClassNotFoundException ce){System.out.println(ce);}
catch(Exception e){System.out.println(e);}
}
}

Iam getting good result as " 23785 " but when i used this same
code(as it is ) in my DemoServiceImpl, iam getting error
**** java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
****. So Iam unable to load the driver...i just wonder about
this..what am i doing wrong ...please please any one help...

pierrot

unread,
Jun 24, 2006, 5:29:02 PM6/24/06
to Google Web Toolkit
I have the mysql-connector-java-3.0.16-ga-bin.jar in the
gwt-windows-1.0.21 directory. Well I use JDBC for the MySQL.

I also had to modify myApplication-shell.cmd so that to include the
mysql jar file in the classpath:

@java -cp
"%~dp0\src;%~dp0\bin;C:/google/gwt-windows-1.0.21/gwt-user.jar;C:/google/gwt-windows-1.0.21/gwt-dev-windows.jar;C:/google/gwt-windows-1.0.21/mysql-connector-java-3.0.16-ga-bin.jar"
com.google.gwt.dev.GWTShell -out "%~dp0\www" %*
com.uniksoft.MyAPP02/MyAPP02.html

and then I was able to use JDBC in the hosted development shell.

pierrot

unread,
Jun 24, 2006, 5:38:38 PM6/24/06
to Google Web Toolkit
Here is an example to connect to a MySQL database from a servlet:

public interface DataService extends RemoteService {
public Person[] getData();
}

public interface DataServiceAsync {
public void getData(AsyncCallback callback);
}

public class DataServiceImpl extends RemoteServiceServlet implements
DataService {
public Person[] getData() {
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
ArrayList values = new ArrayList();
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
con =
DriverManager.getConnection("jdbc:mysql://192.168.0.100:3306/flex","root","321erre1p");
stmt = con.createStatement();
rs = stmt.executeQuery("SELECT First_Name, Last_Name, Days,
Hire_Date, Bonus " + FROM employees");
while (rs.next()) {
values.add( new Person(rs.getString(1), rs.getString(2),
rs.getDate(4).toString(), rs.getString(5)));
}
con.close();
stmt.close();
rs.close();
} catch(Exception e) {
System.out.println(e.toString());
}

return (Person[]) values.toArray( new Person[values.size()] );
}
}

In web.xml:

<?xml version="1.0"?>
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">


<web-app>
<servlet>
<servlet-name>testRPCServlet</servlet-name>
<servlet-class>com.uniksoft.server.DataServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>testRPCServlet</servlet-name>
<url-pattern>/data</url-pattern>
</servlet-mapping>
</web-app>

Hope this help.

Cheerio.

Reply all
Reply to author
Forward
0 new messages