2009-12-21 31 views
2

我的应用程序中包含一个.properties文件,其中包含dataSource属性。 我成立了一个JNDI引用该数据源使用下面的代码:使用其他应用程序与Tomcat创建的JNDI数据源

// 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); 

如果我使用这个应用程序查找,数据源中发现:

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

现在我想用这dataSource在另一个应用程序中。但是,如果我执行的查找操作与之前相同,则不会找到myDataSource(而在Tomcat中仍然存在以前的应用程序,并且在监听程序的帮助下启动jndi绑定)。

如何在第二个应用程序中获取myDataSource,因为我无法在server.xml或context.xml文件中使用Tomcat资源(由于不同的原因,我必须使用此.properties文件)?

谢谢

+0

如果你想要它的服务器范围,它必须在Server.xml文件中设置。 – Zoidberg 2009-12-21 14:57:46

+0

我不认为由Tomcat中的一个webapp绑定的JNDI资源对其他webapps都是可见的。 – skaffman 2009-12-21 15:01:45

+0

因此,你有一个将在tomcat内部运行的web应用程序,并且你不能使用context.xml或web.xml? – ChadNC 2009-12-21 15:18:48

回答

1

你正在做的是不会工作。 J2EE应用程序不允许修改应用程序服务器(J2EE规范,第5.2.2节)和Tomcat JNDI documentation提供的JNDI环境,即每个Web应用程序都获得每个自己的只读JNDI环境。我不确定为什么绑定/重新绑定数据源并不是立即失败,为什么它可以在同一个Web应用程序中工作,但即使是JNDI环境的这种应用程序内部使用也是未记录的行为,我不会依赖它。

0

有几个人已经评论过这个,但我想你的问题的答案是:Tomcat有一个名为server.xml的文件,你需要使用它。我以前也使用过一个很好的参考低于:这里定义

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

资源将是可见的部署所有的应用程序(如果设置正确)。如果您在应用上下文或Web xml文件中设置了JNDI资源,则该资源只应用于您的应用。

0

JNDI上下文对于每个webapp都是私有的。在一个应用程序中创建的上下文无法被其他人访问。

尝试在GlobalNamingResources中创建一个条目,并使用<ResourceLink>这两个webapps中的链接来查看它是否有效。

我之前使用此设置从两个应用程序中读取,但从未尝试从一个应用程序写入。所以不知道它是否会起作用。

2

“本地”JDNI目录在Tomcat中是只读的。不过,你可以在LifecycleListener绑定 “全局” JNDI资源,然后在 “链接” 到您的上下文(S)(*):

您需要实现org.apache.catalina.LifecycleListener http://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/LifecycleListener.html

然后在你的服务器上注册它。像这样的XML(连同其他听众):

<Listener className="yourlistener.YourLifecycleListener"/> 

你的听众应该等待2个事件:

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

那么你就必须传播资源的访问来自“全球的“链接”起来“JNDI目录 ”使用ResourceLink元素本地“ JNDI目录中的META-INF/context.xml中:

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

为我工作至今。

(*)一些注释:

使用生命周期侦听器有一个优势。由于上下文创建的顺序不能保证。好处是所有的上下文都会看到这个对象的创建。

如果您需要在生命周期侦听器创建时更动态地创建和配置数据源创建,请注意您可以绑定实现Factory模式的自定义类。

为避免类加载不兼容问题,可以考虑将您的监听器,数据源等类放在Tomcat lib目录下的jar文件中,这样它们就包含在通用类加载器中。

问候。

0

实际上,如果servlet实现了org.apache.catalina.ContainerServlet,则可以访问其他JNDI资源。这个接口有一个org.apache.catalina.Wrapper属性,它由容器本身“填充”。

通过这个,我创建了一个简单的应用程序来监视资源。

但是,我想在监听器中这样做,所以我的资源监视器可以在容器启动时启动。任何人都知道的方式?

相关问题