【问题标题】:How to deploy a JDBC Driver to Wildfly that can be used by WebApp如何将 JDBC 驱动程序部署到 WebApp 可以使用的 Wildfly
【发布时间】:2017-11-29 00:40:20
【问题描述】:

我们目前正在从 Tomcat 迁移到 Wildfly 10 服务器。我们喜欢利用 Java EE 服务器。目前我们在数据源方面存在一些问题。我们已经在 Wildfly 上部署了 JDBC 驱动程序并设置了数据源。 这很有效,但我们喜欢使用 DatabaseQueryNotification (Oracle) 来处理数据库端事件。

现在我遇到的问题:

当我将驱动程序与我的 war(另外)打包时,由于 T4Connection 和 OracleConnection 不匹配,我得到了 ClassCastException。因此,我从我的 War (maven -> scope: provided) 中删除了 JDBC-Driver。但是现在我的应用程序在部署时失败了,因为 NoClassDefFound(请参阅下面的 Stacktrace)。

如何确保应用程序可以找到 JDBC 驱动程序?

Java 代码段:

public class DBListener implements IDBListener, Runnable, DatabaseChangeListener, IPropertyListener, Serializable {  
     @Resource(lookup = "java:/PlsDS")  
     private DataSource dataSource;  
     ...  
     public void connectToDB(){
       Connection tmpCon = dataSource.getConnection();  
       connection = (OracleConnection) tmpCon.getMetaData().getConnection();  
       ...
     }
}

堆栈跟踪:

14:32:59,869 WARN  [org.jboss.modules] (MSC service thread 1-7) Failed to define class de.istec.pls.client.db.listener.DBListener in Module "deployment.client.pls-sc-1.0.0-SNAPSHOT.war:main" from Service Module Loader: java.lang.NoClassDefFoundError: Failed to link de/istec/pls/client/db/listener/DBListener (Module "deployment.client.pls-sc-1.0.0-SNAPSHOT.war:main" from Service Module Loader): oracle/jdbc/dcn/DatabaseChangeListener
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at org.jboss.modules.ModuleClassLoader.defineClass(ModuleClassLoader.java:446)
    at org.jboss.modules.ModuleClassLoader.loadClassLocal(ModuleClassLoader.java:274)
    at org.jboss.modules.ModuleClassLoader$1.loadClassLocal(ModuleClassLoader.java:78)
    at org.jboss.modules.Module.loadModuleClass(Module.java:606)
    at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:190)
    at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:363)
    at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:351)
    at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:93)
    at org.wildfly.extension.undertow.deployment.ServletContainerInitializerDeploymentProcessor.loadClassInfoSet(ServletContainerInitializerDeploymentProcessor.java:259)
    at org.wildfly.extension.undertow.deployment.ServletContainerInitializerDeploymentProcessor.deploy(ServletContainerInitializerDeploymentProcessor.java:169)
    at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:147)
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948)
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

14:32:59,871 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-7) MSC000001: Failed to start service jboss.deployment.unit."client.pls-sc-1.0.0-SNAPSHOT.war".INSTALL: org.jboss.msc.service.StartException in service jboss.deployment.unit."client.pls-sc-1.0.0-SNAPSHOT.war".INSTALL: WFLYSRV0153: Failed to process phase INSTALL of deployment "client.pls-sc-1.0.0-SNAPSHOT.war"
    at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:154)
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948)
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

Caused by: java.lang.NoClassDefFoundError: Failed to link de/istec/pls/client/db/listener/DBListener (Module "deployment.client.pls-sc-1.0.0-SNAPSHOT.war:main" from Service Module Loader): oracle/jdbc/dcn/DatabaseChangeListener
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at org.jboss.modules.ModuleClassLoader.defineClass(ModuleClassLoader.java:446)
    at org.jboss.modules.ModuleClassLoader.loadClassLocal(ModuleClassLoader.java:274)
    at org.jboss.modules.ModuleClassLoader$1.loadClassLocal(ModuleClassLoader.java:78)
    at org.jboss.modules.Module.loadModuleClass(Module.java:606)
    at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:190)
    at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:363)
    at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:351)
    at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:93)
    at org.wildfly.extension.undertow.deployment.ServletContainerInitializerDeploymentProcessor.loadClassInfoSet(ServletContainerInitializerDeploymentProcessor.java:259)
    at org.wildfly.extension.undertow.deployment.ServletContainerInitializerDeploymentProcessor.deploy(ServletContainerInitializerDeploymentProcessor.java:169)
    at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:147)

【问题讨论】:

  • 您绝对不想将驱动程序打包到您的 WAR 中。您是否为驱动程序添加了模块或部署了 JAR?您可能希望根据自己的情况为其创建一个模块。
  • 我刚刚通过管理控制台部署了 JAR。
  • 通过管理控制台部署的 JAR 文件将可用于配置文件中定义的数据源。如果你想让 JDBC 驱动程序类对 webapp 可用,那么你必须在 Webapp 类路径中创建模块或添加 JDBC 驱动程序 jar

标签: jdbc wildfly wildfly-10


【解决方案1】:

我已经解决了问题:

  1. 我必须将 JDBC 驱动程序部署为模块(请参阅: http://hpehl.info/jdbc-driver-setup.html)
  2. 我必须从模块中导出所需的 oracle.jdbc.dcn* 文件
  3. 在 Manifest.MF 文件中插入依赖项。 (可以由 Maven 完成,见下文)

module.xml

<module xmlns="urn:jboss:module:1.1" name="com.oracle">
  <resources>
    <resource-root path="ojdbc7-12.1.0.2.jar"/>
  </resources>
  <dependencies>
    <system export="true">
        <paths>
            <path name="oracle/jdbc/OracleStatement"/>
            <path name="oracle/jdbc/dcn/DatabaseChangeEvent"/>
            <path name="oracle/jdbc/dcn/DatabaseChangeListener"/>
            <path name="oracle/jdbc/dcn/DatabaseChangeRegistration"/>
            <path name="oracle/jdbc/dcn/QueryChangeDescription"/>
            <path name="oracle/jdbc/dcn/RowChangeDescription"/>
        </paths>
    </system>
    <module name="javax.api"/>
    <module name="javax.transaction.api"/>
  </dependencies>
</module>

pom.xml

<plugin>
    <artifactId>maven-war-plugin</artifactId>
    <version>3.1.0</version>
    <configuration>
        <archive>
          <manifestEntries>
             <Dependencies>com.oracle</Dependencies>
          </manifestEntries>
        </archive>
    </configuration>
</plugin>

【讨论】:

    【解决方案2】:

    您应该通过 JNDI 获取数据源的实例或通过 CDI 注入。

    【讨论】:

    • 我通过 JNDI 获取数据源,这不是问题。错误说它找不到我用 Class 实现的 oracle/jdbc/dcn/DatabaseChangeListener。
    • Irrc 你得到的连接是一个 org.jboss.jca.adapters.jdbc.WrappedConnection ,你需要从中获得“真正的”连接
    • 连接不是我的问题。应用程序当前在部署时失败,因为它找不到 JDBC 实现,尤其是 DatabaseChangeListener (oracle.jdbc.dcn.DatabaseChangeListene)。我需要导入几个 orcacle.jndi.dcn.* 类,但需要从服务器接收驱动程序(jdbc7.jar)。
    • 您在为驱动程序创建模块时是否导出(使用 module.xml 中的导出标签)这些包?否则这些不可用
    • 这是缺少的提示。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-23
    • 2011-07-15
    • 2015-04-02
    • 2011-11-25
    • 2018-07-11
    • 1970-01-01
    相关资源
    最近更新 更多