当前位置: 首页 > 知识库问答 >
问题:

如何创建自定义c3p0 ComboPooledDataSource并引用tomcatcontext.xml

赏梓
2023-03-14

我有一个tomcat应用服务器,我的DB连接是在上下文中定义的。xml并以JNDI的形式获取数据源。

<Context>

    <!-- Default set of monitored resources. If one of these changes, the    -->
    <!-- web application will be reloaded.                                   -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>

    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->

<Resource name="datasource/test" auth="Container"
                type="com.mchange.v2.c3p0.ComboPooledDataSource"
                    factory="org.apache.naming.factory.BeanFactory"
                        user="abc"
                        password="abc123"
                        jdbcUrl="jdbc:mysql://localhost:3306/jacplus"
                        driverClass="com.mysql.jdbc.Driver"
                        minPoolSize="2"
                        initialPoolSize="30"
                        maxPoolSize="50"
                        idleConnectionTestPeriod="600"
                        acquireRetryAttempts="30"/>
                        
 </Context>

而不是在上下文中硬编码用户名和密码。xml。我想在aws secret manager中存储db凭据,并使用从aws secret manager检索到的db凭据创建数据源。

为此,我创建了以下自定义ComboPooledDataSource类。

import com.mchange.v2.c3p0.AbstractComboPooledDataSource;

import javax.naming.Referenceable;
import java.io.Serializable;

    public final class CustomComboPoolDataSource extends AbstractComboPooledDataSource implements Serializable, Referenceable {
    
    
    }



    import com.mchange.v2.c3p0.PoolConfig;
    import org.apache.tomcat.jdbc.pool.DataSourceFactory;
    
    import java.sql.SQLException;
    import java.util.Properties;
    import javax.naming.Context;
    import javax.sql.DataSource;
    
    import org.apache.tomcat.jdbc.pool.PoolConfiguration;
    
    public class SecureTomcatDataSourceImpl extends DataSourceFactory {
    
        public SecureTomcatDataSourceImpl() {
    
        }
    
        @Override
        public DataSource createDataSource(Properties properties, Context context, boolean XA) throws SQLException {

String userName = getFromAWSSecretManager("username");
String password = getFromAWSSecretManager("password");
    
            PoolConfiguration poolProperties = SecureTomcatDataSourceImpl.parsePoolProperties(properties);
            PoolConfig poolConfig = new PoolConfig(properties);
    
            CustomComboPoolDataSource customDataSource = new CustomComboPoolDataSource();
            customDataSource.setProperties(properties);
            customDataSource.setUser(userName );
            customDataSource.setPassword(password);
    
            // The rest of the code is copied from Tomcat's DataSourceFactory.
            if (poolProperties.getDataSourceJNDI() != null && poolProperties.getDataSource() == null) {
               performJNDILookup(context, poolProperties);
            }
    
           
    
    
            return customDataSource;
        }
    
    }

之后,我根据上面的实现创建了一个jar文件,并将其放在tomcat/lib文件夹中。

我在上下文中做了以下修改。tomcat/conf文件夹中的xml文件。

<Resource name="datasource/test" auth="Container"
                    type="com.mchange.v2.c3p0.ComboPooledDataSource"
                        **factory="com.aws.rds.SecureTomcatDataSourceImpl"
                            user=""
                            password=""**
                            jdbcUrl="jdbc:mysql://localhost:3306/jacplus"
                            driverClass="com.mysql.jdbc.Driver"
                            minPoolSize="2"
                            initialPoolSize="30"
                            maxPoolSize="50"
                            idleConnectionTestPeriod="600"
                            acquireRetryAttempts="30"/>

但当我开始tomcat我得到以下例外。

