55

I had a friend who said:

Docker is amazing. You can use it to replicate production and all its quirks on your local machine. Then you can deploy that instance straight through all the staging workflows super-quick.

Now this would be true if the developers were writing Ruby, PHP or Go - where there was a direction binary link to the operating system.

But when using Java - there is already a virtual layer between the operating system and the language, making consistency of operation regardless of the underlying operating system.

Arguably, in this case, the benefits of running Docker for developers locally to replicate the production environment are negated. (Compared to Ruby, PHP or Go).

I'm open to discussion on this and am keen to hear a dissenting point of view (with evidence).

Are the development benefits of using Docker negated when using Java compared to other languages closer to Unix binaries?

hawkeye
  • 4,859

4 Answers4

87

Not at all.

Imagine you're running the version 1.8.0 of Java on both your development machine and the server. By the way, you're working simultaneously on two projects, both using Java.

One day, a bug is found in JVM, and the servers which run the first project you're working on are migrated to 1.8.1. By the way, the servers running the second project aren't affected by the bug, and are managed by a different team of system administrators, who may not be willing to update to 1.8.1.

Now, at least for one of the projects, you're running a different version of Java.

This may not bother you too much (until one server migrates to 1.9, while the other one keeps the old version), but this would mean that you're not replicating production environment any longer on your local machine, which makes it possible for tiny bugs to creep in.

If you imagine that your file system, your dependencies, your security settings, your local configuration and your version of Linux itself differ from production, you are putting yourself at risk of writing code which will fail in production. Instead of taking this risk, you could be using virtualization or Docker, with minor to no productivity loss.

35

You rarely just deploy a "Java App". Your java application has a lot of different support programs around it. We use Apache HTTPD, Apache Tomcat, ActiveMQ for messaging, an FTP Deamon, MySQL and a handful of custom services to integrate with programs that don't work directly with Java.

This doesn't even go into the development software that goes along with it--eclipse, ant, adobe flex, groovy, firefox and subversion (I'm skipping quite a few)

It takes between a full day and a week to set up a new workstation--we've discussed moving to Docker to simplify this issue. It would be amazing if we could reliably roll out a new workstation in a couple hours.

Not to mention the fact that when we deploy we need to maintain upwards of--20 servers; Docker is starting to look like a pretty good deal!

(20 seems Pretty painful for an app that only runs on a single server at a time... but multiply that one server by clusters(x2), test/staging/prod(x3), Internal/External(x2) and primary site/backup site(x2) and you get up there pretty quickly)

Bill K
  • 2,749
9

This question would also be pertinent for golang, where you can just extract statically linked binaries and run them somewhere, as opposed to Python or C++ where you usually have a large number of linked libraries which leads people to just build a docker container out of the development environment.

There are two points to answer here:

One: there has to be a better way, and there is: you can build smaller (and more efficient) docker containers using just the install environment, which leads to similar advantages as in the case of Golang-with-environment versus Golang-just-binaries containers. In the case of Java, you can build a fat jar or an installable app which contains all the library jars and a shell script; in the case of Python, you could use auditwheel to build self-contained wheels that are independent of the build environment (and you could use C++ with static linking to almost the same effect).

Two: what do you need docker for? In Java land, you can do a lot of separation between different components by using class loaders, but the main point is what is around the Java application. No Java application runs by itself - if it does not run in docker, it would usually have to be supervised by supervisord or systemd or the likes. Enter Kubernetes, Marathon, or Docker cloud, which use the container abstraction to virtualize not the host itself, but actually virtualize the whole network such that you can just deploy containers and they run on some random host.

Microservices usually run on docker-based clouds because it allows you to treat your docker hosts as cattle, not as pets, and similarly with the dockerized applications. Of course, this abstraction becomes leaky as soon as you mount host volumes onto docker and need to run docker containers on exactly the host that has these volumes. Some people get even around that.

Yannick
  • 99
  • 1
6

This is a really good question but after working with Docker, I would turn it around:

Are the benefits of the JVM negated by containerization (e.g. Docker)?

Containers really challenge a lot of the assumptions I have about development that come from my experience. For example, if someone were to hard-code a path to a resource file in an application, a lot of experienced developers would know that this is problematic and you should make it configurable. But if you are targeting a container, is this really the case? When you build the container, you tell it what the directory structures are. You are configuring the path there. So should you configure it twice? What's the benefit? If you don't make them match, it won't work so... DRY?

I recently created a prototype application with Java and Docker which essentially watched the GC events and when the old portion of the heap hit a threshold percentage, it would shut itself down. Docker (swarm mode) would then spin up a new one. Essentially, it eliminated the need for major GC-cycles in the JVM and let docker manage them. It didn't work as well as I might have hoped (clients saw some impact of the shutdown) but it was functional enough to do a live demo to a crowd.

You should really just try containers out if you are curious. It really is a disruptive technology and you will need to come to grips with it. Docker is a great place to start but there is at least one other viable alternative which is good for everyone, IMO.

JimmyJames supports Canada
  • 30,578
  • 3
  • 59
  • 108