Last Modified 2020.3.14

Modularization - JavaBank

This article covers modularization of the JDBC Example JavaBank.
Download the source with the following command.

git clone https://github.com/kimjonghoon/JavaBank

Download the Oracle JDBC Driver from https://www.oracle.com/database/technologies/jdbcdriver-ucp-downloads.html#license-lightbox.
Download the latest slf4j-api and slf4j-simple from http://www.slf4j.org/download.html.
Copy ojdbc6.jar, slf4j-api-1.7.30.jar and slf4j-simple-1.7.30.jar to jars/ directory.

src/
├── net
│   └── java_school
│       └── bank
│            ├── Account.java
│            ├── Bank.java
│            ├── BankDao.java
│            ├── BankUi.java
│            ├── ShinhanBank.java
│            ├── ShinhanBankDao.java
│            └── Transaction.java
├── simplelogger.properties
jars/
├── ojdbc6.jar
├── slf4j-api-1.7.30.jar
└── slf4j-simple-1.7.30.jar

Compile

CP=jars/slf4j-api-1.7.30.jar
CP+=:jars/slf4j-simple-1.7.30.jar
javac -cp $CP -d out -sourcepath src $(find src -name "*.java")

Copy properties to out/ directory.

cp src/simplelogger.properties out/

Run

CP+=:jars/ojdbc6.jar
java -cp $CP:out net.java_school.bank.BankUi

Before modularization, run the following to check the external library that JavaBank depends on.

jdeps -summary -cp jars/*.jar out
..
out -> jars/slf4j-api-1.7.30.jar
..

We found that JavaBank depends on slf4j-api-1.7.30.jar.
Remember that a library like this should be in the module path.
Jars that are not modules in the module path become automatic modules.

Modularization

Download the custom connection pool modules.

git clone https://github.com/kimjonghoon/java-module-test

Place the JavaBank sources in the src/ directory of java-module-test as follows. --Remove the main.app module in java-module-test--

src/
├── net.java_school.javabank
│   ├── net
│   │   └── java_school
│   │       └── bank
│   │            ├── Account.java
│   │            ├── Bank.java
│   │            ├── BankDao.java
│   │            ├── BankUi.java
│   │            ├── ShinhanBank.java
│   │            ├── ShinhanBankDao.java
│   │            └── Transaction.java
│   ├── module-info.java
│   └── simplelogger.properties

    ..Omit..

lib/
├── slf4j-simple-1.7.30.jar
jars/
├── ojdbc6.jar
└── slf4j-api-1.7.30.jar

Add jars/ to the module path. --Non-module jars in the module path become automatic modules--
Add lib/ to the classpath. --Non-module jars in the classpath become unnamed modules--
Only automatic modules can read unnamed modules.
--The fact that slf4j-api depends on slf4j-simple can easily be inferred from the jar name--
An unnamed module can read any other module.

To use the connection pool module in the net.java_school.javabank module, edit module-info.java of the net.java_school.javabank module as follows.

module net.java_school.javabank {
  requires net.java_school.db.dbpool.api;
  uses net.java_school.db.dbpool.api.ConnectionManageable;
}

Compile to see how the names of the automatic modules are determined.

javac -p jars -d out --module-source-path src $(find src -name "*.java")
src/net.java_school.javabank/net/java_school/bank/ShinhanBankDao.java:12: error: package org.slf4j is not visible
import org.slf4j.Logger;
          ^
  (package org.slf4j is declared in module org.slf4j, but module net.java_school.javabank does not read it)
src/net.java_school.javabank/net/java_school/bank/ShinhanBankDao.java:13: error: package org.slf4j is not visible
import org.slf4j.LoggerFactory;
          ^
  (package org.slf4j is declared in module org.slf4j, but module net.java_school.javabank does not read it)
2 errors

(package org.slf4j is declared in module org.slf4j, but module net.java_school.javabank does not read it)
The module name can be found in the above error message.
Add the following to module-info.java in net.java_school.javabank module.

module net.java_school.javabank {
  requires net.java_school.db.dbpool.api;
  requires org.slf4j;
  uses net.java_school.db.dbpool.api.ConnectionManageable;
}

Compile again.

javac -p jars -d out --module-source-path src $(find src -name "*.java")

Copy properties to the module directory.

cp src/net.java_school.db.dbpool.oracle/oracle.properties \
out/net.java_school.db.dbpool.oracle/
cp src/net.java_school.javabank/simplelogger.properties \
out/net.java_school.javabank/

Run

CP=lib/slf4j-simple-1.7.30.jar
java -cp $CP -p jars:out \
-m net.java_school.javabank/net.java_school.bank.BankUi
Related Articles References