Quick and clean start with Java 9–running Docker container in VirtualBox VM on Windows 10 courtesy of Vagrant image 83

Quick and clean start with Java 9–running Docker container in VirtualBox VM on Windows 10 courtesy of Vagrant

The messages from JavaOne 2017 were loud and clear. Some of these:

  • Java 9 is here,
  • the OpenJDK has all previously exclusive commercial features from the Oracle (fka SUN) JDK – this includes the Java Flight Recorder for real time monitoring/metrics gathering and analysis,
  • Java 9 will be succeeded by Java 18.3, 18.9 and so on (a six month cadence) with much quicker evolution with continued quality and stability
  • JigSaw is finally here; it powers the coming evolution of Java and the platform and it allows us to create fine tuned, tailor more Java runtime environments that may take less than 10-20% of the full blown JRE
  • Java 9 has many cool and valuable features besides the Modularity of JigSaw – features that make programming easier, more elegant more fun more lightweight etc.
  • One of the objectives is “Java First, Java Always” (instead of: when web companies mature, then they switch to Java) (having Java enabled for cloud, microsevice and serverless is an important step in this)

    Note: during the JavaOne Keynote, Spotify presented a great example of this pattern: they have a microservices architecture (from before it was called microservice); most were originally created in Python, with the exception of the search capability; due to scalability challenges, all Python based microservices have been migrated to Java over the years. The original search service is still around. Java not only scales very well and has the largest pool of developers to draw from, it also provides great run time insight into what is going on in the JVM

I have played around a little with Java 9 but now that is out in the open (and I have started working on a fresh new laptop – Windows 10) I thought I should give it another try. In this article I will describe the steps I took from a non Java enabled Windows environment to playing with Java 9 in jshell – in an isolated container, created and started without any programming, installation or configuration. I used Vagrant and VirtualBox – both were installed on my laptop prior to the exercise described in this article. Vagrant in turn used Docker and downloaded the OpenJDK Docker image for Java 9 on top of Alpine Linux. All of that was hidden from view.

The steps:

0. Preparation – install VirtualBox and Vagrant

1. Create Vagrant file – configured to provide a VirtualBox image (based on Ubuntu Linux) and provision the Docker host on that image as well as a Docker Container with OpenJDK 9

2. Run Vagrant for that Vagrant file to have it spin up the VirtualBox, install Docker into it, pull the OpenJDK image and run the container

3. Connect into VirtualBox Docker Host and Docker Container

4. Run jshell command line and try out some Java 9 statements

In more detail:

1. Create Vagrant file

In a new directory, create a file called Vagrantfile – no extension. The file has the following content:

It is configured to provide a VirtualBox image (based on Ubuntu Linux) and provision the Docker host on that VB image as well as a Docker Container based on the OpenJDK:9 image.

image

Vagrant.configure("2") do |config|
 
config.vm.provision "docker" do |d|
    d.run "j9",
      image: "openjdk:9",
      cmd: "/bin/sh",
      args: "-v '/vagrant:/var/www'"
    d.remains_running = true  
  end
 
# The following line terminates all ssh connections. Therefore Vagrant will be forced to reconnect.
# That's a workaround to have the docker command in the PATH
# Command: "docker" "ps" "-a" "-q" "--no-trunc"
# without it, I run into this error:
# Stderr: Get http:///var/run/docker.sock/v1.19/containers/json?all=1: dial unix /var/run/docker.sock: permission denied.
# Are you trying to connect to a TLS-enabled daemon without TLS?
 
config.vm.provision "shell", inline:
"ps aux | grep 'sshd:' | awk '{print $2}' | xargs kill"
 
config.vm.define "dockerhostvm"
config.vm.box = "ubuntu/trusty64"
config.vm.network "private_network", ip: "192.168.188.102"
 
config.vm.provider :virtualbox do |vb|
  vb.name = "dockerhostvm"
  vb.memory = 4096
  vb.cpus = 2
  vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
  vb.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
end
 
end

# to get into running container: 
# vagrant ssh
# docker run -it  -v /vagrant:/var/www openjdk:9 /bin/sh

2. Run Vagrant for that Vagrant file

And have it spin up the VirtualBox, install Docker into it, pull the OpenJDK image and run the container:

image

3. Connect into VirtualBox Docker Host and Docker Container

Using

vagrant ssh

to connect into the VirtualBox Ubuntu Host and

docker run –it openjdk:9 /bin/sh

to run a container and connect into the shell command line, we get to the environment primed for running Java 9:

image

At this point, I should also be able to use docker exec to get into the container that started by the Vagrant Docker provisioning configuration. However, I had some unresolved issues with that – the container kept restarting. I will attempt to resolve that issue.

4. Run jshell command line and try out some Java 9 statements

JShell is the new Java command line tool that allows REPL style exploration – somewhat similar to for example Python and JavaScript (and even SQL*Plus).

Here is an example of some JShell interaction:

image

I tried to use the new simple syntax for creating collections from static data. Here I got the syntax right:

image

It took me a little time to find out the exit strategy. Turns out that /exit does that trick:

image

In summary: spinning up a clean, isolated environment in which to try out Java is not hard at all. On Linux – with Docker running natively – it is even simpler, although even then using Vagrant may be beneficial. On Windows it is also quite straightforward – no complex sys admin stuff required and hardly any command line things either. And that is something we developers should start to master – if we do not do so already.

Issue with Docker Provider in Vagrant

Note: I did not succeed in using the Docker provider (instead of the provisioner) with Vagrant. Attempting that (cleaner) approach failed with “Bringing machine ‘j9’ up with ‘docker’ provider…
The executable ‘docker’ Vagrant is trying to run was not
found in the %PATH% variable. This is an error. Please verify
this software is installed and on the path.” I have looked across the internet, found similar reports but did not find a solutio that worked for me.

image

The provider is documented here: https://www.vagrantup.com/docs/docker/

The Vagrantfile I tried to use originally – but was unable to get to work:

image

(based on my own previous article: https://technology.amis.nl/2015/08/22/first-steps-with-provisioning-of-docker-containers-using-vagrant-as-provider/)