Deploy a WAR on JBoss EAP 7.1 Standalone with an Oracle 19c Datasource



DBAs are often the ones called when an application "cannot connect to the database" after a deployment, and very often the problem sits in the application server's datasource, not in the database. Knowing how the middleware side is set up makes those calls much shorter.

In this guide I deploy a sample web application (WAR) on JBoss EAP 7.1 in standalone mode on Linux, connected to an Oracle 19c database. Everything is done from the command line with jboss-cli.sh, so it is repeatable and easy to script.

Environment

ComponentVersion / value
Application serverJBoss EAP 7.1 (standalone mode) on RHEL / Oracle Linux
JavaJDK 8 (OpenJDK 1.8 or Oracle JDK 8)
DatabaseOracle Database 19c, service ORCLPDB1
JDBC driverojdbc8.jar (from the 19c Oracle Home)
Applicationsample-app.war, datasource JNDI java:/jdbc/SampleDS

Before you start

  • JBoss EAP 7.1 is unzipped on the server. In this post JBOSS_HOME=/opt/jboss-eap-7.1.
  • JDK 8 is installed.
  • The application schema exists in the database, and you have its user name and password.
  • Port 1521 is open from the app server to the database server. Test it with nc -zv dbhost 1521.
  • You can copy files to the server (WinSCP or scp) and log in to it (PuTTY or ssh).

The steps

Prepare Database Deploy Operate

1
Prepare

Verify Java and JBoss

Log in to the application server over SSH (PuTTY on Windows works fine) and confirm both are present.

java -version
echo $JAVA_HOME

export JBOSS_HOME=/opt/jboss-eap-7.1
ls $JBOSS_HOME
$JBOSS_HOME/bin/standalone.sh --version

JBoss EAP 7.1 is supported on Java 8. Make sure java -version reports 1.8.

2
Prepare

Set JAVA_HOME for JBoss

Instead of editing a custom start script, set Java in JBoss's own configuration file, $JBOSS_HOME/bin/standalone.conf. Every start method then picks it up.

# $JBOSS_HOME/bin/standalone.conf
JAVA_HOME="/usr/lib/jvm/java-1.8.0-openjdk"

# Heap size (adjust to your server)
JAVA_OPTS="-Xms1g -Xmx2g -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m"
3
Prepare

Create a management user

You need it for the admin console (port 9990) and for jboss-cli.sh from a remote host.

$JBOSS_HOME/bin/add-user.sh -u jbadmin -p 'Str0ng#Pass' -g admin
4
Prepare

Start the server

Start in the background, binding to the server's IP so other machines can reach it:

cd $JBOSS_HOME/bin
nohup ./standalone.sh -b 0.0.0.0 -bmanagement 0.0.0.0 > /dev/null 2>&1 &

# Watch the startup
tail -f $JBOSS_HOME/standalone/log/server.log
Look for this line
WFLYSRV0025: JBoss EAP 7.1.x.GA (WildFly Core ...) started in 6512ms
Ports: HTTP listens on 8080 and management on 9990 by default. To run several instances on one box, shift all ports together with -Djboss.socket.binding.port-offset=100 (8080 → 8180, and so on).
5
Database

Install the Oracle JDBC driver as a module

For Oracle 19c with Java 8 use ojdbc8.jar. It ships with the database in $ORACLE_HOME/jdbc/lib, or you can download it from Oracle. Copy it to the app server, then register it as a JBoss module, the supported way to add a driver.

jboss-cli
scp oracle@dbhost:/u01/app/oracle/product/19.0.0/dbhome_1/jdbc/lib/ojdbc8.jar /tmp/

$JBOSS_HOME/bin/jboss-cli.sh --connect

module add --name=com.oracle --resources=/tmp/ojdbc8.jar --dependencies=javax.api,javax.transaction.api

/subsystem=datasources/jdbc-driver=oracle:add(driver-name=oracle, \
    driver-module-name=com.oracle, \
    driver-xa-datasource-class-name=oracle.jdbc.xa.client.OracleXADataSource)
Why not just drop the jar in deployments/? That works for a quick test, but a module is loaded once, survives redeployments, and is the approach Red Hat documents. Also avoid ojdbc6: it is built for Java 6 and does not support the 19c driver features.
6
Database

Create the datasource

Still in jboss-cli, create a non-XA datasource. The JNDI name must match what the application looks up, so confirm it with the application team.

jboss-cli
data-source add --name=SampleDS \
    --jndi-name=java:/jdbc/SampleDS \
    --driver-name=oracle \
    --connection-url=jdbc:oracle:thin:@//dbhost:1521/ORCLPDB1 \
    --user-name=app_user --password='App#Pass' \
    --min-pool-size=5 --max-pool-size=50 \
    --valid-connection-checker-class-name=org.jboss.jca.adapters.jdbc.extensions.oracle.OracleValidConnectionChecker \
    --exception-sorter-class-name=org.jboss.jca.adapters.jdbc.extensions.oracle.OracleExceptionSorter \
    --stale-connection-checker-class-name=org.jboss.jca.adapters.jdbc.extensions.oracle.OracleStaleConnectionChecker \
    --background-validation=true --background-validation-millis=60000

