Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have a .properties file in my application which contains dataSource properties. I set up a JNDI reference to this dataSource using the following code :

// first I create MyDataSource from the properties found in the .properties file
//then :

Context initContext = new InitialContext();
initContext.createSubcontext("jdbc");
initContext.createSubcontext("jdbc/oracle");
initContext.rebind(jdbc/oracle/myDataSource, MyDataSource);

If I use a lookup in this application, the dataSource is found :

Context initContext = new InitialContext();
BasicDataSource dataSource = 
            (BasicDataSource) initContext.lookup("jdbc/oracle/myDataSource")
//everything works fine and I can use my dataSource to getConnection,
//requests, etc...

Now I would like to use this dataSource in another application. But if I do the same lookup than previously, I don't find myDataSource (whereas there is still the previous application in tomcat and the jndi binding is done on start-up with the help of a listener).

How can I get myDataSource in this second application, given that I can't use a Tomcat's resource in server.xml or a context.xml file (for different reasons I have to use this .properties file)?

Thanks

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
151 views
Welcome To Ask or Share your Answers For Others

1 Answer

"local" JDNI directories are read-only in Tomcat. Nevertheless, you can bind "global" JNDI resources in a LifecycleListener, and then "link" them to your context(s)(*):

You need to implement org.apache.catalina.LifecycleListener http://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/LifecycleListener.html

Then register it in your server.xml like this (along with the other listeners):

<Listener className="yourlistener.YourLifecycleListener"/>

Your listener should await for 2 events:

public void lifecycleEvent(final LifecycleEvent event) {

    if (Lifecycle.START_EVENT.equals(event.getType())) {
      // Create your datasource instance...
      Context initContext = new InitialContext();
              initContext.createSubcontext("jdbc");
              initContext.createSubcontext("jdbc/oracle");
              initContext.rebind("jdbc/oracle/myDataSource", myDataSource);
    } else if (Lifecycle.STOP_EVENT.equals(event.getType())) {
      // unbind...
    }
}

Then you'll have to propagate resource accesses by "linking" them from "global" JNDI directory to "local" JNDI directory using ResourceLink element in your META-INF/context.xml:

<ResourceLink name="jdbc/oracle/myDataSource" global="jdbc/oracle/myDataSource"
    type="javax.sql.DataSource" />

That worked for me so far.

(*) Some notes:

There's an advantage on using lifecycle listeners. Since the order of context creation is not guaranteed. The advantage is that all of your contexts will see this object created.

If you need to create and configure datasource creation more dynamically that on lifecycle listener creation, note that you can bind a custom class implementing the Factory pattern.

To avoid classloading incompatibility problems, consider putting your listener, datasource, etc. classes in a jar file in the Tomcat lib directory, so they're included y the common classloader.

Regards.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...