9 ms·
Really Small Java Apps
- sgt 7y agoI get Docker and I use it, but it does bother me that one bundles the JDK along with the docker image. Such a waste of space. I like this idea, I hope it gets more traction. In terms of deployment of Java apps, we've found that Nomad works really well as it doesn't need a full Docker image (or equivalent) like Docker, Kubernetes etc. In Nomad you just make sure the worker node has the JDK, and then you specify the .jar file in the job.
- mzi 7y agoThat's not the whole truth, though. If you don't tweak chroot_env in the client settings you get a whole copy of /lib, /lib64, /sbin, /usr and some other things in each allocation. So less network traffic, but uses more real estate.
- sz4kerto 7y agoDocker images are layered, so this isn't a problem in most cases.
- jacques_chester 7y agoCloud Native Buildpacks take advantage of this to isolate a JRE or JDK to its own layer for fast rebasing and high reuse[0]. [0] https://github.com/cloudfoundry/java-cnb https://github.com/cloudfoundry/java-cnb
- sgt 7y agoYeah I meant the container i.e. the end result, not the actual image. I'm aware of layered images.
- taude 7y agoI don't see what the issue is with space/size having the JDK in a docker issue layer vs installing through ansible/chef later (or whenever it is you're doing). Docker images are layered, and by including a pinned version of the JVM that's baked into a core Docker stack for your org that's been security hardened, tested, etc, seems like it's better than taking the time to install a JVM every time during deployment of the worker node. EDIT: checking out Nomad now, since we have used other Hashicorp prods in the past...
- Longwelwind 7y agoI'm not sure this is the issue you are referencing, but you can use multi-stage Docker image builds to avoid bundling the JDK in the final Docker image: FROM openjdk:jdk AS build COPY . . RUN mvn package FROM openjdk:jre COPY --from=build ./somepath/app.jar . CMD java app.jar The first stage (defined by the first FROM) is only used to build the ".jar", the second stage will only contain the JRE and the ".jar" copied from the first stage.
- dashwav 7y agoAnything after Java 9 would have to use the jlink method, as with the new modules system, there is no longer a distinction between the JDK and JRE. The problem is most 3rd party libraries aren't ready for the modules switchover, so for anyone using those libraries, you are stuck with having either a 3-400mb docker image or using jlink
- javagram 7y agoThere are “jre” images for java 10 plus that exclude the java compiler and other unnecessary JDK components, you don’t need to use modules to use this.
- sgt 7y agoSorry, I didn't intend to write "image", but rather container. I can no longer edit my comment.
- z3t4 7y agoThe underlying file system might be able to dedupe the data. I remember playing around with linux containers and ZFS, where the base image was a snapshot, so only the changes to the base image take up hdd space. With modern solid state disks able to read several GB per second and with 1TB capacity, and Gbit Internet, i do not worry much if the app itself is 300MB big. If you skip the GUI the app should be fairly small - even when statically linked, then I use Linux namespaces for isolation, so no need to ship the entire OS with the app (which is a bit absurd imho. I wonder how many containers run old OS and risk container escape that would end up with root on the host, or the unnecessary extra virtualization layer killing the performance)
- commandlinefan 7y ago> bundles the JDK Not being pedantic, honestly - do you mean the JDK (which includes the compiler) or the JRE (just the VM)?
- deleted 7y ago[deleted]
- manojlds 7y agoIs GraalVM a good option for this?
- hmottestad 7y agoYes and no. Graal Native Image doesn’t work for spring, since some of the jvm functionality wrt. class loading don’t work yet (I think). Also native image has lower throughput due to the lack of profile driven code optimizations.
- argonium 7y agoMore info on Spring support for GraalVM native images: https://github.com/spring-projects/spring-framework/wiki/GraalVM-native-image-support https://github.com/spring-projects/spring-framework/wiki/Gra...
- jacques_chester 7y agoThe Spring team and Graal folks are working on full support. I believe the main angle is to ensure the annotation-based model will work smoothly[0]. Another is to introduce a fully-functional model (Spring Fu/Kofu [1]). Bear in mind, a lot of what Spring -- Spring Boot in particular -- gets charged with is beyond its control. It's an entrypoint to the vast Java ecosystem, much of which is also incompatible with Graal native images at the moment. [0] https://github.com/spring-projects-experimental/spring-fu https://github.com/spring-projects-experimental/spring-fu [1] https://github.com/spring-projects-experimental/spring-graal-native https://github.com/spring-projects-experimental/spring-graal...
- deleted 7y ago[deleted]
- deleted 7y ago[deleted]
- jcollins 7y agoI've found a combination of Spring Boot executable jar + a small jlink built JRE runtime packaged next to the executable jar works fairly well. Our zipped distribution is 50mb. Uncompressed the executable is 26mb and the runtime is 75mb. I'd love for it to be smaller but I can't complain. This also makes solving for Linux, macOS, and Windows pretty trivial. They each get their own zip with packaged runtime.
- jwhitlark 7y agoThis seems to be about the sweet spot that I keep finding, although I normally work in clojure.
- userbinator 7y agoI thought this article would be about something like https://en.wikipedia.org/wiki/Java_4K_Game_Programming_Contest https://en.wikipedia.org/wiki/Java_4K_Game_Programming_Conte... but it's more appropriately "Really Small JVM". For a simple project requiring java.net.http, using these steps produced a 23MB jlink image 23MB may seem tiny today, but depending on what that "simple project" does, in absolute terms it's still twenty-three million bytes. For comparison, a full installation of Windows 3.11 is roughly that size too, not compressed. As the saying goes, "there's still plenty of room at the bottom."
- aasasd 7y agoI thought it would be about sim cards and other smart cards.
- bluedino 7y agoTo be fair, Windows at that time was a pretty simple 16-bit operating system, and didn't even support networking until you added Winsock or WFW 3.11. It didn't really support much of anything until you started adding lots of other DLL's and libraries
- thrower123 7y agoThat'd be 16 floppy disks, or roughly a quarter of the hard disk space on my first PC clone. Or nearly ten Dooms!
- mhd 7y ago
- stuff4ben 7y agoInteresting to see this as I didn't know it was so simple to compile the JDK these days. But curious how this compares to Quarkus (https://quarkus.io/ https://quarkus.io/) which is built upon GraalVM?
- nobleach 7y agoI keep a close eye on quarkus.io. I love what they're doing for the Java ecosystem. It's interesting to see other frameworks follow suit (Micronaut, etc)
- crazysmoove 7y agoMicronaut predates Quarkus by almost a year, but they both seem to be great frameworks.
- nobleach 7y agoAgreed... I almost looked it up before I hit "reply". I didn't start seeing the container native/GraalVM stuff in Micronaut's tweets until more recently, but that doesn't mean anything. Good info to know. Thanks!
- lvh 7y agoGraalVM native-image is not a listed option, but I regularly use it to produce binaries that are competitive with (often better than) Go in terms of size and (start time) perf. A Clojure tool that parses, traverses and processes JSON (caro, see below) worked out to 3.2MB. I'm sure C and Rust can do better, but it's not bad compared to a JVM, and it's an order of magnitude better than the best option in the article. It's also small enough that while comparisons like "that's three floppies!" are interesting historical perspective, you can't reasonably complain about having a 3 MB binary in ~/.local/bin. Examples: https://github.com/latacora/wernicke/releases https://github.com/latacora/wernicke/releases https://github.com/latacora/recidiffist-cli/releases https://github.com/latacora/recidiffist-cli/releases https://github.com/latacora/caro/releases https://github.com/latacora/caro/releases It mostly works out of the box. My biggest frustration is that you can't easily link in dynamic libraries, which makes it a little annoying to do e.g. EC TLS with a single binary. (Go would have a similar problem but sidestepped it by reimplementing most of it natively.) Second biggest frustration: it is not a fast compiler. You're definitely doing development on the JVM (I use Graal as my default JVM now) and a "production build" afterwards with native-image.
- vips7L 7y ago>I regularly use it to produce binaries that are competitive with (often better than) Go in terms of size and (start time) perf. How do they compare to go in terms of speed? Another comment also said graal native images still suffer with throughput vs using the jvm due to profile guided optimizations.
- chrisseaton 7y agoIt's still optimised native code - it's not like they're running in an interpreter. The real issue is the GC is not as efficient.
- chvid 7y ago"Since bundling apps and runtime is the new best-practice" When did this become the new best-practice in Java land?
- gcbw3 7y agosince the author internalized the AWS marketing message.
- retbull 7y agoI mean AWS has driven a lot of developer practices in the last 10 years. Not a terrible bandwagon to jump on.
- diroussel 7y agoSince people tested on one JVM version and ran production in another. Finding that gives unpredictables results people moved to linking the versions together. And then the next natural step is distributing the runtime and the app together. Note this was not possible in the past as the java license prohibited redistribution.
- javagram 7y agoAfter OpenJDK 8 the separate JRE was deprecated. The recommendation now is for app developers to include their own JRE with the app; just like how each electron app includes its own copy of chromium.
- chrisseaton 7y agoSince mid 2017 when the JRE was discontinued. How else are you shipping Java apps? With the JDK? That’s for developers.
- malkia 7y agoHmmm.. Makes me wonder if this could help bazel slim down even more (although it's very acceptable size right now).
- zmmmmm 7y agoIt's an interesting turnaround. Once upon a time all the thinking was that you should pile as much into shared DLLs and common runtimes as you can, because those things will almost certainly be kept in the cache and will be much faster to launch / lower overhead. Now not only is it becoming "best practice" to bundle your whole runtime with your app, people are bundling the whole operating system via Docker. I'm curious if people have compared actually using a single JVM that is kept hot in OS cache vs separate minimal packaging for every app. It might favor single packaging if you only run 1 java app, but if you ran 10 different ones the benefits of shared code might win.