代码之家  ›  专栏  ›  技术社区  ›  Chad Van De Hey

Java Spring Tomcat:被忽略的自定义数据源工厂

  •  0
  • Chad Van De Hey  · 技术社区  · 6 年前

    我正在处理一个项目,该项目要求在运行时解析数据库密码。我通过指定一个 DataSourceFactory 在Tomcat配置中。此过程防止任何凭证存储在纯文本配置文件中,并为我们提供自定义控件以在运行时解析密码。我在本地取得了很大的成功,但是当我将解决方案移动到AWS上的真实/非嵌入式Tomcat实例时,我看到了以下错误:

    无法在命名工厂上调用静态NewInstance方法 类“org.apache.openjpa.jdbc.kernel.jdbbrokerFactory”。

    首先,在这个错误消息周围有一些可疑的细节。第一个(如您将在下面看到的那样),我的工厂类在tomcat配置文件中被忽略,尽管其他凭证是有效的(例如用户名、密码等)。

    我的密码 数据源工厂 需要引用类来解析值。 下面是我为Tomcat提供的XML配置:

    <?xml version='1.0' encoding='UTF-8'?>
    <Context useHttpOnly="false">
        <Resource auth="Container" name="mail/Session" type="javax.mail.Session"/>
    
        <Resource name="jdbc/jndi"
            auth="Container"
            scope="Shareable"
            type="javax.sql.DataSource"
            useLocalSessionState="true"
            cacheServerConfiguration="true"
            useServerPrepStmts="true"
            cachePrepStmts="true"
            cacheCallableStmts="true"
            elideSetAutoCommits="true"
            alwaysSendSetIsolation="false"
            enableQueryTimeouts="false"
            prepStmtCacheSize="250"
            prepStmtCacheSqlLimit="2048"
            maxActive="100"
            maxIdle="20"
            maxWait="10000"
            removeAbandoned="true"
            driverClassName="com.mysql.jdbc.Driver"
            url="${myURL}"
            username="${myUsername}"
            password="${myPasswordToResolve}"
            factory="my.class.CustomDatabaseConfigurationFactory"
            testOnBorrow="true"
            testWhileIdle="true"
            timeBetweenEvictionRunsMillis="20000"
            poolPreparedStatements="true"
            maxOpenPreparedStatements="50"
            validationQuery="select 1"
            validationInterval="60000"
            defaultTransactionIsolation="READ_COMMITTED"
        />
    
        <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
    
        <Loader loaderClass="org.apache.catalina.loader.ParallelWebappClassLoader" />
    
        <Resource auth="Container"
            name="jms/JMSConnectionFactory"
            type="org.apache.activemq.pool.PooledConnectionFactory"
            description="JMS Connection Factory"
            factory="org.apache.activemq.jndi.JNDIReferenceFactory"
            brokerURL="my.URL"
            maxConnections="100"
            maximumActiveSessionPerConnection="50"
            expiryTimeout="10000"
        />
    </Context>
    

    我不会添加我的代码 my.class.CustomDatabaseConfigurationFactory 因为我知道它在本地工作。出于某种原因,当我使用远程配置和设置启动这个时,Tomcat完全忽略了我为JNDI资源设置的自定义工厂。有什么我必须添加,以迫使Tomcat寻找我的定制工厂,而不是忽视它?我在本地的嵌入式Tomcat实例上使用了几乎相同的配置。除此之外,我在日志中没有看到任何与错误配置的文件相关的线索。

    以下是完整的堆栈跟踪:

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [spring/dataaccess/openjpa/openjpa.xml]: Invocation of ini\
    t method failed; nested exception is <openjpa-2.4.0-ep2.1-runknown fatal user error> org.apache.openjpa.persistence.ArgumentException: Could not invoke the static newInstance method on the named fact\
    ory class "org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory".
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1514)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
            at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)
            at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
            at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)
            at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191)
            at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1119)
            at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:924)
            at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
            at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:410)
            at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
            at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
            at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:5118)
            at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5634)
            at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
            at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:899)
            at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:875)
            at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:652)
            at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:679)
            at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1966)
            at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
            at java.util.concurrent.FutureTask.run(FutureTask.java:266)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java)
            at java.lang.Thread.run(Thread.java:748)
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   Chad Van De Hey    6 年前

    实际上,当自定义数据工厂正在解决正确的密码时,不应该出现此问题。

    对于其他有此问题的人来说:

    除此之外,我在日志中没有看到任何与 配置错误的文件。

    这是一个死赠品,一些东西没有被加载或没有正确设置伐木工人。当我意识到log4j配置不正确后,我可以看到我的工厂实际上正在加载。稍后,在看到结果之后,我能够看到为数据库设置的密码是不正确的。

    虽然日志错误的级别太高,而且没有足够的详细信息,但是这个问题可以通过基本的调试方法来解决,并且可以通过注意日志来避免。