Add specific JRE to .Net Dockerfile - java

I'm setting up a .net Docker image, with some .net code within it. The code, however, needs access to a very specific version of Java Runtime (jre-7u9-windowsx64.exe).
I don't know exactly where to start in adding this executable into my dotnet Dockerfile.
The current Dockerfile for dotnet
FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build-env
WORKDIR /name
# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore
# Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out
# Build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "name.dll"]
I would just like to get the JRE added to the Dockerfile so it is installed or available when Docker spins up.

Because the JRE forms part of your runtime environment, you're going to want to install it into your # Build runtime image.
Your ideal goal is to find the lowest common multiple, sufficient to run both ASP.NET and your .NET code and the JRE and your Java code.
Option #1: Find a (trusted) container image that runs both ASP.NET and JRE
Presumably, you've pursued this approach and been unsuccessful.
Option #1: Start from your currently working solution and add
I'm unfamiliar with mcr.microsoft.com/dotnet/core/aspnet but this may well continue to suffice as your baseline and it has the advantage that you know it will run your .NET app.
So, your process will be to determine what additionally -- if anything -- you'll need to install to be able to run jre-7u9-windowsx64.exe.
A hacky way to determine this would be to insert whatever the installer is for this binary (between lines 13-14). This will take the form RUN the jre-7u9-windowsx64.exe installer. Then, try to build your container and see what errors arise.
A more considered approach would be to identify whether you need to install additional packages to support jre-7u9-windowx64.exe and, if you do, you'll need to install those (using further RUN ...) commands beforehand.
Option #2: Start from a minimal baseline and add
Alternatively, you could start from a more foundational baseline. I assume the OS here is Windows rather than Linux. Presumably there's a minimal Windows container image?
Then you'd need to add whatever is needed to:
Get ASP.NET and your .NET code working
Get JRE and your Java code working
This would provide a more considered foundation for your image but at the cost of requiring you to solve two puzzles.
Option #3: Start from a working JRE image and add
Included for completeness but not-recommended in this case.

Related

Understanding Startup Time Difference Between JRE and JDK Based Images

