issues|August 10, 2019|2 min read

Solving Jboss Wildfly Oracle JDBC driver problem, with Dockerfile

TL;DR

Configure the Oracle JDBC driver as a module in JBoss Wildfly by adding the module.xml and ojdbc jar to the modules directory, and register the driver in standalone.xml.

Solving Jboss Wildfly Oracle JDBC driver problem, with Dockerfile

Assuming your web application is using oracle, and you are deploying your app on Jboss wildfly. If you run on fresh download of wildfly or docker image of jboss/wildfly, you will get following error:

ERROR [org.jboss.msc.service.fail] (MSC service thread 1-6) MSC000001: Failed to start service
.
.
.
10:15:56,901 ERROR [org.jboss.as.controller.management-operation] (Controller Boot Thread) WFLYCTL0013: Operation ("add") failed - address: ([
    ("subsystem" => "datasources"),
    ("data-source" => "oracle")
]) - failure description: {
    "WFLYCTL0412: Required services that are not installed:" => ["jboss.jdbc-driver.OracleJDBCDriver"],
    "WFLYCTL0180: Services with missing/unavailable dependencies" => [
        "org.wildfly.data-source.oracle is missing [jboss.jdbc-driver.OracleJDBCDriver]",
        "jboss.driver-demander.java:/oracle is missing [jboss.jdbc-driver.OracleJDBCDriver]"
    ]
}
10:15:56,903 ERROR [org.jboss.as.controller.management-operation] (Controller Boot Thread) WFLYCTL0013: Operation ("add") failed - address: ([
    ("subsystem" => "datasources"),
    ("data-source" => "oracle")
]) - failure description: {
    "WFLYCTL0412: Required services that are not installed:" => [
        "jboss.jdbc-driver.OracleJDBCDriver",
        "jboss.jdbc-driver.OracleJDBCDriver"
    ],
    "WFLYCTL0180: Services with missing/unavailable dependencies" => [
        "org.wildfly.data-source.oracle is missing [jboss.jdbc-driver.OracleJDBCDriver]",
        "jboss.driver-demander.java:/oracle is missing [jboss.jdbc-driver.OracleJDBCDriver]",
        "org.wildfly.data-source.oracle is missing [jboss.jdbc-driver.OracleJDBCDriver]"
    ]
}

Solution to Oracle jdbc driver issue

  • First you need to download jdbc driver from oracle website.
  • Download ojdbc7.jar
  • Now, you need to make this as module in Jboss wildfly so that it can load this as module.
  • Assumming your wildfly path is in variable: $WILDFLY_HOME
  • Copy ojdbc to directory: $WILDFLY_HOME/modules/system/layers/base/com/oracle/main
    • NOTE: You need to create few directories under modules/system/layers/base directory
  • Create a file in that folder named: module.xml, and put following content:
<?xml version="1.0" encoding="UTF-8"?>
    
<module name="com.oracle" xmlns="urn:jboss:module:1.1">
    <resources>
        <resource-root path="ojdbc7.jar"/>
    </resources>
    <dependencies>
        <module name="javax.api"/>
        <module name="javax.transaction.api"/>
    </dependencies>
</module>
  • Open $WILDFLY_HOME/standalone/configuration/standalone.xml file
  • Put following:
    • Look for more subsystem tags, to see where this block of xml will go.
    • Also be careful, not to duplicate this block. If another block exist with same xmlns, remove it.
<subsystem xmlns="urn:jboss:domain:datasources:5.0">
    <datasources>
        <datasource jndi-name="java:/oracle-ds" pool-name="oracle-ds" enabled="true">
            <connection-url>jdbc:oracle:thin:@HOSTNAME:PORT/DATABASE</connection-url>
            <driver>OracleJDBCDriver</driver>
            <pool>
                <min-pool-size>5</min-pool-size>
                <max-pool-size>100</max-pool-size>
                <prefill>true</prefill>
                <flush-strategy>IdleConnections</flush-strategy>
            </pool>
            <security>
                <user-name>USERNAME</user-name>
                <password>PASSWORD</password>
            </security>
            <validation>
                <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleValidConnectionChecker"/>
                <check-valid-connection-sql>select 1 from dual</check-valid-connection-sql>
                <background-validation>true</background-validation>
                <stale-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleStaleConnectionChecker"/>
                <exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleExceptionSorter"/>
            </validation>
            <timeout>
                <blocking-timeout-millis>5000</blocking-timeout-millis>
                <idle-timeout-minutes>5</idle-timeout-minutes>
            </timeout>
        </datasource>
        <drivers>
            <driver name="OracleJDBCDriver" module="com.oracle">
                <driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
                <xa-datasource-class>oracle.jdbc.xa.client.OracleXADataSource</xa-datasource-class>
            </driver>
        </drivers>
    </datasources>
