Thursday Jul 05, 2007

JNDI + JDBC and Debugging with Sun Java System Webserver 7

My web searches didn't find all these steps in one nice recipe, so I thought I'd write up what I did to replace a DriverManager.getConnection() call with a JNDI lookup to use a DB connection pool managed by Sun Java System Webserver 7.

First, the java code itself.. I found that either of these worked:

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

or

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

Both followed by:

Connection c = ds.getConnection();

The InitialContext/Context classes are in javax.naming and DataSource is in javax.sql.  You may also use ds.getConnection(username, password).

Next, the web application configuration so the "jdbc/mydb" lookup will work. The WEB-INF/web.xml file needs a section like this inside the main <web-app> tag: 

<resource-ref>
  <description>My database connection</description>
  <res-ref-name>jdbc/mydb</res-ref-name>
  <res-type>javax.sql.DataSource</res-type>
  <res-auth>Container</res-auth>
  <res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>

I'm not too sure what the res-auth and res-sharing-scope items are about (probably more web searches can reveal this), but I used NetBeans 5.5 to create this entry and it added those.  In NetBeans, open the web.xml file and select the "References" section in the buttons across the top.  Under "Resource References" click Add and it shows a dialog to enter all these settings.

The next step is a bit of magic glue to connect this resource reference to its definition in SJSWS7 (pretty sure this is needed for SJSAS9 too).  I don't know why the server can't use the resource name directly.. also note that without this glue the error messages/java exceptions provide no clue about what is wrong.  The magic: create a WEB-INF/sun-web.xml file that simply maps between the resource name and the JNDI name.

<sun-web-app>
  <resource-ref>
    <res-ref-name>jdbc/mydb</res-ref-name>
    <jndi-name>jdbc/mydb</res-ref-name>
  </resource-ref>
</sun-web-app>

I suppose you could use different names, but why introduce confusion about which name to use?  To create this file in NetBeans I opened the Web Pages / WEB-INF subtree in the project viewer, then right clicked on WEB-INF and chose New / XML Document.

The last step is to define the database connection in the app container.  In SJSWS, login to the administration server and browse to the configuration for the instance in use.  Click the Java tab and Resources subtab.  Under JDBC Resources click New and follow the wizard to define the DB connection and pool settings.  The default value for the JNDI name was "jdbc-resource-1" but I used / instead of - in my name, "jdbc/mydb".  For the Datasource Class Name be sure to enter the DataSource implementation for the DB type, not the Driver class used with DriverManager.getConnection().

 

Yay, I have a database connection via a connection pool managed by SJSWS7.  But now I wanted to debug other things in my application.. in NetBeans 5.5 you can select Tools / Update from the menu and add support for deployment to SJSWS7.  However, I didn't find this at first so I added a few lines to my build.xml file so when I do "Build" in NetBeans it also deploys to my SJSWS server.

<target name="-post-dist">
  <echo>Deploy to my SJSWS instance</echo>
  <exec executable="/path/to/webserver7/bin/wadm">
    <arg value="--user=admin"/>
    <arg value="--password-file=/path-to/admin-pw"/>
    <arg value="--commands-file=/path-to/deploy-myapp"/>
    <arg value="--no-prompt"/>
  </exec>
</target>

The admin-pw file has a single line with wadm_password={password}.  The deploy-myapp file has:

puts [add-webapp --config=myconfig.mydomain.com --vs=myserver.mydomain.com --uri=/myapp /path/to/myapp/dist/MyApp.war]
puts [deploy-config myconfig.mydomain.com]


Next I setup the debugger, which is possible since both sides support JPDA (Java™ Platform Debugger Architecture).  Login to the SJSWS admin server.  In the settings for my configuration under Java tab / JVM Settings subtab there is a Debug section.  There is a checkbox to turn on debug mode and a line to see or set the port number used by the debugger.  After restarting the server in debug mode you can select "Attach Debugger" in the Run menu of NetBeans.  Enter the port number here and you can debug the app running in SJSWS.

Comments:

Post a Comment:
  • HTML Syntax: NOT allowed