Skip to main content

skip to main content

developerWorks  >  Open source | Java technology | WebSphere  >

Three ways to connect a database to a Geronimo application server

Setting up JDBC data sources in Geronimo

developerWorks
Document options

Document options requiring JavaScript are not displayed

Discuss

Sample code


Rate this page

Help us improve this content


Level: Intermediate

Neal Sanche (neal@nsdev.org), Java developer and author, Freelance

21 Jun 2005

Need to connect your database to a Web application written for Geronimo? Though still young, Geronimo is modular and well architected. You can use any of three methods to connect a database to a Geronimo application server; each method creates a different type of Java™ Database Connectivity (JDBC) data source. Follow along using the included example application and a downloadable Eclipse IDE project to learn how to hook things up and get your application talking through a JDBC connection pool deployed in Geronimo.

To set up JDBC data sources in the Apache Geronimo application server, you should have:

  • A server with at least a Milestone 3 (M3) release of Geronimo. See Resources for a link to download Geronimo.
  • Some knowledge of the J2EE concepts, such as JSPs, tag libraries, deployment descriptors, and packaging your Web applications in a .war file. (As we develop an example application, you'll be guided through most of these topics. So if you're new to Java™ Web application development, you'll be able to follow along.)
  • Some experience running a database server. This article covers the details of using MySQL for database access. Even so, be aware that you can easily substitute any database server and JDBC driver within the example files to get your favorite database running with the example.

You can connect a database to a Geronimo application server in three ways:

  • Create a global, server-wide data source for use by many applications.
  • Embed the JDBC connection pool into a single-deployed enterprise application, though, when using this method, the application must be bundled as an .ear file.
  • Create module-scoped JDBC data sources that allow fine-grained control over which parts of your application can access the database.

Currently only Web applications can have module-scoped access to a database. But the Geronimo team has discussed getting module-scoped access working with other types of application modules in the releases closer to the actual 1.0 release.

All three of these methods for connecting a database to a Geronimo application server are covered in this article, along with an example application that uses these concepts. The example application will be extended in future articles to exercise more of the J2EE stack, but for now we'll exercise only the Web application (Servlet and JSP layer) as well as the JDBC connector layer of the J2EE stack.

Deployment plans

Geronimo is a flexible application server capable of hosting many different application components. Geronimo uses deployment plans to help the application deployment system figure out which pieces of an application need to go where. The J2EE specification leaves some of the details of deployment up to the application server provider to define. The Apache Geronimo team currently uses deployment plans to tell the server what parts are available as well as how they should be configured and deployed.

In the case of a Web application, the deployed .war file will contain a deployment plan called geronimo-jetty.xml that is placed in the WEB-INF directory of your Web application along with the web.xml file. This deployment plan helps the Geronimo server with final application details, such as what the Web application context root is (the path part of the URL to the application when typed into the user's browser) and any resource references the application may need. This will become more clear after going through the sample Web application. If you are fluent in XML Schema Definition language (aren't we all?) then you might have a look at the $geronimo-root$/schema/geronimo-jetty.xsd file, which will give you some ideas about what you're allowed to put into the deployment plan. Also, someday, when all of our XML editors support XML Schema, we'll be guided by our XML editors into creating perfect XML files that satisfy the schemas. For now, you'll have to learn to read the schemas a little.

An enterprise application module can be similarly augmented with a deployment plan. These modules, packaged in an .ear file, will have a geronimo-application.xml deployment plan alongside the application.xml file inside the META-INF directory. After looking at the geronimo-application.xsd XML schema file, you may understand that this deployment plan allows you to set up a configId, a parentId, the application name, and dependencies. The dependencies are useful in allowing the application server to load what is required for an application to run correctly when the application is deployed. You'll see more about geronimo-application.xml later in this article.



Back to top


Creating a global JDBC data source

To create a global data source that can be used by multiple applications within the Geronimo server, you must create a deployment plan and correctly deploy it into the server. This is done by creating an XML file that describes to the server the details of what application components to create, what their configuration parameters should be, and what dependencies the configuration has.

The JDBC driver, which is usually packaged into a .jar file, is required as a dependency to make this all work. Geronimo has a clean and tidy place for keeping all of its required dependency .jar files. On your Geronimo server's home directory, you'll find a subdirectory called repository that, in turn, contains subdirectories for each shared component to declare. Inside each of these subdirectories is a jars subdirectory into which you can place the required files.

Because you want to connect to a local MySQL database, we've downloaded the mysql-connector-java-3.1.8-bin.jar file from the MySQL Web site (see Resources to link to this site). Create a directory under repository called mysql, and place the .jar file into a jars directory.

Now you need to create a deployment plan for the J2EE connector. Notice in the XML file that there is a dependency element specifying the URI path within the repository directory where the JDBC driver .jar is located. To modify this to suit your own database, edit the configId and the config-property-setting elements for UserName, Password, Driver, and ConnectionURL, shown in Listing 1.


Listing 1. Editing the configId and config-property-settings elements
<?xml version="1.0">

<connector xmlns="http://geronimo.apache.org/xml/ns/j2ee/connector" 
  version="1.5" 
  configId="MysqlDatabase"  
  parentId="org/apache/geronimo/Server">

<dependency>
  <uri>
    mysql/jars/mysql-connector-java-3.1.8-bin.jar
  </uri>
</dependency>

<resourceadapter>
  <outbound-resourceadapter>
    <connection-definition>
      <connectionfactory-interface> 
        javax.sql.DataSource 
      </connectionfactory-interface>
      <connectiondefinition-instance>
        <name>MysqlDataSource</name>
        <config-property-setting name="UserName"> 
          geronimo 
        </config-property-setting>
        <config-property-setting name="Password"> 
          geronimo 
        </config-property-setting>
        <config-property-setting name="Driver"> 
          com.mysql.jdbc.Driver 
        </config-property-setting>
        <config-property-setting name="ConnectionURL">
          jdbc:mysql://localhost/geronimo 
        </config-property-setting>
        <config-property-setting name="CommitBeforeAutocommit"> 
           false 
        </config-property-setting>
        <config-property-setting name="ExceptionSorterClass"> 
           org.tranql.connector.NoExceptionsAreFatalSorter
        </config-property-setting>

        <connectionmanager>
          <local-transaction/>
          <single-pool>
             <max-size>10</max-size>
             <min-size>0</min-size>
             <blocking-timeout-milliseconds> 
                5000 
              </blocking-timeout-milliseconds>
              <idle-timeout-minutes>
                30
              </idle-timeout-minutes>
              <match-one/>
          </single-pool>
        </connectionmanager>

        <global-jndi-name> 
          jdbc/MysqlDatabase 
        </global-jndi-name>

      </connectiondefinition-instance>
    </connection-definition>
  </outbound-resourceadapter>
</resourceadapter>
</connector>

Save the XML file as mysql-plan.xml to be clear that it is a deployment plan for the MySQL database. Next, deploy the file. To do this, the Geronimo Deploy command is used. Because this is a J2EE Connector, the tranql-connector-1.0-SNAPSHOT.rar file, found in the Geronimo repository under tranql/rars, is also required. Put the XML file into the Geronimo root directory, and use the following command to complete the deployment from that directory.

Type the following single command on one line. It's split to two lines here only for space reasons.

$ java -jar bin\deployer.jar mysql-plan.xml 
repository\tranql\rars\tranql-connector-1.0-SNAPSHOT.rar 

You will be prompted for your username and password, which default to system and manager, respectively. If you're on a UNIX® operating system, flip your backslashes to forward slashes. If all goes well, the command will respond with Deployed MysqlDatabase. Or, if you've changed your configId to something else, it will reference that. If there was a problem, debug it by looking at the Geronimo logs.



Back to top


Creating application-scoped JDBC data sources

The second type of database configuration scoping is the application-scoped data source. The file format for the mysql-plan.xml file described in the Creating a global JDBC data source section can be reused with this type of deployment. The following procedure is used to embed the database access information directly into your application's .ear file.

First, as mentioned in the introduction, you need to create a META-INF/geronimo-application.xml deployment plan, shown here:


Listing 2. Creating a META-INF/geronimo-application.xml deployment plan
<application
xmlns="http://geronimo.apache.org/xml/ns/j2ee/application"
configId="MyApplication">

<module>
<connector>tranql-connector-1.0-SNAPSHOT.rar</connector>
<alt-dd>mysql-plan.xml</alt-dd>
</module>
</application>

Next, bundle the tranql-connector-1.0-SNAPSHOT.rar file into your .ear file. Also, reference it inside the application.xml file (within a connector element inside a module element) as you would for any other module within the bundled .ear file. The trick is that the deployment plan adds the information (in the alt-dd element) that the mysql-plan.xml file uses to provide the connector configuration. Don't forget to bundle the mysql-plan.xml file into your application .ear file.



Back to top


Creating module-scoped JDBC data sources

The third type of scoping for database configuration is probably the most unique to Geronimo. Obviously, the Geronimo team has thought through scoped access to data sources thoroughly and has been working at refining data source access to the module level. This is different from many application servers, which only allow either application-scoped or globally-scoped data sources. This module-level scoping provides a degree of abstraction (data hiding) that lets you restrict visibility of the database to a specific module. This means that no other modules can modify the database, reducing the debugging paths you need to follow in a multi-tiered application architecture when problems arise.

To complete this type of configuration, simply cut the connector element from the mysql-plan.xml file, and embed it into a new resource element within the geronimo-jetty.xml file between the text emphasized in bold in the following code:


Listing 3. Embedding the connector element into a new resource element
<web-app xmlns="http://geronimo.apache.org/xml/ns/web/jetty"
xmlns:naming="http://geronimo.apache.org/xml/ns/naming"
...>
...
<resource>
<external-rar>
tranql/rars/tranql-connector-1.0-SNAPSHOT.rar
</external-rar>
<!-- Place the connector element, verbatim, below -->
<connector

</connector>
</resource>

As you can see, the tranql-connector-1.0-SNAPSHOT.rar file will have to be placed in the appropriate subdirectory of the $GERONIMO_HOME/repository directory for this to work, which should be true in a newly deployed server.

Why would you use this type of database configuration scoping? If you had a database table that you wanted to make sure was available only to your Web application components and not to any other components or applications, this would be ideal. It has the nice effect of requiring no extra files to be deployed, because the tranql.rar file is a shared resource. The other nice benefit is that with only some extra text in the geronimo-jetty.xml file, your application's database configuration is embedded, which may mean easier clustering of Web applications in the future.



Back to top


Using a data source

To describe how to use the data source, I've written a small application that uses the global-scoped database connector deployed with the mysql-plan.xml file described earlier. I chose this method for its simplicity and because I was considering developing only a Web application, which is deployed in a .war file. So the application-scoped deployment does not apply (it's available only to .ear file deployment plans). Therefore, we could choose from global-scoped deployment or module-scoped deployment in this case.

