1

The problem

I'm currently working with Java 9 and its module system and want to connect to my PostgreSQL database via JDBC.

The problem is that I could not find any information on its setup with Java 9 and it's module system but only for Java 8 and older.

The question

How can I properly setup JDBC and its driver using the java module system?

Community
  • 1
  • 1
ShadowDragon
  • 2,238
  • 5
  • 20
  • 32
  • What did you try and what went wrong? – Mark Rotteveel Nov 06 '19 at 12:28
  • You are making this way too difficult. A JDBC driver is a jar. Do jar stuff. – Gimby Nov 06 '19 at 12:31
  • @MarkRotteveel As far as I know, for a library without any module description a new module based on the jar file name will be created. Thus I tried to put `requires postgresql-42.2.8` in my module-info.jar but this did not work. – ShadowDragon Nov 06 '19 at 15:02
  • @ShadowDragon Recent version of the PostgreSQL JDBC driver declare `Automatic-Module-Name: org.postgresql.jdbc` in their manifest, so the module name is `org.postgresql.jdbc`. However, your own module doesn't need to require the PostgreSQL JDBC driver, as `DriverManager` (in module `java.sql`) loads the driver through the service loader mechanism. – Mark Rotteveel Nov 06 '19 at 16:05

1 Answers1

3

The jar must be on the classpath at runtime. For compilation you do not need the jar.

If the Postgresql driver is modularized already it would would work with the uses/provides mechanism for runtime:

The java JRE:

module java.sql {
   uses java.sql.Driver;
   exports java.sql;
}

The driver then should have something like this in module-info:

module org.postgresql {
   requires java.sql;
   provides java.sql.Driver with org.postgresql.Driver;
}

And the normal ServiceLoader would discover the driver automatically.

Class.forName("org.postgresql.Driver"); generally is not needed, just in some JavaEE applications where there is some class loader juggling.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
  • Looking at the documentation: It's not yet modularized. – ShadowDragon Nov 06 '19 at 13:51
  • https://stackoverflow.com/questions/42969977/derby-driver-not-found-in-java-9-module had a similar problem and there it was just the wrong classpath. Indeed 4.2, java 8, no module-info.class. – Joop Eggen Nov 06 '19 at 14:23
  • 1
    Without a module-info.class, I think it should work as well if the driver is on the module-path (not the class-path). – Mark Rotteveel Nov 06 '19 at 14:41
  • @MarkRotteveel thanks, I thought that jars on the _classpath_ were considered "unnamed" modules. Are you sure? (I lack the experience.) – Joop Eggen Nov 06 '19 at 14:54
  • @MarkRotteveel hm, interesting. We learned that Java will generate a module based on the jar files name for every jar without a module description (unnamed module). – ShadowDragon Nov 06 '19 at 15:10
  • To be honest, I'm not sure anymore. I experimented with modules a while ago and I thought that was sufficient, but I'll need to try again to be sure. You might be right that having it on the class-path would work as well. – Mark Rotteveel Nov 06 '19 at 16:08
  • @ShadowDragon The unnamed module is something else than generated module names. – Mark Rotteveel Nov 06 '19 at 16:10
  • Automatic Modules (like the PostgreSQL driver) should also work on the module-path. – JorSol Feb 18 '21 at 18:32
  • Note that automatic modules (like the PostgreSQL driver 42.4.1) will work on the module-path when run with the `java` command, but not with a module linking tool like jlink (which requires all linked modules to not be automatic modules). – jewelsea Aug 15 '22 at 23:14
  • 1
    Tracking info for the [feature request to define a module-info for the postgres JDBC jar](https://github.com/pgjdbc/pgjdbc/issues/1979). – jewelsea Aug 15 '22 at 23:23