1

一个简短的问题:如何替换 Tomcat 中默认的只读 JNDI 实现?

我正在开发一个使用 JNDI 数据源(连接池)连接到各种 DBMS 的 Web 应用程序。我需要能够将此应用程序部署到 Amazon Elastic Beanstalk 以实现可扩展性。Amazon Elastic Beanstalk 目前不支持使用 JNDI 数据源,但按照 Amazon 的建议直接通过 JDBC 驱动程序(没有连接池)访问数据库从性能和架构的角度来看并没有吸引力。但是,可以使用经过修改的 Tomcat 创建自定义 AMI,该 Tomcat 使用 JNDI 数据源。我的应用程序的另一个要求是数据源可以动态创建,并且数据源定义存储在一个集中位置,以便参与 Elastic Beanstalk 集群的所有机器都可以访问它们。

我创建了一个自定义读/写 JNDI 实现,它将数据源定义存储在 S3 中,并将数据源实例(连接池)缓存在内存中。要替换 Tomcat 的默认只读 JNDI 实现,我必须使用以下键启动 Tomcat:-Dcatalina.useNaming=false -Djava.naming.factory.initial=com.company.product.AwsContextFactory -Djava.naming.factory.url.pkgs=com.company.product.awsjndi. 这com.company.product.AwsContextFactory是我的上下文工厂com.company.product.awsjndi的名称,并且是包含AwsContextFactory. 但是,要使这项工作在AwsContextFactory.getInitialContext我必须java.naming.factory.url.pkgs从环境中显式删除预先存在的引用并添加对我的包的引用,如下所示:

public Context getInitialContext(Hashtable environment) throws NamingException {
    environment.remove("java.naming.factory.url.pkgs");
    environment.put("java.naming.factory.url.pkgs", "com.company.product.awsjndi");
    AwsContext context = new AwsContext((Hashtable) environment, null);
    return context;
}

如果不这样做,Tomcat 的默认只读 JNDI 将占上风,并且不使用我的 AwsContextFactory。据我了解,这是一种黑客行为,没有必要这样做。指定 JVM-Djava.naming.factory.url.pkgs=com.company.product.awsjndi应该是我需要做的所有事情。这是Tomcat中的错误还是我做错了什么?

感谢您的建议。

P。

4

0 回答 0