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
| Component | Version / value |
|---|---|
| Application server | JBoss EAP 7.1 (standalone mode) on RHEL / Oracle Linux |
| Java | JDK 8 (OpenJDK 1.8 or Oracle JDK 8) |
| Database | Oracle Database 19c, service ORCLPDB1 |
| JDBC driver | ojdbc8.jar (from the 19c Oracle Home) |
| Application | sample-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
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.
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"
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
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
WFLYSRV0025: JBoss EAP 7.1.x.GA (WildFly Core ...) started in 6512ms
-Djboss.socket.binding.port-offset=100 (8080 → 8180, and so on).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.
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)
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.
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
{"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):
<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>
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.
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:
/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")
Copy and deploy the WAR
Copy the WAR from your machine with WinSCP, or from the command line:
scp sample-app.war jboss@appserver:/tmp/
Then deploy it. Either of these works:
# 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 file | Meaning |
|---|---|
sample-app.war.deployed | Deployed successfully |
sample-app.war.failed | Deployment failed; the file contains the reason |
sample-app.war.isdeploying | Still in progress |
sample-app.war.undeployed | Removed |
grep -E "WFLYSRV0010|WFLYUT0021|ERROR" $JBOSS_HOME/standalone/log/server.log | tail
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).
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
| Symptom | Likely cause | Fix |
|---|---|---|
WFLYCTL0412 required services not installed / missing jboss.jdbc-driver.oracle | Driver module not registered, or wrong driver name | Check /subsystem=datasources:installed-drivers-list |
| IO Error: The Network Adapter could not establish the connection | Wrong host or port, firewall, listener down | nc -zv dbhost 1521; lsnrctl status on the DB server |
| ORA-12514 listener does not know of service | Wrong service name in the URL | Use //host:port/SERVICE, not the SID |
| ORA-01017 invalid username/password | Credentials in the datasource are wrong | Fix with data-source --name=SampleDS --password=... and reload |
| .war.failed marker / WFLYCTL0080 | Deployment error, often a missing JNDI name | Read the .failed file and server.log; compare JNDI names with the app team |
| Address already in use on startup | Another process holds 8080 or 9990 | ss -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
