Using a JNDI datasource created by another application with Tomcat

别来无恙 提交于 2019-11-28 11:44:51

"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.

What you are trying to do is not going to work. J2EE applications are not allowed to modify the JNDI environment provided by the application server (J2EE spec, section 5.2.2) and the Tomcat JNDI documentation also states, that each web applications gets each own read-only JNDI environment. I'm not sure why binding/rebinding your datasource is not failing immediately and why it's working within the same web application, but even such application-internal usage of the JNDI environment is undocumented behaviour, which I would not rely on.

A couple people have already commented on this, but I think the answer to your question is: Tomcat has a file called server.xml that you need to use. A good reference I have used before is below:

http://tomcat.apache.org/tomcat-5.5-doc/jndi-resources-howto.html

Resources defined here will be visible to all apps deployed (if set up correctly). If you set up a JNDI resource in your apps context or web xml file, it should only be available to your app.

JNDI context are private to each webapp. Context created in one app can't be accessed by others.

Try to create an entry in GlobalNamingResources and links in both webapps using <ResourceLink> to see if it works.

I used this setup before to read from both apps but never tried to write from one. So not sure if it will work.

Actually, it is possible to access others JNDI resources, if the servlet implements org.apache.catalina.ContainerServlet. This interface has a org.apache.catalina.Wrapper attribute, that is "populated" by the container itself.

through that, I created a simple application to monitor resources.

BUT, I would like to do that in a listener, so my resource monitor could start when the container starts. Anyone knows a way?

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!