BreadcrumbHomeResourcesBlog Docker Container Development With Visual Studio Code and JMSL December 17, 2019 Docker Container Development With Visual Studio Code and JMSLEmbedded AnalyticsBy Chris BednarzContainer-based development has been a rising area of software development. However, despite the flexibility, container development creates its own set of unique challenges.In this article, we'll look at the first steps in taking advantage of container development when working with JMSL.Using Docker for DevelopmentOne challenge in container development, due to containers not typically having a display, is the lack of a native editor. With a new "Remote - Containers" extension for Visual Studio Code, Microsoft has aimed to alleviate this problem. "Remote - Containers" enable developers to use Visual Studio Code as if it were running inside the Container, allowing for easier project management, development, and debugging.While each piece of the example below will be explained, if you're new to Docker, Containers, or even Visual Studio Code, it may help to get a better understanding of them before proceeding.What's a Container?Getting Started with DockerGetting Started with Visual Studio CodeExample: Docker Container Development With JMSLThe example we'll be looking at JMSL with the BesselEx1 example. Additional examples and complete documentation can be found in the documentation.RequirementsDockerVisual Studio Code with the Remote - Containers pluginJMSL 2018.1 and a subscription license.For first time users, follow Microsoft's getting started instructionsProject StructureIn order to improve integration with Visual Studio Code, Maven will be used to manage our example project's configuration. As a side-effect of this, the folder structure and file names used need to be set up in a particular way:. |-- .devcontainer | |-- Dockerfile | |-- devcontainer.json | `-- jmsl-2018.1.0-linux_eval.run |-- .vscode | `-- launch.json |-- pom.xml `-- src `-- main `-- java `-- example `-- BesselEx1.java Docker Container ConfigurationAt the project's root directory the .devcontainer folder allows us to specify how to set up our Docker container along with how Visual Studio Code should use it.The devcontainer.json file offers Visual Studio Code-specific configurations for how to interact with Docker. It's here that we specify attributes such as Visual Studio Code extensions and Java home. Additionally, in order to simplify our license management, we use the "-v" flag to mount our license file as a volume.Note: /path/to/imsl_eval.dat must be updated with the appropriate path to your JMSL subscription license file./.devcontainer/devcontainer.json{ "name": "JMSL Example", "dockerFile": "Dockerfile", "settings":{ "java.home": "/docker-java-home", "terminal.integrated.shell.linux": "/bin/bash" }, "extensions": [ "vscjava.vscode-java-pack", "redhat.vscode-xml" ], "runArgs": [ "-v", "/path/to/imsl_eval.dat:/opt/RogueWave/imsl_eval.dat" ] } Dockerfile, on the other hand, tells Docker how to build our container. In the file below, we'll set up a new image utilizing Maven 3.6 and JDK 11./.devcontainer/DockerfileFROM maven:3.6-jdk-11 ENV DEBIAN_FRONTEND=noninteractive # Install recommended packages RUN apt-get update RUN apt-get -y install --no-install-recommends apt-utils dialog RUN apt-get -y install git procps lsb-release # Link Java install directory to our previously defined "docker-java-home" folder RUN ln -s "${JAVA_HOME}" /docker-java-home # Copy and run JMSL installer ENV JMSL_INSTALLER jmsl-2018.1.0-linux_eval.run COPY ${JMSL_INSTALLER} /tmp/jmsl-installer.run RUN /tmp/jmsl-installer.run --mode unattended RUN rm /tmp/jmsl-installer.run ENV DEBIAN_FRONTEND= Finally, in order to ensure Docker is able to find and run our JMSL installer, we must place the jmsl-2018.1.0-linux_eval.run file in the .devcontainer folder.Project filesNow that our container is properly configured, we need to set up our Maven project. We do this through the pom.xml file./pom.xml<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>example</groupId> <artifactId>jmsl-docker-example</artifactId> <version>1.0-SNAPSHOT</version> <name>jmsl-docker-example</name> <url>http://www.roguewave.com/</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>jmsl</groupId> <artifactId>jmsl</artifactId> <version>2018.1</version> <scope>system</scope> <systemPath>/opt/RogueWave/jmsl-core-2018.1.0-eval.jar</systemPath> </dependency> </dependencies> </project> While the code of this file is boilerplate, we've added a <dependency> tag to specify where Maven can find our JMSL dependency.Of course, specifying our project won't do much good without a source file to go along with it.Here we've taken the BesselEx1 example and placed it into our project. The package name has been modified for the sake of brevity./src/main/java/example/BesselEx1.javapackage example; import com.imsl.math.*; public class BesselEx1 { public static void main(String args[]) { double x = 10.e0; int hiorder = 4; // Exercise some of the Bessel functions with argument 10.0 double bi[] = Bessel.I(x, hiorder); double bj[] = Bessel.J(x, hiorder); double bk[] = Bessel.K(x, hiorder); System.out.println("Order Bessel.I Bessel.J Bessel.K"); for (int i = 0; i < 4; i++) { System.out.printf(" %d %10.4f %10.4f %10.4f\n", i, bi[i], bj[i], bk[i]); } } } Visual Studio Code ConfigurationAt this point, our container and project are defined. The final piece is to add our launch.json file. This tells Visual Studio Code how it should invoke our application. In this case, we need to include the com.imsl.license.path property for our license file./.vscode/launch.json{ "configurations": [ { "type": "java", "name": "BesselEx1", "request": "launch", "mainClass": "example.BesselEx1", "projectName": "jmsl-docker-example", "vmArgs": "-Dcom.imsl.license.path=/opt/RogueWave/imsl_eval.dat" } ] } Executing the ExampleNow that all the files are appropriately set up, we can run the example.Open the project folder in Visual Studio Code.Press F1 (or press the green button in the bottom left-hand corner) and select the "Remote-Containers: Reopen Folder in Container..." command.Run the example application by pressing F5.A terminal view should open and the following output should be produced:Order Bessel.I Bessel.J Bessel.K 0 2815.7166 -0.2459 0.0000 1 2670.9883 0.0435 0.0000 2 2281.5190 0.2546 0.0000 3 1758.3807 0.0584 0.0000 Additional Resources and Next StepsNow that it runs, feel free to try out the other JMSL examples. For further guidance please review the following resources:JMSL DocumentationDeveloping Inside a ContainerVisual Studio Code - Java in a Container sampleVisual Studio Code - Java TutorialTry JMSL for FreeWant to try JMSL on your project? Request a trial today by clicking the button below.REQUEST A FREE JMSL TRIAL
Chris Bednarz Senior Software Developer, Perforce Chris Bednarz is a Senior Software Developer for SourcePro and HydraExpress at Perforce. An experienced developer, Chris is focused on bringing efficiency and modernization to software and its process.