A small Eclipse project is included

Included in this article is a small Eclipse IDE project that you can load. It provides an Ant script to build the sample application and deploy it into your Geronimo server. I used Eclipse 3.1M6 and a version of the Lomboz EJB plug-in (optional) to organize the code for me. You certainly don't need to go to this extent in order to deploy the application.

The file tree organization of the sample project is shown below in Figure 1. This illustrates a standard Web-application source code layout consisting of a few Java source files, a .jsp file, some supporting deployment descriptors, and the Geronimo deployment plan. I've included one of my favorite JSP tag libraries, DisplayTag (see Resources for a link), which makes displaying a tabular representation of a collection of Java objects easy. As a bonus, this also shows you how to include and use a JSP tag library within the Geronimo environment.


Figure 1. Structure of the Eclipse sample project files
Structure of the Eclipse sample project files

Some database setup is required

Use the following MySQL commands to create the database, grant permissions on it, and add a table to it:


Listing 4. Setting up the database with MySQL commands
$ mysql -u root -p mysql
password: ****
> create database geronimo;
> grant all on geronimo.* to geronimo@127.0.0.1 
identified by 'geronimo';
> grant all on geronimo.* to geronimo@localhost 
identified by 'geronimo';
> use geronimo;
Database Changed
> create table phone ( 
name varchar(255) primary key, 
phone varchar(255)
);
> insert into phone ('Ralph Nader', '555-2221');
> insert into phone ('Albert Einstein','555-2222');

