How to use a docker container for JRE in VSCode IDE?

Viewed 742

In VSCode, my IDE, I'm configure the Language support for Java(TM) by Red Hat extension with a "Java" docker container. Thus far I have been able to set up the runtime, however I didn't manage to point my IDE to the Java home directory of the docker container.

According to the extension's page, this is what I need to achieve in order to make the extension work:

This JDK will be used to launch the Java Language Server. And by default, will also be used to compile your projects.

The path to the Java Development Kit can be specified by the java.home setting in VS Code settings (workspace/user settings). If not specified, it is searched in the following order until a JDK meets current minimum requirement.

  • the JDK_HOME environment variable
  • the JAVA_HOME environment variable
  • on the current system path

How I set up the runtime

As I already said, I manage to set up a runtime. This is how I did it:

  1. Added a java binary for the docker container, in my case I put it in /usr/local/bin.

    #!/bin/sh
    
    docker run \
         --name usr-local-bin-java \
         -i \
         --rm \
         --network=host \
         -w /root/project \
         -v "$PWD":/root/project \
         -v "$PWD"/.docker/mvn/cache:/root/.m2 \
         maven:3-jdk-8-slim \
         java "$@"
    
    exit $?
    

    I'm using a Maven image because I also needed Maven, which also includes Java. Of course a OpenJDK image could also have been used.

  2. Added/updated my IDE's user settings.json with the following:

    "java.configuration.runtimes": [
         {
             "name": "JavaSE-1.8",
             "path": "/usr/local/bin/java",
             "default": true
         }
    ],
    

Where I am stuck at

So the last step I've in front of me, is to specify the path for java.home. But how will I do that if it's located in a docker container? Well the most obvious solution would be to mount the path in the docker container to my host. Unfortunately that won't work because the path I need is stored in the docker image, thus when I mount my host to the path then it will result in a empty directory.

To summarize this won't work (note: java home in my docker image is at /usr/local/openjdk-8):

  1. Add the following argument to the java binary, to set up a volume mount:
    -v "$PWD"/.docker/java/jdk:/usr/local/openjdk-8 \
    
  2. Add the java.home attribute to the settings.json config:
    "java.home": "${cwd}/.docker/java/jdk",
    

This will result in something like: "The java.home configuration doesn't point to a valid JDK".

Does anyone know: What are my options here? Can I point to directory in a interactive automatically removed docker container?

PS: I don't want to install a JDK on my OS directly.

UPDATE #1: I managed to mount a volume from the docker container to my host

  1. Create a new docker volume:
    docker volume create openjdk
    
  2. Add the volume mount arg to the the java binary:
    -v openjdk:/usr/local/openjdk-8 \
    
  3. Run the binary:
    java -version
    
  4. Add the JDK_HOME or JAVA_HOME variable to your bash env:
    JAVA_HOME="$(docker inspect -f '{{ index .Mountpoint }}' openjdk)"
    
  5. Reload the IDE and get errors...

    Java 11 or more recent is required to run the Java extension. Please download and install a recent JDK. You can still compile your projects with older JDKs by configuring 'java.configuration.runtimes'

I even tried to set the java.home attribute to the mountpoint of the volume directly, which resulted in permission denied error, thus I chmod +rx -R my whole "var lib docker" directory (the place where the volumes are stored). Eventually the same error occurred as described in the steps above.

1 Answers

Okay I guess I just figured it out how to accomplish it, but it's not really the best way to do it I would say. Because it basically is the same as downloading the jdk and placing it in a certain directory... anyway:

  1. Create a docker volume to store the jdk in:
    docker volume create openjdk-15
    
  2. Run a container with the jdk you want (needs to be Java 11 or more recent) and while doing so let it fill the volume you just created:
    docker run --rm -v openjdk-15:/usr/local/openjdk-15 openjdk:15-slim java -version
    
  3. (optional) I like to symlink to the volume e.g.:
    sudo ln -s $(docker inspect -f '{{ index .Mountpoint }}' openjdk-15) /usr/local/lib/openjdk-15
    
  4. Configure the extension in settings.json:
    "java.home": "/usr/local/lib/openjdk-15",
    "java.configuration.runtimes": [
      {
        "name": "JavaSE-15",
        "path": "/usr/local/lib/openjdk-15",
        "default": true
      }
    ]
    

So there is no need for a custom java binary what spins up a docker container. However you still will have to store the JDK-files on your OS directly.

Related