</subsystem>
  • Restart your wildfly.

Solution using Docker

If you are using wildfly docker image, you might require following Dockerfile

FROM jboss/wildfly

COPY ojdbc7.jar /opt/jboss/wildfly/modules/system/layers/base/com/oracle/main/
COPY module.xml /opt/jboss/wildfly/modules/system/layers/base/com/oracle/main/

#Copying required scripts and files
COPY standalone.xml /opt/jboss/wildfly/standalone/configuration/
COPY <WEBAPP>.war /opt/jboss/wildfly/standalone/deployments/

Note: In above file, module.xml is file having following content:

<?xml version="1.0" encoding="UTF-8"?>
    
<module name="com.oracle" xmlns="urn:jboss:module:1.1">
    <resources>
        <resource-root path="ojdbc7.jar"/>
    </resources>
    <dependencies>
        <module name="javax.api"/>
        <module name="javax.transaction.api"/>
    </dependencies>
</module>
  • standalone.xml file is copied from the container itself. To take this, use following method;
docker run -it -d jboss/wildfly

# get its container id
docker ps

# Copy standaline.xml file to current path
docker cp <container-id>/opt/jboss/wildfly/standalone/configuration/standalone.xml .

Final solution for docker

Now, we just need to build another image from our Dockerfile

docker build -t MY_IMAGE_NAME .

# To run it,
docker run -it -d MY_IMAGE_NAME

Hope you get your problem resolved.

Related Posts

Python SMTP Email Code - Sender Address Rejected - Not Owned By User

Python SMTP Email Code - Sender Address Rejected - Not Owned By User

Introduction In a normal email sending code from python, I’m getting following…

How to Fix Drupal Mysql error - Communication link failure: 1153 Got a packet bigger than 'max_allowed_packet' bytes

How to Fix Drupal Mysql error - Communication link failure: 1153 Got a packet bigger than 'max_allowed_packet' bytes

Introduction While this topic may applicable to all mysql/mariadb users who…

React JS router not working on Nginx docker container

React JS router not working on Nginx docker container

Problem Statement I developed a simple ReactJS application where I have used…

Mac showing strange incorrect month name

Mac showing strange incorrect month name

Introduction to problem So, on my mac, I’ev set timezone to my local city i.e…

How to solve - Apache Ftp Client library is printing password on console

How to solve - Apache Ftp Client library is printing password on console

The problem comes while using FTPS. When developer uses login method of this…

php55w-common conflicts with php-common-5.* | Php issues while installing libraries

php55w-common conflicts with php-common-5.* | Php issues while installing libraries

I was trying to install mongo extension with pecl. It gave me error: Then, I…

Latest Posts

Claude Code Skills — Build a Better Engineering Workflow with AI-Powered Code Reviews, Security Scans, and More

Claude Code Skills — Build a Better Engineering Workflow with AI-Powered Code Reviews, Security Scans, and More

Most developers use Claude Code like a search engine — ask a question, get an…

Building an AI Voicebot for Visitor Check-In — A Practical Guide to Handling the Messy Parts

Building an AI Voicebot for Visitor Check-In — A Practical Guide to Handling the Messy Parts

Every office lobby has the same problem: a visitor walks in, nobody’s at the…

Server Security Best Practices — Complete Hardening Guide for Production Systems

Server Security Best Practices — Complete Hardening Guide for Production Systems

Every breach post-mortem tells the same story: an unpatched service, a…

Staff Engineer Study Plan for MAANG Interviews — The Complete 12-Week Roadmap

Staff Engineer Study Plan for MAANG Interviews — The Complete 12-Week Roadmap

If you’re a Senior Engineer (L5) preparing for Staff (L6+) roles at MAANG…

XSS and CSRF Explained — The Complete Guide with Real Attack Examples and Defenses

XSS and CSRF Explained — The Complete Guide with Real Attack Examples and Defenses

XSS and CSRF have been in the OWASP Top 10 for over a decade. They’re among the…

OWASP Top 10 (2021) — Every Vulnerability Explained with Code

OWASP Top 10 (2021) — Every Vulnerability Explained with Code

The OWASP Top 10 is the industry standard for web application security risks. If…