With this simple database created, you'll see (in Listing 5) a class that returns a list of PhoneBookEntry objects. It obtains a JDBC connection from a JNDI lookup for a resource-mapped data source. The code appears in the phonebook/JavaSource directory under the org.acme.phonebook package.


Listing 5. getPhoneList() method returns a list of PhoneBookEntry objects
/**
 * Obtain a phone list from a JDBC Datasource.
 */
public Collection getPhoneList() 
throws NamingException, SQLException {

      ArrayList list = new ArrayList();

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

      Connection con = null;
      Statement stmt = null;
      ResultSet rs = null;

      try {
            con = ds.getConnection();
            stmt = con.createStatement();
            rs = stmt.executeQuery("select name,number from phone");
            while (rs.next()) {
                  PhoneBookEntry entry = 
                        new PhoneBookEntry(rs.getString("name"),
                              rs.getString("number"));
                  list.add(entry);
            }
            return list;
      } finally {
            if (ctx != null)
                  ctx.close();
            if (rs != null)
                  rs.close();
            if (stmt != null)
                  stmt.close();
            if (con != null)
                  con.close();
}
}

You can see that the data source is obtained by asking an InitialContext instance, named ctx here, for the DataSource named java:comp/env/jdbc/DataSource by way of the lookup() method. Then the DataSource is used to get a database connection from the pool, which is eventually used to perform a query and iteration through the result set, returning the resulting list of PhoneBookEntry objects.