I am struggling to understand the startup time difference between JRE based application and JDK based application.
Think that I have an application with sample DockerFile
# syntax=docker/dockerfile:experimental
ARG BASE_IMAGE_FROM=<image>
FROM $BASE_IMAGE_FROM/maven-jdk11:0.0.2 as builder
WORKDIR /builder
COPY settings.xml /settings.xml
COPY . .
RUN --mount=type=cache,id=m2-cache,target=/root/.m2 /root/build.sh <app-name>
## app
FROM $BASE_IMAGE_FROM/<jre-name>
ARG APP_PATH=/builder
ARG DEPENDENCY=${APP_PATH}/target/dependecy
WORKDIR /server
COPY <somethings>
USER <some-user>
# update class to run
ENTRYPOINT exec java ${JAVA_OPTS} -cp app/config:app/lib/setup.jar:app:app/lib/* <app-name>
In the FROM $BASE_IMAGE_FROM/ part of the file, I specify JDK based or JRE based image. The current application is based on java 11 alpine JDK image. I've changed it with JRE based image. There is a big difference in size of the images.
I also thought there should be improvements in the startup time because of the overhead of the JDK. Yet, the startup time didn't change. I couldn't figure it why.
Any opinions?
Both the JDK and the JRE contain the same java runtime. The JDK contains additional tools like the javac compiler, javadoc documentation tool, and so on.
So in your setup, the JRE-based image will be much smaller, but when the container starts up, the ENTRYPOINT java ... starts the same JVM, loads the same class files, and runs the same application.
There's nothing different here other than the disk space required by the JDK functionality you're not using (if you need to pull the image, also the network I/O and time to download the unused files).

CloudFoundry and JDK

I'm struggling with the deployment of a spring app that needs to compile java code during runtime. My app calls the javac command when a user submits a solution to a problem, so it can later run java
I'm deploying to cloud foundry and using the java-buildpack, but unfortunately, it doesn't come with JDK, only JRE is available and that thing has no javac or java commands available.
Do you guys know a way on how to add JDK to cloud foundry, without having to write my own custom buildpack.
Thanks
I would suggest you use multi-buildpack support and use the apt-buildpack to install a JDK. It should work fine alongside the JBP. It just needs to be first in the list.
https://github.com/cloudfoundry/apt-buildpack
Example:
Create an apt.yml.
---
packages:
- openjdk-11-jdk-headless
Bundle that into your JAR, jar uf path/to/your/file.jar apt.yml. It should be added to the root of the JAR, so if you jar tf path/to/your/file.jar you should see just apt.yml and nothing prefixed to it.
Update your manifest.yml. Add the apt-buildpack first in the list.
---
applications:
- name: spring-music
memory: 1G
path: build/libs/spring-music-1.0.jar
buildpacks:
- https://github.com/cloudfoundry/apt-buildpack#v0.2.2
- java_buildpack
Then cf push. You should see the apt-buildpack run and install the JDK. It'll then be installed under ~/deps/0/lib/jvm/java-11-openjdk-amd64. It does not appear to end up on the PATH either, so use a full path to javac or update the path.

Unable to get GaalVM to work on latest version of OS/X?

I have tried loading the latest versions of GraalVm from the site onto OS/X from : graalvm-ce-java11-darwin-amd64-20.2.0.tar.gz
I tar this bundle, following the instructions and sudo mv the directory to /Libaray/Java/JavaVirtualMachines and setup the .bash_profile per the instructions. If I run the java_home -V command I see the VM there.
When I try to execute any of the command line utilizes from the VM (java, javac, jar, etc.) I get a fault by OS/X saying the application is from an untrusted developer. I then I have to to control panel/security and settings/general and manually select each an every binary and each and every native library one at a time and tell OS/X to add them as an exception to allow them to be run.
Am I missing something or is this expected behavior? Is there a better way to install the graalVM on OS/X?
This is an old issue but maybe it helps:
https://github.com/oracle/graal/issues/1724
I wonder why this has not been fixed yet.

How to create very small JRE using jrecreate in ejdk for windows 10?

I want to ship my java application (command line tool) along with a small jre. I tried a lot using jrecreate options of ejdk but, I am unable to create jre for windows 10. Please help me in this regard. I referred the following links. It is always creating for linux. How to do it for Windows ?
I used the the following command:
jrecreate.bat --profile compact2 --dest compact2-client --vm all
https://blogs.oracle.com/jtc/introducing-the-ejdk
https://www.oracle.com/technetwork/java/embedded/embedded-se/downloads/index.html
https://docs.oracle.com/javase/8/embedded/develop-apps-platforms/installing.htm
Assumption:
You already know what you are going to package into your JRE.
Like you have a list of dependencies or you have a jar file and you need to extract the dependencies and create a JRE with only those dependencies
If Java version is not of concern then you can stick to Java 9 and follow this post here.
https://medium.com/azulsystems/using-jlink-to-build-java-runtimes-for-non-modular-applications-9568c5e70ef4
I tried this a couple of weeks ago and it worked.
Regarding Win or Linux, it depends upon where you are running the jlink command
I used the following command to get compacted jre with profile compact1 in MAC.
jrecreate.sh -d ./compact1-jre/ -p compact1

Using 2 FROM in docker file: alpine-java-python and python3 removes installed java?

In my project, I need java and python3.
I used 2 FROM statements in Dockerfile.
FROM docker.<xx>.com/alpine-java-python
......
......
FROM python3
......
......
CMD [ "java", "-jar", "abc.jar"]
On starting of the container it gives "java command not found".
Why does the installed java gets deleted when using FROM python3 ?
First, to answer your question of why the installed Java gets deleted when using 'FROM python3':
The Docker Documentation states:
FROM can appear multiple times within a single Dockerfile to create multiple images or use one build stage as a dependency for another...Each FROM instruction clears any state created by previous instructions.
So what's happening is that your second 'FROM' is writing over what was done in the first 'FROM' and that's why you don't see Java in the final image.
Now, to answer the implied question of how do you fix this...
Since you want to have all these packages in a single image, you need to either:
Add the packages within a single 'FROM' section or
Use multi-stage docker builds where you pull packages installed, built, etc. from one 'FROM' instruction into another 'FROM' instruction. If you want to use multi-staged builds, I recommend reading the Docker Documentation on multi-stage builds.
For the example here, option (1) is sufficient. For that case, you should be able to do something like the following:
FROM docker.<xx>.com/alpine-java-python
RUN apk update && apk add python3
......
......
......
......
CMD [ "java", "-jar", "abc.jar"]
Note that if python2 exists in the base image, then both versions will now be installed and you will want to reference the python3 version when running your application, or change the default version.

Categories