/subsystem=datasources/data-source=SampleDS:test-connection-in-pool
Expected
{"outcome" => "success", "result" => [true]}

The CLI writes this into standalone/configuration/standalone.xml. It looks like this, if you prefer to compare or edit offline (stop the server before editing the file by hand):

standalone.xml
<datasource jndi-name="java:/jdbc/SampleDS" pool-name="SampleDS">
    <connection-url>jdbc:oracle:thin:@//dbhost:1521/ORCLPDB1</connection-url>
    <driver>oracle</driver>
    <pool>
        <min-pool-size>5</min-pool-size>
        <max-pool-size>50</max-pool-size>
    </pool>
    <security>
        <user-name>app_user</user-name>
        <password>App#Pass</password>
    </security>
    <validation>
        <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleValidConnectionChecker"/>
        <exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleExceptionSorter"/>
        <background-validation>true</background-validation>
    </validation>
</datasource>
Do not leave passwords in plain text in production. JBoss EAP 7.1 includes the Elytron credential store for this. At minimum, make sure only the JBoss OS user can read standalone.xml.

If the application needs a second datasource (for example a reporting schema), repeat the command with a different name, JNDI name and user.

7
Database

Add JNDI bindings (only if the app needs them)

Some applications look up EJBs or values through custom JNDI names. Get the exact list from the application team and add them under the naming subsystem:

jboss-cli
/subsystem=naming/binding=java\:global\/app\/configPath:add(binding-type=simple, value="/opt/app/config")
/subsystem=naming/binding=java\:\/ejb\/OrderService:add(binding-type=lookup, \
    lookup="java:global/sample-app/OrderServiceBean!com.example.OrderService")
8
Deploy

Copy and deploy the WAR

Copy the WAR from your machine with WinSCP, or from the command line:

From your machine
scp sample-app.war jboss@appserver:/tmp/

Then deploy it. Either of these works:

On the app server
# Option A: CLI (recommended, shows errors immediately)
$JBOSS_HOME/bin/jboss-cli.sh --connect --command="deploy /tmp/sample-app.war --force"

# Option B: deployment scanner
cp /tmp/sample-app.war $JBOSS_HOME/standalone/deployments/
ls $JBOSS_HOME/standalone/deployments/
Marker fileMeaning
sample-app.war.deployedDeployed successfully
sample-app.war.failedDeployment failed; the file contains the reason
sample-app.war.isdeployingStill in progress
sample-app.war.undeployedRemoved
Check the log
grep -E "WFLYSRV0010|WFLYUT0021|ERROR" $JBOSS_HOME/standalone/log/server.log | tail
9
Deploy

Open the application

The URL is http://<server-ip>:<http-port>/<context-root>/. The context root is the WAR name unless the application sets it in jboss-web.xml. Find the HTTP port in standalone.xml:

grep 'socket-binding name="http"' $JBOSS_HOME/standalone/configuration/standalone.xml
# <socket-binding name="http" port="${jboss.http.port:8080}"/>

curl -I http://localhost:8080/sample-app/

An HTTP 200 or 302 means the application is up. Then open the same URL in a browser from your desktop. If it does not load, check the firewall (sudo firewall-cmd --add-port=8080/tcp --permanent && sudo firewall-cmd --reload).

10
Operate

Stop the server cleanly

$JBOSS_HOME/bin/jboss-cli.sh --connect --command=":shutdown"

# with a port offset or remote server
$JBOSS_HOME/bin/jboss-cli.sh --connect --controller=appserver:10090 --command=":shutdown"

Avoid kill -9. It skips the graceful shutdown of datasource pools and in-flight requests.

Troubleshooting

SymptomLikely causeFix
WFLYCTL0412 required services not installed / missing jboss.jdbc-driver.oracleDriver module not registered, or wrong driver nameCheck /subsystem=datasources:installed-drivers-list
IO Error: The Network Adapter could not establish the connectionWrong host or port, firewall, listener downnc -zv dbhost 1521; lsnrctl status on the DB server
ORA-12514 listener does not know of serviceWrong service name in the URLUse //host:port/SERVICE, not the SID
ORA-01017 invalid username/passwordCredentials in the datasource are wrongFix with data-source --name=SampleDS --password=... and reload
.war.failed marker / WFLYCTL0080Deployment error, often a missing JNDI nameRead the .failed file and server.log; compare JNDI names with the app team
Address already in use on startupAnother process holds 8080 or 9990ss -tlnp | grep -E '8080|9990'; use a port offset

Conclusion

The order that keeps this simple: Java → management user → start → JDBC module → datasource → test the connection → deploy → verify the URL. Testing the datasource with test-connection-in-pool before deploying the WAR separates database problems from application problems, and saves a lot of time on deployment night.

Do you manage JBoss or WildFly alongside your databases? Share your tips in the comments.

Tamilselvan Perumal · Lead Product Engineer & Senior DBA