Correct way to make datasources/resources a deploy-time setting

Posted by Draemon on Stack Overflow See other posts from Stack Overflow or by Draemon
Published on 2010-02-26T18:39:43Z Indexed on 2010/03/16 22:01 UTC
Read the original article Hit count: 274

Filed under:
|
|
|

I have a web-app that requires two settings:

  • A JDBC datasource
  • A string token

I desperately want to be able to deploy one .war to various different containers (jetty,tomcat,gf3 minimum) and configure these settings at application level within the container.

My code does this:

InitialContext ctx = new InitialContext();
Context envCtx = (javax.naming.Context) ctx.lookup("java:comp/env");
token = (String)envCtx.lookup("token");
ds = (DataSource)envCtx.lookup("jdbc/datasource")

Let's assume I've used the glassfish management interface to create two jdbc resources: jdbc/test-datasource and jdbc/live-datasource which connect to different copies of the same schema, on different servers, different credentials etc. Say I want to deploy this to glassfish with and point it at the test datasource, I might have this in my sun-web.xml:

...
<resource-ref>
  <res-ref-name>jdbc/datasource</res-ref-name>
  <jndi-name>jdbc/test-datasource</jndi-name>
</resource-ref>
...

but

  • sun-web.xml goes inside my war, right?
  • surely there must be a way to do this through the management interface

Am I even trying to do the right thing? Do other containers make this any easier? I'd be particularly interested in how jetty 7 handles this since I use it for development.

EDIT Tomcat has a reasonable way to do this:

Create $TOMCAT_HOME/conf/Catalina/localhost/webapp.xml with:

<?xml version="1.0" encoding="UTF-8"?>
<Context antiResourceLocking="false" privileged="true">
  <!-- String resource -->
  <Environment name="token" value="value of token" type="java.lang.String" override="false" />

  <!-- Linking to a global resource -->
  <ResourceLink name="jdbc/datasource1" global="jdbc/test" type="javax.sql.DataSource" />

  <!-- Derby -->
  <Resource name="jdbc/datasource2"
    type="javax.sql.DataSource"
    auth="Container"
    driverClassName="org.apache.derby.jdbc.EmbeddedDataSource"
    url="jdbc:derby:test;create=true"
    />

  <!-- H2 -->
  <Resource name="jdbc/datasource3"
    type="javax.sql.DataSource"
    auth="Container"
    driverClassName="org.h2.jdbcx.JdbcDataSource"
    url="jdbc:h2:~/test"
    username="sa"
    password=""
    />
</Context>

Note that override="false" means the opposite. It means that this setting can't be overriden by web.xml.

I like this approach because the file is part of the container configuration not the war, but it's not part of the global configuration; it's webapp specific.

I guess I expect a bit more from glassfish since it is supposed to have a full web admin interface, but I would be happy enough with something equivalent to the above.

© Stack Overflow or respective owner

Related posts about .war

Related posts about deployment