thod失败;嵌套的异常是org。springframework。jdbc。数据源。查找。DataSourceLookupFailureException:无法查找名为“java:comp/env/DataSource/test”的JNDI数据源;嵌套的异常是javax。命名。NameNotFoundException:找不到[java:comp/env/datasource/test]的JNDI对象:JNDI实现在org返回null。springframework。豆。工厂支持AbstractAutowireCapableBeanFactory。在org上初始化ebean(AbstractAutowireCapableBeanFactory.java:1745)。springframework。豆。工厂支持AbstractAutowireCapableBeanFactory。org上的doCreateBean(AbstractAutowireCapableBeanFactory.java:576)。springframework。豆。工厂支持AbstractAutowireCapableBeanFactory。org上的createBean(AbstractAutowireCapableBeanFactory.java:498)。springframework。豆。工厂支持抽象工厂。org上的lambda$doGetBean$0(AbstractBeanFactory.java:320)。springframework。豆。工厂支持DefaultSingletonBeanRegistry。位于org的getSingleton(DefaultSingletonBeanRegistry.java:222)。springframework。豆。工厂支持抽象工厂。org上的doGetBean(AbstractBeanFactory.java:318)。springframework。豆。工厂支持抽象工厂。org上的getBean(AbstractBeanFactory.java:199)。springframework。上下文支持AbstractApplicationContext。位于org的getBean(AbstractApplicationContext.java:1083)。springframework。上下文支持AbstractApplicationContext。finishBeanFactoryInitialization(AbstractApplicationContext.java:853)位于org。springframework。上下文支持AbstractApplicationContext。在org上刷新(AbstractApplicationContext.java:546)。springframework。网状物上下文上下文加载器。在org上配置和刷新WebApplicationContext(ContextLoader.java:400)。springframework。网状物上下文上下文加载器。位于org的initWebApplicationContext(ContextLoader.java:291)。springframework。网状物上下文ContextLoaderListener。contextInitialized(ContextLoaderListener.java:103)位于org。阿帕奇。卡塔琳娜。果心标准上下文。listenerStart(StandardContext.java:4770)位于org。阿帕奇。卡塔琳娜。果心标准上下文。startInternal(StandardContext.java:5236)位于org。阿帕奇。卡塔琳娜。util。生命周期酶。在org上启动(LifecycleBase.java:150)。阿帕奇。卡塔琳娜。果心集装箱基地。addChildInternal(ContainerBase.java:754)位于org。阿帕奇。卡塔琳娜。果心集装箱基地。addChild(ContainerBase.java:730)位于org。阿帕奇。卡塔琳娜。果心标准主机。addChild(StandardHost.java:744)位于org。阿帕奇。卡塔琳娜。启动。主机配置。在org上部署war(HostConfig.java:980)。阿帕奇。卡塔琳娜。启动。HostConfig$DeployWar。在java上运行(HostConfig.java:1851)。util。同时发生的遗嘱执行人$runnableapter。在html" target="_blank">java上调用(Executors.java:511)。util。同时发生的未来任务。在java上运行(FutureTask.java:266)。util。同时发生的线程池执行器。java上的runWorker(ThreadPoolExecutor.java:1149)。util。同时发生的线程池执行器$Worker。在java上运行(ThreadPoolExecutor.java:624)。朗。丝线。运行(Thread.java:748)

引起:javax.naming.NameNotFoundExcema: JNDI对象与[java: comp/env/datasSource/test]未找到:JNDI实现返回null在org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:158)在org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:178)org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:96)org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup.getDataSource(JndiDataSourceLookup.java:45)

我验证了我的数据库凭据和数据库配置是正确的。

共有1个答案

费凯康
2023-03-14

您正在扩展Tomcat JDBC的ObjectFactory来创建数据源,只要type属性不是javax,它就会返回null。sql。数据源javax。sql。XADataSource组织。阿帕奇。公猫jdbc。水塘数据源,并以警告级别记录问题(参见源代码)。

如果您设置了type="javax.sql.DataSource",它应该可以工作,但是您的解决方案依赖于Tomcat JDBC和C3P0。

我宁愿检索用户名和密码,在CustomComboPoolDataSource的默认构造函数中调用setUsersetPassword,并使用通用BeanFactory在Tomcat中配置它。

 类似资料:
  • 问题内容: 我正在http://www.cafeaulait.org/javafaq.html上阅读#6.10项,然后我开始怀疑大型企业如何创建自己的JVM实现。一个人会尝试(或可行)实验性的东西吗? 问题答案: 从技术上讲,创建该新JVM所需的所有信息都是该语言和目标平台的公共规范。即使字节码解释在很大程度上相同,JVM还是需要根据其是要在台式机还是手机上运行而有所不同。 一些开始寻找信息的地方

  • 本文向大家介绍Android如何创建自定义ActionBar,包括了Android如何创建自定义ActionBar的使用技巧和注意事项,需要的朋友参考一下 当多个界面都有很多相似部分时,可以考虑创建一个功能较全的模板。而在需要时,可以通过引用模板来实现自己想要实现的功能。比如适配器 Adapter,当很多的适配器都差不多时,就可以通过打造一个通用的适配器来实现。本例中主要是如何创建自定义的 Act

  • 标题说明了一切。我想创建一个自定义的prestashop页面,但我不知道如何创建。我真正想做的是:创建一个按钮,打开一个自定义页面。我在网上找不到任何有用的东西,所以我来这里寻求帮助。有人能告诉我怎么做吗?

  • 问题内容: 如何创建自定义javadoc标记,例如@pre / @post?我找到了一些解释它的链接,但是我还没有运气。这些是一些链接: http://www.developer.com/java/other/article.php/3085991/Javadoc- Programming.html http://java.sun.com/j2se/1.5.0/docs/tooldocs/wind

  • 我试图使用OpenNLPJavaAPI从文档中提取名称、技能等实体。但它没有提取正确的名称。我使用opennlp源锻造链接上可用的模型 下面是一段java代码- 我想做的是: 我正在使用ApacheTika将PDF文档转换为纯文本文档 但它正在提取姓名和其他单词。它不是提取专有名称。如何创建自定义模型,从文档中提取游泳、编程等技能? 给我一些想法! 任何帮助都将不胜感激!?

  • 基本上,我想知道我是否可以创建一个树并在JavaFX上自定义它...我试着去做,但到目前为止还不能用这个代码做任何事情... 我在质疑自己,这是否是正确的“技术”,可以解决我想做的事情... 我从https://docs.oracle.com/javafx/2/ui_controls/tree-view.htm#babjgggf看到了这个教程,但我对这个教程真的很困惑...我不太了解细胞工厂的机制