【问题标题】:Can't find valid JDBC driver when deploying Liberty app in Bluemix with ElephantSQL使用 ElephantSQL 在 Bluemix 中部署 Liberty 应用程序时找不到有效的 JDBC 驱动程序
【发布时间】:2016-09-07 12:53:00
【问题描述】:

我有一个 WebSphere Liberty 16.0.0.2 web 应用程序,我使用 JPA 使用 Derby DB 在我的笔记本电脑上开发并在本地运行它来处理数据库。我曾经使用 SQLDB(2016 年 5 月被 IBM 淘汰)将它部署到 Bluemix 中,并且在服务的自动连接中一切正常。由于 SQLDB 不再可用,我能够在 Bluemix 上找到的唯一免费 SQL 是 ElephantSQL,但是自动装配似乎不起作用。这是我在部署后得到的错误:

Program error occured: CWWJP0013E: The server cannot locate the java:comp/env/jdbc/TriReplicatorDB data source for the TriReplicatorPersistenceUnit persistence unit because it has encountered the following exception: javax.naming.NamingException: CWNEN1001E: The object referenced by the java:comp/env/jdbc/TriReplicatorDB JNDI name could not be instantiated. If the reference name maps to a JNDI name in the deployment descriptor bindings for the application performing the JNDI lookup, make sure that the JNDI name mapping in the deployment descriptor binding is correct. If the JNDI name mapping is correct, make sure the target resource can be resolved with the specified name relative to the default initial context. [Root exception is com.ibm.wsspi.injectionengine.InjectionException: CWNEN0030E: The server was unable to obtain an object instance for the java:comp/env/jdbc/TriReplicatorDB reference. The exception message was: CWNEN1006E: The server was unable to obtain an object for the jdbc/TriReplicatorDB binding with the javax.sql.DataSource type. The exception message was: java.sql.SQLNonTransientException: DSRA4000E: A valid JDBC driver implementation class was not found for the jdbcDriver jdbcDriver[myDerbyJDBCdriver] using the library com.ibm.ws.classloading.sharedlibrary_79. [/home/vcap/app/wlp/usr/servers/triServer/lib/postgresql-jdbc-9.4.1209.jar]]. 

我上传网络应用的方式是打包服务器并使用cf push 命令。这是生成的 server.xml 文件:

<server description="new server">
<!-- Enable features -->
<featureManager>
    <feature>jsp-2.3</feature>
    <feature>concurrent-1.0</feature>
    <feature>jaxrs-2.0</feature>
    <feature>jaxrsClient-2.0</feature>
    <feature>jpa-2.1</feature>
    <feature>appSecurity-2.0</feature>
    <feature>localConnector-1.0</feature>
    <feature>icap:managementConnector-1.0</feature>
    <feature>appstate-1.0</feature>
    <feature>jdbc-4.1</feature>
    <feature>cloudAutowiring-1.0</feature>
</featureManager>
<httpEndpoint httpPort="${port}" id="defaultHttpEndpoint" host="*"/>
<webContainer deferServletLoad="false" trustHostHeaderPort="true" extractHostHeaderPort="true"/>
<applicationMonitor updateTrigger="mbean"/>
<!-- This is the application itself -->
<webApplication contextRoot="/" id="Tri-Replicator" location="Tri-Replicator.war" name="Tri-Replicator">
</webApplication>
<jdbcDriver id="myDerbyJDBCdriver">
    <library name="DerbyLib">
        <fileset dir="C:\projects_c\Tri-Replicator-16\db\db-derby-10.11.1.1-bin\lib" includes="derby.jar"/>
        <fileset dir='${server.config.dir}/lib' includes='postgresql-jdbc-9.4.1209.jar'/>
    </library>
</jdbcDriver>
<!-- Use local Derby DB for local testing on laptop, but when deployed into BlueMix this will automatically be rewired to use SQL DB instance -->
<dataSource id="DerbyConnection" jdbcDriverRef="myDerbyJDBCdriver" jndiName="jdbc/TriReplicatorDB">
    <properties createDatabase="create" databaseName="${cloud.services.ElephantSQL-tri-replicator.connection.name}" user="${cloud.services.ElephantSQL-tri-replicator.connection.user}" password="${cloud.services.ElephantSQL-tri-replicator.connection.password}" serverName="${cloud.services.ElephantSQL-tri-replicator.connection.host}" portNumber="${cloud.services.ElephantSQL-tri-replicator.connection.port}"/>
