This repository showcases some Java technologies that allow extending an application securely. This technical demo uses Java's service provider interface and JAR signing to allow a client application to dynamically load and validate external libraries.
The cli/ folder holds a console application that accepts any number of paths as arguments, and will scan these locations for JARs with classes that match the service provider interface. The ones that are signed (and un-tampered) will be used to output a greeting message. The formal/ folder provides such a library.
Warning
Please note that this is a technical demonstration, and is not intended for production use as it is. In particular, JARs should be signed with certificates issued by a trusted authority, and validated accordingly.
- Package the
cli/
project to generate the client application:mvn package -f formal/
- Run the client application:
The output should show only the built-in greeting service:
java -jar cli/target/cli-1.0-SNAPSHOT.jar
Answer[HelloService] Hello, world! Run again? [Y/n]
y
or just press Enter, and you will get the same message. - In another terminal, execute the
package
phase in the Maven project in theformal
folder to create and sign the extension:mvn package -f formal/
- Copy the signed extension to the
extensions/
folder of the client application folder:cp formal/target/formal-1.0-SNAPSHOT.jar cli/extensions/
- Back to the initial terminal, answer
y
once more, and you should see the new greeting provider's message:[HelloService] Hello, world! [FormalGreetingService] How do you do? Run again? [Y/n]
You have just run a client application that can be extended at runtime with vetted extensions.
Note
There is a [dev container] with Java 21 and Maven, which should allow running this project straight away in any Docker-equipped environment.
For convenience, the extension folder holds a keystore used to sign the JAR:
keytool -genkeypair \
-alias ABC \
-keyalg RSA \
-keystore abc.keystore.jks