I am working on a to-do list using a Java server and Postgres DB – specifically trying to set up a local dev environment using Docker Compose. The server has previously been deployed to Heroku and the database connection works without trouble. I am getting a suitable driver not found error
when attempting to establish a connection between the server and DB in Docker.
The Java DB connection code:
public void connectToDatabase() {
try {
String url = System.getenv("JDBC_DATABASE_URL");
conn = DriverManager.getConnection(url);
System.out.println("Database Connection Successful");
} catch (Exception e) {
e.printStackTrace();
}
}
The Java Server Dockerfile:
FROM gradle:7.4-jdk17-alpine
ADD --chown=gradle . /code
WORKDIR /code
EXPOSE 5000
CMD ["gradle", "--stacktrace", "run"]
The image builds without problems. However, when starting with docker compose up
, I get the following error: java.sql.SQLException: No suitable driver found for "jdbc:postgresql://tasks-db:5432/test-tasks-db?user=postgres&password=postgres"
The server still runs, just without the DB connection – I can access other endpoints/features.
Docker Compose:
version: "3.9"
services:
java-service:
build:
context: ./EchoServer/
dockerfile: Dockerfile
ports:
- "5000:5000"
environment:
- PORT=5000
- JDBC_DATABASE_URL="jdbc:postgresql://tasks-db:5432/test-tasks-db?user=postgres&password=postgres"
tasks-db:
image: postgres
restart: always
ports:
- "1235:5432"
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
volumes:
- tasks-db:/var/lib/postgresql/data
volumes:
tasks-db:
driver: local
logvolume01: {}
Grateful for any help, have been blocked on this most of the evening.
EDIT: build.gradle dependencies:
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
implementation 'org.json:json:20210307'
implementation 'org.postgresql:postgresql:42.3.1'
}
2
Answers
So after a lot of trial and error, it was a problem with the docker-compose yml, specifically the environmental variable for the DB.
BAD:
JDBC_DATABASE_URL="jdbc:postgresql://tasks-db:5432/test-tasks-db?user=postgres&password=postgres"
This gives DriverManager the url wrapped in quotes. You do not want this.
GOOD:
JDBC_DATABASE_URL=jdbc:postgresql://tasks-db:5432/test-tasks-db?user=postgres&password=postgres
Lack of quotation marks in docker-compose.yml leads to a happy DriverManager.
You don’t show how you build your Java application – but you’re missing a dependency on the postgres JDBC driver. It does not come with Java, but has to be presented to a Java application in its classpath. Using maven, you would add this dependency: https://mvnrepository.com/artifact/org.postgresql/postgresql/42.3.3