put Java JARs on a diet, and load maven modules as needed (original) (raw)
News:
diet4j, noun
- A principled plan to limit ingestion to only the rightfoods JARs instead of living a life of bloat oversized, all-but-the-kitchen-sink JARs and WARs.
- An assembly of all the notables modules needed (and no more) in a particular place and time tomake 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 sayjava -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 artifactIddiet4j-examples-one
in your maven repository atHOME/.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 theMain-Class
field of the top module'sMANFIEST.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: nojar-with-dependencies required.
To learn more, we suggest you look at thecode 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 indiet4j-tomcat/target/diet4j-tomcat-VERSION.jar
) to your Tomcatlib
directory, restart Tomcat, and add aLoader
statement to yourcontext.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 fromsystemd
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.