The astute would be asking where the java:comp/env/jdbc/DataSource name is specified. This happens partly in the web.xml file and partly in the geronimo-jetty.xml deployment plan.

This is how it looks in the web.xml file:


Listing 6. Specifying the java:comp/env/jdbc/DataSource name in the web.xml file
<resource-ref>
      <res-ref-name>jdbc/DataSource</res-ref-name>
      <res-type>javax.sql.DataSource</res-type>
      <res-auth>Container</res-auth>
      <res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>

And this is how it looks in the geronimo-jetty.xml file:


Listing 7. Specifying the java:comp/env/jdbc/DataSource name in the geronimo-jetty.xml file
<naming:resource-ref>
      <naming:ref-name>jdbc/DataSource</naming:ref-name>
      <naming:resource-link>MysqlDataSource</naming:resource-link>
</naming:resource-ref>

You can see that in the web.xml file, the alias jdbc/DataSource is established. And in the geronimo-jetty.xml file, the reference is linked with the MysqlDataSource defined earlier when we deployed the mysql-plan.xml.

To ensure that the MysqlDataSource is loaded automatically when deploying the application, you can set the parentId attribute of the web-app element in the geronimo-jetty.xml file to MysqlDatabase. This tells Geronimo that the Web application, when deployed, requires the database deployment to be started first. This is a nice dependency mechanism.



Back to top


Writing a simple JSP

