如何创建自定义 c3p0 ComboPooledDataSource 并在 tomcat context.xml 中引用

如何解决如何创建自定义 c3p0 ComboPooledDataSource 并在 tomcat context.xml 中引用

我有一个 tomcat 应用服务器,我的数据库连接是在 context.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>

而不是在 context.xml 中硬编码用户名和密码。我想将数据库凭据存储在 aws 机密管理器中,并使用从 aws 机密管理器检索到的数据库凭据创建数据源。

为此,我创建了以下自定义 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 文件夹中的 Context.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 时,我遇到了以下异常。

失败了;嵌套异常是 org.springframework.jdbc.datasource.lookup.DataSourceLookupFailureException: 无法使用名称查找 JNDI 数据源 'java:comp/env/datasource/test';嵌套异常是 javax.naming.NameNotFoundException: JNDI 对象 [java:comp/env/datasource/test] 未找到:JNDI 实现 返回空值 org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.initializeBean(AbstractAutowireCapablebeanfactory.java:1745) 在 org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.doCreateBean(AbstractAutowireCapablebeanfactory.java:576) 在 org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.createBean(AbstractAutowireCapablebeanfactory.java:498) 在 org.springframework.beans.factory.support.Abstractbeanfactory.lambda$doGetBean$0(Abstractbeanfactory.java:320) 在 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) 在 org.springframework.beans.factory.support.Abstractbeanfactory.doGetBean(Abstractbeanfactory.java:318) 在 org.springframework.beans.factory.support.Abstractbeanfactory.getBean(Abstractbeanfactory.java:199) 在 org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1083) 在 org.springframework.context.support.AbstractApplicationContext.finishbeanfactoryInitialization(AbstractApplicationContext.java:853) 在 org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546) 在 org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:400) 在 org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:291) 在 org.springframework.web.context.ContextLoaderListener.contextinitialized(ContextLoaderListener.java:103) 在 org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4770) 在 org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5236) 在 org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) 在 org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:754) 在 org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:730) 在 org.apache.catalina.core.StandardHost.addChild(StandardHost.java:744) 在 org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:980) 在 org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1851) 在 java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) 在 java.util.concurrent.FutureTask.run(FutureTask.java:266) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) 在 java.lang.Thread.run(Thread.java:748)

Caused by: javax.naming.NameNotFoundException: JNDI object with [java:comp/env/datasource/test] 未找到:JNDI 实现 返回空值 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)

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

解决方法

您正在扩展 Tomcat JDBCObjectFactory 以创建您的数据源,只要类型属性不是 nulljavax.sql.DataSource 或 {{ 1}} 并将问题记录到警告级别(参见source code)。

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

我宁愿检索用户名和密码,并在 org.apache.tomcat.jdbc.pool.DataSource 的默认构造函数中调用 setUsersetPassword,并使用泛型 type="javax.sql.DataSource" 在 Tomcat 中对其进行配置。>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?