I have a java program that I wrote. The main things include OpenJDK8, Maven, and JavaFX. The program builds and runs on its own. I want to put it in a Docker container, but I'm having trouble getting it to build.
Here is my Dockerfile:
FROM openjdk:8-jdk
FROM maven:3.3-jdk-8-onbuild
RUN apt-get update && apt-get install -y --no-install-recommends openjfx && rm -rf /var/lib/apt/lists/*
CMD ["java","-jar","target/"CodeDemo-1.0-SNAPSHOT.jar"]
Here is what I ran to build the container:
sudo docker build -t java-maven-code-demo .
Here is the error I keep getting complaining about no javafxpackager:
Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.2.1:exec
(unpack-dependencies) on project CodeDemo: Command execution failed.
Cannot run program
"/usr/lib/jvm/java-8-openjdk-amd64/jre/../bin/javafxpackager" (in
directory "/usr/src/app"): error=2, No such file or directory -> [Help
1]
I have all the files in a CodeDemo directory. At the top level, I have src, target, Dockerfile, pom.xml. In target, I have the compiled jar.
I'm confused by the error because I thought Java 8 OpenJDK came with JavaFX. So, if I'm pulling OpenJDK, I should be gettng the things I need for JavaFX (similar question on GitHub - solution still gave the error though).
Can anyone point me in the direction of what I could be doing wrong? Is there something else I should be doing to get the proper libraries?
You have multiple FROM lines. Based from your Dockerfile, only the maven base image will be used. Maybe try installing openjdk through another RUN statement before installing openjfx?
I also don't see any COPY statement in your Dockerfile. I initially assumed CodeDemo-1.0-SNAPSHOT.jar exists by default on the maven image but I just tried building the image and it doesn't exist. If that's the jar file from your Java program, don't forget to add it through a COPY statement in your Dockerfile.
Related
I have to bundle up my system using Docker. But my system uses Java (JAR file to run) and python with PyTorch. I initially tried to use openjdk:buster base Docker image and then installed python3 on top of it. So both JAR and PyTorch worked, but PyTorch is only CPU supportive. But now I have to speed-up my PyTorch code using GPU, and for that I need NVIDIA-Cuda. In a separate Docker, I found nvidia/cuda:10.2-base-ubuntu18.04 works for my PyTorch. But this Docker can't run JAR file.
So I am stuck in combining these 2. I either want to
install NVIDIA-Cuda dependencies to openjdk Docker base image
install openjdk (openjdk-14) dependencies to NVIDIA-Cuda Docker base image
Anyone has any suggestions on how I can do that or any alternative hacks ?
You can have a single image, instead of two by creating your own docker image that uses the nvidia image, and install java on it. I.e. have a Dockerfile as below
FROM nvidia/cuda:10.2-base-ubuntu18.04
RUN apt-get update
RUN apt-get install openjdk-14-jdk
COPY <your jar file> <a path>
CMD [ "java" "other java flags/args>" "-jar" "<path to your jar file>"]
run docker build on that Dockerfile, and docker run as you normally would, and your java code should have access to NVIDIA-Cuda. (Also note, some prefer ENTRYPOINT to CMD)
I am trying to compile Hadoop 3.1 from its source code.
Once inside docker container i am building it with maven following included instructions in BUILDING.txt inside Hadoop's source code files.
While Apache Hadoop Common ............................... FAILURE [ 0.458 s] is trying to build, i am getting the following error, regarding protoc --version
[ERROR] Failed to execute goal org.apache.hadoop:hadoop-maven-plugins:3.1.0:protoc (compile-protoc) on project hadoop-common:org.apache.maven.plugin.MojoExecutionException: 'protoc --version' did not return a version -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.hadoop:hadoop-maven-plugins:3.1.0:protoc (compile-protoc) on project hadoop-common: org.apache.maven.plugin.MojoExecutionException: 'protoc --version' did not return a version
However, the protoc command is working on my installation:
$ protoc
Missing input file.
$ protoc --version
libprotoc 2.5.0
Same thing is happening with protoc version 3.0.
Anyone experienced something similar?
After not finding the exact solution, here is a workaround.
Hadoop's source code, comes with ./start-build-env.sh. Upon running the script, a Docker container will be launched by it, in which Hadoop can be build with Maven.
All the necessary libraries exist in the container, but are only included in user's $PATH, and not root's $PATH. That's a problem because it comes handy using sudo to build the package, and that's the reason that protoc --version could not return something.
Now every container launched by ./start-build-env.sh seems to be temporary, and you can't edit the root's $PATH via ~/.bashrc. A workaround is to launch the container through ./start-build-env.sh and from another terminal window, log into the container using the command: sudo docker exec -it <container> bash. Now you can download a simple editor (like nano or vi through apt-get), and edit the default $PATH in visudo.
Then the command sudo mvn package -Pdist... inside the container, wont stuck in the problem I described above
I am using Jenkins, and using a Github repo as Source Code.
In the Build section, I am executing this as a Windows Batch command:
set path=%path%;C:\Program Files\Java\jdk1.8.0_144\bin
cd \Users\harr\JenkinsServer\JenkinsTest\src
javac SimpleTest.java //Error is after this executes
java SimpleTest
I know it has something to do with classpath, but I am unsure how to solve this problem in jenkins.
Let me know if more information would be helpful.
Suppose you deploy the jekins server on linux platform, so you have to install the jdk, tomcat and so on, set the env path as well. Then you don't have to execute set path before every build.
you can create a script and copy the command into it, then when jenkins performs the build task, it can execute the script. Refer to the jenkins tutorial to learn about it.
I inherited Android Java-code in my company, without Gradle-files etc, and I want to be able to compile this on my dev-server (I program from a ChromeOS machine, hence a CLI SSH connection to a server where I do dev stuff). Now I found some Docker images like this one (which doesn't even have a working command line example) but I haven't managed to create an APK yet. What am I missing and how would you do this?
You have three steps to do:
Migrate your project to gradle.
It isn't too difficult since there are plenty of gradle project out there and you can try to follow them or just read "Migrating to Gradle" article.
Build project with gradle on local machine.
If you migrated properly you can build your project in terminal like:
./gradlew assembleDebug
but it might be also assembleDevDebug or assembleProdRelease which depends on your buildType and flavor in gradle. Check which assembles are available by running:
./gradlew tasks
Build project using Docker.
Based on image you linked:
docker run -t -i ksoichiro/android -v /path/to/project:/workspace -w workspace /bin/sh -c "./gradlew assembleDebug"
I'll start by saying that I'm not a Java developer and also I'm not a Docker expert.
In order to minimize the gap between frontend and backend (in this specific case, Java) developers I started to put some docker images in place with java and maven and after the build I start a docker container with a volume pointing to the java project (and frontend developers don't have to worry about dependencies or how to run backend services).
Already here I have a question.
I've seen other people building an image with the actual code inside instead of attaching it later, so what's the best case (if there's one)?
I've done this way since I can reuse that image for "every" project and avoid building different images.
For starting/stopping/restarting docker containers I created a script that does all of that, so I can make some changes to the code, bring it down and up again.
It kinda works, and what I mean is, I'm well aware this is not a normal workflow of a Java developer to do that kind of stuff from a console.
So now, to the most important question, how do you integrate docker with a Java IDE?
I know that you can create custom build/run commands but I also read that things like logs are not displayed on the IDE's.
Can someone explain me how are you using Docker + Java IDE's?
Note: Maven is also used for compiling java code, like mvn clean install (if this helps)
I do not use Docker with a Java IDE. I use the IDE (Eclipse) to write and test the code, with Maven to manage the build. Then I have a Dockerfile like this:
FROM java:8
RUN apt-get update || apt-get update
RUN apt-get install -y maven
# Maven installs Java 7, which set itself as the default...
RUN update-alternatives --remove java /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java
CMD java -jar target/main.jar
# Pull down dependencies here to allow Docker to cache more
ADD pom.xml /opt/app/pom.xml
WORKDIR /opt/app
RUN mvn dependency:go-offline -X
# I use the maven-shade-plugin to build a single jar
ADD src /opt/app/src
RUN mvn package
If you build all your images on one machine, then Docker will cache intelligently and you don't need to do anything more. If you want to run across more machines, or you just want to make it explicit, you could do something like this:
base/Dockerfile:
FROM java:8
RUN apt-get update || apt-get update
RUN apt-get install -y maven
RUN update-alternatives --remove java /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java
CMD java -jar target/main.jar
$ docker build -t yourorg/java-base:8 ./base/
myapp/Dockerfile:
FROM yourorg/java-base:8
ADD pom.xml /opt/app/pom.xml
WORKDIR /opt/app
RUN mvn dependency:go-offline -X
ADD src /opt/app/src
RUN mvn package
You don't get as big an effect from Docker with Java, because JARs are already pretty portable and well-contained. I suppose it makes it easy to run different Java versions side-by-side. I use it because it allows me to run applications in different languages without needing to know what's inside the container. I have some in Java, some in Python, some in JavaScript, some in Erlang, but they all get started as docker run -d <flags> myorg/myimage:someversion.