There are many methods of writing Web applications. You can write servlets, introduce an XML/XSLT template engine, or simply write HTML. You can also write JSPs, which are much like HTML with a little XML markup that allows Java code to be embedded into the page. It also allows modules, called tag libraries, to be embedded into the application, increasing the number of XML tags that can be added to the HTML and provide useful functionality. There's nothing special about writing a JSP page in Geronimo. Jetty, the Web container behind Geronimo, is a well-established container with excellent performance and a well-respected development team behind it.

The JSP found in the sample application simply instantiates a Java object and uses the DisplayTag tag library to display the entries in a tabular form. The code is extremely simple and can be found in Listing 8.


Listing 8. The index.jsp file
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://displaytag.sf.net" prefix="display" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Geronimo Phonebook</title>
</head>

<body>

<jsp:useBean id="phonelist" 
class="org.acme.phonebook.PhoneList" 
scope="request"/>

<p>This is a test application to show very simple 
database access.
</p>

<display:table name="phonelist.phoneList"/>

</body>
</html>

Compiling and deploying

Now you need a simple build.xml file to use with the Ant build system. You should be able to type ant in the main directory of the sample files and have it build as long as the build.xml file is configured with the correct properties.

In the build.xml file there is an Ant task, shown in Listing 9.


Listing 9. An Ant task in the build.xml
<target name="deploy" depends="compile,package" description="--> 
A simple Geronimo Phonebook JDBC Application">
     <java jar="${geronimo.root}/bin/deployer.jar" fork="true">
          <arg value="--user"/>
          <arg value="${geronimo.user}"/>
          <arg value="--password"/>
          <arg value="${geronimo.password}"/>
                    <arg value="undeploy"/>
          <arg value="PhoneBookWeb"/>
     </java>
     <java jar="${geronimo.root}/bin/deployer.jar" fork="true">
                    <arg value="--user"/>
                    <arg value="${geronimo.user}"/>
                    <arg value="--password"/>
                    <arg value="${geronimo.password}"/>
                    <arg value="deploy"/>
          <arg value="phonebook.war"/>
     </java>
 </target>

As you can see, the deployer.jar file is executed and asked to undeploy the Web application. While I used Ant with this small application, you may also consider using Maven, which, according to the Geronimo development team, makes automatic deployment of a Geronimo application much easier.



Back to top


Summary

Geronimo is still young and may show its age periodically while you are trying out the example application. However, Geronimo may be one of the most modular and cleanly architected application servers around, and it will likely continue to improve rapidly. This year will hopefully see a standards-compliant 1.0 release of the software, so it's worth getting to know it now.

This article has covered the three methods of deploying a database connector in Geronimo. As an exercise, you could modify the Web-application deployment plan to embed the connector element and convert it from globally scoped to module scoped.

Be sure to follow the development of this small phone book application through several more iterations in upcoming articles, where you'll learn about more of the features of Geronimo and what sets it apart from many other J2EE application servers.




Back to top


Download

DescriptionNameSizeDownload method
Source code for the phone book applicationGeronimoPhonebook.zip1,527 KBHTTP
Information about download methods


Resources



About the author

Neal Sanche is a Java developer recently beached in the Microsoft® .NET world and fighting for any ties back to his old, comfortable roots. His experience includes development of several commercial J2EE applications, as well as several stand-alone Java applications. In his spare time, he writes music, takes photographs, and writes technical articles. See several examples at his Web site. Contact Neal at neal@nsdev.org.




Rate this page


Please take a moment to complete this form to help us better serve you.



 


 


Not
useful
Extremely
useful
 


Share this....

digg Digg this story del.icio.us del.icio.us Slashdot Slashdot it!



Back to top


IBM is a registered trademark of International Business Machines Corporation in the United States, other countries, or both. Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both. Microsoft is a registered trademark of Microsoft Corporation in the United States, other countries, or both. UNIX is a registered trademark of The Open Group in the United States and other countries. Other company, product, or service names may be trademarks or service marks of others.