[diet4j logo]

diet4j

No more JAR bloat; load your Maven projects as needed at run-time

News:

diet4j, noun

  1. A principled plan to limit ingestion to only the right foods JARs instead of living a life of bloat oversized, all-but-the-kitchen-sink JARs and WARs.
  2. An assembly of all the notables modules needed (and no more) in a particular place and time to make important decisions run a Java application.

So what is diet4j?

diet4j lets you distribute your Maven modules as you built them: one at a time. No need for gigantic JARs or WARs that bundle a gazillion libraries.

When you run an application, diet4j automatically assembles all required modules into a running executable (or web app). It's like Maven at run-time.

It currently works for command-line applications, and Tomcat web applications.

The old way:

> java -classpath this.jar:and-this.jar:and-that.jar:and-i-forgot-something.jar:and-lets-bundle-this-too-just-in-case.jar:and-five-more-miles-of.jar

or

> java -jar BLOAT.jar

The diet4j way:

> diet4j my-project

where my-project is the name of your top-level Maven project. Regardless how complicated its dependencies might be, diet4j will pull in all dependent module JARs at run-time — just like Maven does at compile time. And it uses the pom that maven already packages with the JAR, so you have to do basically nothing to get your code ready for diet4j.

(If you don't like our shell script, you can say java -jar diet4j-cmdline-VERSION.jar my-project instead; it does the same thing.)

Why is this a good idea?

Some people like gigantic JARs and long build times. If you don't, diet4j lets you:

  • Ship and update a module used by several applications on the same server once, instead of once per app. Lots of other programming languages do that (libc.so, anyone?). Why not Java?
  • Reduce incremental build/deploy times by just updating the JAR of the module that was updated, not the entire application.
  • Dynamically load additional modules at run-time without taking the app down, if you are so inclined. jdiet has an API for that.
  • Use a separate ClassLoader for each module. Helps with modularization, security, and debugging.
  • It works with most existing Maven projects without change!

How to install

Getting the code is easiest right now with git:

> git clone https://github.com/diet4j/diet4j.git
> cd diet4j
> mvn install
> install -m755 diet4j-cmdline/bin/diet* ~/bin/

(This is for Linux)

Demo apps

Get them:

> git clone https://github.com/diet4j/diet4j-examples
> cd diet4j-examples
> mvn install

Run example 1:

> DIET4J_REPO=$HOME/.m2/repository diet4j org.diet4j:diet4j-examples-one some rand/some text

This is what happened:

  • diet4j's main program started, and looked for maven module with groupId org.diet4j and artifactId diet4j-examples-one in your maven repository at HOME/.m2
  • After loading the JAR, diet4j examined the contained Maven POM file, and noticed that this module has a dependency: module diet4j-examples-utils. So it loaded that, too.
  • diet4j created a ClassLoader for each, and connected them, so that the main module can load the classes from the dependency (but not the other way around).
  • diet4j then looked for a main() method to run in the main module, and found one in the Main-Class field of the top module's MANFIEST.MF, just as if you had run the application with a kitchen-sink-JAR directly from the command-line.
  • diet4j passed the remaining arguments into that main() method.
  • Note: no jar-with-dependencies required.

To learn more, we suggest you look at the code for the examples on Github.

What else can diet4j do?

  • Find and load modules at run-time. That's great for apps that have plug-in's and other add-on's that the user can add without needing to restart the app.
  • Activate and deactivate modules when they are loaded/unloaded. Try
    > DIET4J_REPO=$HOME/.m2/repository diet4j org.diet4j:diet4j-examples-activate
  • Do the same thing for Tomcat web apps. For that, you add diet4j-tomcat.jar (which you built earlier in diet4j-tomcat/target/diet4j-tomcat-VERSION.jar) to your Tomcat lib directory, restart Tomcat, and add a Loader statement to your context.xml file.
  • And if you don't like prefixing your diet4j commands with the environment variable, you can put it into your ~/.bashrc or such. By default, diet4j looks for modules in /usr/lib/java.
  • As if 0.14, diet4j can now easily run under jsvc, the Apache project's Java daemon (docs), which in itself can be easily run from systemd on Linux. This makes it a lot easier to run diet4j-based server applications.

Platforms

This has been tested on Linux and OSX, but should run on Windows as well.

License

Apache 2.0, a liberal open-source license.