【发布时间】:2011-01-21 14:04:45
【问题描述】:
我有一个需要两项设置的网络应用:
- 一个 JDBC 数据源
- 字符串标记
我非常希望能够将一个 .war 部署到各种不同的容器(jetty、tomcat、gf3 最低)并在容器内的应用程序级别配置这些设置。
我的代码是这样做的:
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")
假设我使用 glassfish 管理界面创建了两个 jdbc 资源:jdbc/test-datasource 和 jdbc/live-datasource,它们连接到同一架构的不同副本、不同服务器、不同凭据等。假设我想将它部署到 glassfish 并将其指向测试数据源,我可能在我的 sun-web.xml 中有这个:
...
<resource-ref>
<res-ref-name>jdbc/datasource</res-ref-name>
<jndi-name>jdbc/test-datasource</jndi-name>
</resource-ref>
...
但是
- sun-web.xml 进入我的战争,对吧?
- 肯定有办法通过管理界面做到这一点
我是否在尝试做正确的事情?其他容器是否使这更容易?我对 jetty 7 如何处理这个问题特别感兴趣,因为我将它用于开发。
编辑 Tomcat 有一个合理的方法来做到这一点:
使用:创建$TOMCAT_HOME/conf/Catalina/localhost/webapp.xml:
<?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>
请注意,override="false" 的意思正好相反。这意味着这个设置不能被web.xml覆盖。
我喜欢这种方法,因为该文件是 container 配置而不是战争的一部分,但它不是全局配置的一部分;它是特定于 webapp 的。
我想我对 glassfish 的期望更高一些,因为它应该有一个完整的网络管理界面,但我会很高兴有与上述相同的东西。
【问题讨论】:
-
您是否需要能够同时访问两个数据源...从同一台服务器?
-
实际上也许不是,但我想保持它们都配置。实际上,我们有可能同时需要实时服务器上的两个数据源。
-
我也遇到了同样的问题,还没有找到好的解决方案。我目前使用不同的 GF 域来部署我的应用程序,但它不是最佳解决方案,因为每个域都是操作系统进程,至少需要 300 MB 并且很难管理多个域。
标签: deployment glassfish jndi war