</dataSource>
<include location='runtime-vars.xml'/>
<httpDispatcher enableWelcomePage='false'/>
<config updateTrigger='mbean'/>
<appstate appName='Tri-Replicator' markerPath='${home}/../.liberty.state'/>

作为替代问题 - 任何人都可以建议其他小型免费计划用于 Bluemix 中的 SQL 数据库吗? PostgreSQL 和 DB2 不提供免费计划。

【问题讨论】:

标签: java postgresql jdbc ibm-cloud websphere-liberty


【解决方案1】:

要使用 PostgreSQL(ElephantSQL 使用的 JDBC 驱动程序),您需要在 &lt;jdbcDriver&gt; 元素上指定数据源实现类名称:

<jdbcDriver id="myDerbyJDBCdriver" javax.sql.DataSource="org.postgresql.ds.PGPoolingDataSource">
  <!-- keep nested stuff the same -->
</jdbcDriver>

您需要为 PostgreSQL 而不是为 Derby 指定 DataSource impl 类的原因是因为 Derby 是 Liberty 的“已知”数据库,而不是 PostgreSQL。

我会让 Liberty 开发人员知道这一点,以便将来某个时候可以将 PostgreSQL 添加为“已知”数据库。

【讨论】:

    【解决方案2】:

    报告的异常说明如下:

    A valid JDBC driver implementation class was not found 
    for the jdbcDriver jdbcDriver[myDerbyJDBCdriver]
    

    此异常表示无法在postgresql-jdbc-9.4.1209.jar 中找到连接池数据源类。

    WLP 按设计工作,需要在 server.xml 中进行额外配置,因为 WLP 只能定位特定数量的已知数据库的实现类[1]。我查看了postgresql-jdbc-9.4.1209.jar驱动,发现实现类如下:

    org.postgresql.ds.PGPoolingDataSource
    

    您应该使用以下内容更新 server.xml 文件:

    javax.sql.DataSource="org.postgresql.ds.PGPoolingDataSource"
    

    [1]https://www.ibm.com/support/knowledgecenter/was_beta_liberty/com.ibm.websphere.wlp.nd.multiplatform.doc/ae/twlp_dep_configuring_ds.html

    【讨论】:

    • org.postgresql.ds.PGPoolingDataSource 没有实现javax.sql.XADataSource,所以我不建议将XADataSource 实现设置为没有实现XADataSource 的类。也可以使用其他属性,例如 javax.sql.DataSourcejavax.sql.ConnectionPoolDataSource
    • 这是非常正确的,这是我的一个错误。 PostgreSQL 驱动程序没有 XA DataSource 类。我已经更新了答案以反映变化。谢谢阿吉伯特!
    • 感谢您的快速响应 - 它现在可以正常工作,但现在我必须在将应用程序推送到 Bluemix 之前手动更改 server.xml,因为我的本地 Derby 数据库 JDBC 驱动程序无法正确加载这个指向 Postgres JDBC 驱动程序的额外指针:&lt;jdbcDriver id="derbyJDBCdriver" javax.sql.ConnectionPoolDataSource="org.postgresql.ds.PGPoolingDataSource"&gt; ... 至于 JPA 代码 - 我现在正在修复数据库访问问题,因为我的代码与 Derby 和 DB2 一起工作不再与 Postgres 一起工作,但这是另一个主题...
    • 原来在 jar 文件 postgresql-jdbc-9.4.1209.jar 中有一个 XA 驱动程序,它被 Bluemix 自动添加到应用程序部署中,所以这是我现在使用的:@987654333 @ 。此驱动程序在此处描述:jdbc.postgresql.org/development/privateapi/org/postgresql/xa/…
    • 我在之前的评论中提到,使用 XA 驱动程序可以连接到数据库,但是从未创建表。根据您之前的建议,我使用非 XA 驱动程序修复了它:&lt;jdbcDriver id="JDBCdriver" javax.sql.ConnectionPoolDataSource='org.postgresql.ds.PGConnectionPoolDataSource'&gt; &lt;library name="PostgresJDBC"&gt; &lt;fileset dir='...' includes='...' /&gt; &lt;/library&gt; &lt;/jdbcDriver&gt; &lt;dataSource jdbcDriverRef="JDBCdriver" jndiName="jdbc/TriReplicatorDB" transactional='false' type='javax.sql.ConnectionPoolDataSource'&gt; &lt;properties ... /&gt; &lt;/dataSource&gt;
    猜你喜欢
    • 1970-01-01
    • 2012-04-21
    • 2016-11-02
    • 1970-01-01
    • 1970-01-01
    • 2018-02-10
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多