We are switching from Oracle JDK/JRE to OpenJDK. Now I found only the JDK but I want to have a JRE as well from OpenJDK. This is for installing our application on the clients without the need of having the full JDK.
Is there a way to create a JRE package from the OpenJDK for Windows X64?
Inspired by the article Using jlink to Build Java Runtimes for non-Modular Applications I used the commands:
java --list-modules to get a list of all openjdk modules available
jlink --no-header-files --no-man-pages --compress=2 --add-modules <module-list from step 1> --output java-runtime to create a compact jre.
For OpendJDK 12 this is the command I ended up with:
jlink --no-header-files --no-man-pages --compress=2 --add-modules java.base,java.compiler,java.datatransfer,java.desktop,java.instrument,java.logging,java.management,java.management.rmi,java.naming,java.net.http,java.prefs,java.rmi,java.scripting,java.se,java.security.jgss,java.security.sasl,java.smartcardio,java.sql,java.sql.rowset,java.transaction.xa,java.xml,java.xml.crypto,jdk.accessibility,jdk.aot,jdk.attach,jdk.charsets,jdk.compiler,jdk.crypto.cryptoki,jdk.crypto.ec,jdk.crypto.mscapi,jdk.dynalink,jdk.editpad,jdk.hotspot.agent,jdk.httpserver,jdk.internal.ed,jdk.internal.jvmstat,jdk.internal.le,jdk.internal.opt,jdk.internal.vm.ci,jdk.internal.vm.compiler,jdk.internal.vm.compiler.management,jdk.jartool,jdk.javadoc,jdk.jcmd,jdk.jconsole,jdk.jdeps,jdk.jdi,jdk.jdwp.agent,jdk.jfr,jdk.jlink,jdk.jshell,jdk.jsobject,jdk.jstatd,jdk.localedata,jdk.management,jdk.management.agent,jdk.management.jfr,jdk.naming.dns,jdk.naming.rmi,jdk.net,jdk.pack,jdk.rmic,jdk.scripting.nashorn,jdk.scripting.nashorn.shell,jdk.sctp,jdk.security.auth,jdk.security.jgss,jdk.unsupported,jdk.unsupported.desktop,jdk.xml.dom,jdk.zipfs --output java-runtime
As others have mentioned, there's no longer a separate JRE distributed with the JDK since Java 9. You will need to use jlink and specify the modules your code depends on to generate a custom jre.
Because this can be a hassle, I've created a web-based tool to make it easier to create a custom JRE from an OpenJDK implementation (such as Oracle HotSpot, Eclipse OpenJ9, or Amazon Corretto) using jlink. The tool will give you the correct jlink command to run depending on your needs.
I've also included a way to make a standard Java SE JRE for those who just want a basic lightweight (~40-60 MB) JRE. If you know how to use a terminal, it'll take you less than 2 minutes to create a general-use JRE for JDK 9 and up.
Give it a try here - EasyJRE: https://justinmahar.github.io/easyjre/
Amazon Corretto OpenJDK https://aws.amazon.com/corretto/ has the builds for JDK and JRE
So I'm going to post something a little bit easier than what was posted by SteinarH. I didn't want to have to compile that list myself so.... this does it for you. Also for the sense of being a bit more concise I wouldn't label it java-runtime but instead jre-11 (or whatever version you are using).
This is PowerShell:
jlink --no-header-files --no-man-pages --compress=2 --add-modules $($(java --list-modules) -join "," -replace "#[0-9]*") --output jre-11
According to the Building OpenJDK document1:
Windows XP is not a supported platform, but all newer Windows should be able to build OpenJDK.
It then goes on to explain that Cygwin is required to do the build, the requirements for native compilers and libraries, and the issue of the "bootstrap" JDK that is required to compile the Java classes in the source tree.
But the clear implication is that you can build OpenJDK on Windows and for Windows ... even though the end result is not supported by Oracle or the OpenJDK project.
Note that the build document describes the make targets for creating JRE and JDK "images". I think it is saying that these are binary trees that can be copied to a target system and used. You could create ZIPs from them ...
But a simpler approach is to use "jlink" to generate a JRE-like executable; see the accepted answer.
#Andrew Henle points out that there are costs and (if you put yourself in the mindset of a corporate lawyer) risks in rolling your own JRE. Whether you just use it internally or you provide it to customers. If this is a concern, you are in a bit of a bind:
From Java 9 onwards, Oracle does not ship JRE distributions at all. Not for Oracle Java. Not for OpenJDK Java. As far as Oracle is concerned, JREs end after Java 8.
Anything that you build for yourself is a cost and a (erm) risk.
Fortunately, there are 3rd-party vendors who ship JRE distributions for Java on Windows. (Both AdoptOpenJDK and Azul do at the time of writing).
Alternatively, just use an Oracle JDK distro. Disk space is cheap, networks are fast.
1 - That link is for the Java 9 version of the document. For others, you should be able to find a corresponding "building.html" document at the same place in the source tree.
Since Java 9, you can use jlink to create a custom runtime environment for your application, using only the modules you actually need to run, which is typically even smaller than the traditional JRE was.
I'm using openjdk 11 in place of jre8 since oracle announced the license change. My customers were unhappy about them changing the agreement.
To get it to work, all I had to do was rename the sdk folder to jre.
One problem I did have was an external library dll. where open jdk complained it could no longer find in the class path. To fix that I just copied the dlls to the system32 folder.
Hope this helps
Stuart
On this site you can get jdk and jre (the jdk contains jre)
https://adoptopenjdk.net/upstream.html.
But if you need to build a jre you can use the following code in python (I have taken the answer from #SteinarH), the code assumes that you are in the jdk bin and that there is no directory called jre at the previous level.
import os
jmod_str = os.popen('java --list-modules').read()
init = jmod_str.index('#')
end = jmod_str.index('\n')
version = jmod_str[init:end]
jmod_list = jmod_str.replace(version, '').replace('\n', ',')
jmod_list = jmod_list[:-1] if jmod_list[-1] == ',' else jmod_list
cmd = 'jlink --no-header-files --no-man-pages --compress=2 --module-path ..\jmods --add-modules '+ jmod_list + ' --output ..\jre'
As far as I know the only place you can download OpenJDK for Windows is Azul website. However, they only seem to provide full JDK, so if you want just the JRE you need to build it yourself as Stephen C suggested.
For a more straightforward approach i wrote this little tool, which you can use under Windows:
https://github.com/g3t00ls/OpenJDKtoOpenJRE
I personally use OpenJDK from:
https://jdk.java.net/
It basicly does exactly what SteinarH wrote.
Currently it includes all java modules and exludes all jdk modules! A GUI to select required modules / an auto detect function for required modules for even smaller JRE's will probably be added soon!
Currently it still needs jlink, so only >=v9 JDK's will work! This could change in the future!
Reasons for making another answer:
I needed a single line to make a standard JRE to put in my Windows installer
I didn't want to have to update it when I upgrade java
Method:
I back engineered the output from the page that Justin made: https://stackoverflow.com/a/54997476/1280293 (Excellent utility)
I took the output of java --list-modules
selected only lines that start with java
removed the #versionnumber from the end of each line
joined the array into a comma separated string
appended it to jlink --output jre --compress=2 --no-header-files --no-man-pages --module-path ../jmods --add-modules
Notes:
This command assumes you have added your java bin to your path
This creates it's output directory in the folder you run the command from
PowerShell:
jlink --output jre --compress=2 --no-header-files --no-man-pages --module-path ../jmods --add-modules "$((java --list-modules | Select-String -Pattern '^(java[^#]+?)#' | % {"$($_.Matches.Groups[1].value)"}) -join ',')"
Azul Systems provides up-to date Windows JREs.
Here the link to Java 18 Windows JRE:
https://www.azul.com/downloads/?os=windows&architecture=x86-64-bit&package=jre
Amazon Corretto nor AdoptOpenJDK provide Windows JREs.
We are using the Azul distribution since Oracle decided to change its licensing and made very good experience.
Also previous versions can be found:
Related
So I've seen a bunch of tutorials on switching from Java 8 to Java 11, but I actually need to do the opposite. And I am doing it on a server, so I can use only bash.
I am pretty clueless of how to do it. Any help?
You can run this command and chose version java:
sudo update-alternatives --config java
This is what I do on my Debian system:
alias j8='export JAVA_HOME=/usr/lib/jvm/bellsoft-java8-full-amd64;export PATH=$JAVA_HOME/bin:$PATH'
This will ensure all executables are of the same version, and is a lot easier than update-alternatives, even if it did work (see my comments below another answer) or update-java-alternatives and is less error-prone
I use this tool SdkMan Install, SkMan manual
skd list java
print the versions of java available, and you can install it with comands like
sdk install java 8.0.292.hs-adpt
After you install a java version with sdkman set the java Home with
export JAVA_HOME=~/.sdkman/candidates/java/current
export PATH=$JAVA_HOME/bin:$PATH
you can install many java versions as you want and set your default version with
sdk default java 8.0.292.hs-adpt
If you use maven or gradle install them from sdkman, because in this way autodetects the version switching.
If you want to switch java versions only for specific projects check the env and .sdkmanrc part in the manual. It switches versions when you cd into a directory and go back to default when you cd out.
I am trying to build cross-platform archives of an application built using Java 11 and packaged with jlink.
For the cross-platform packaging I am basing my build on this answer. I have managed to make my Gradle build download the target platform's JDK and invoke jlink with the appropriate jmods folder, however the target image always includes the binaries and JRE structure of the host platform (in my case Windows, meaning the generated bin folder always includes DLLs and Windows executables). If I supply the --strip-native-commands flag then no executables are included at all, although the DLLs still are.
Is there any way to make jlink package the correct JRE files?
Host JDK: Windows Oracle JDK 11.0.10 x64
Target JDK: OpenJDK 11.0.2 x64
Sample Linux invocation:
C:\Program Files\Java\jdk-11.0.10/bin/jlink.exe
--module-path C:\projectdir\build\install\project-linux\lib;C:\projectdir\build\JREs\linux\jmods
--add-modules com.acme.app
--compress 2
--launcher app=com.acme.app/com.acme.app.Main
--no-header-files
--no-man-pages
--strip-debug
--dedup-legal-notices=error-if-not-same-content
--output C:\projectdir\build\packageFiles\linux
GraalVM
Using GraalVM CE Java 11 21.0.0 yields:
java.io.IOException: Invalid JMOD file: C:\jdks\graalvm-ce-java11-21.0.0\jmods\java.base.jmod
Which makes it seem like GraalVM's jlink always attempts to use the host's JMOD files.
OpenJDK
Using OpenJDK 11.0.2 x64 yields the same result of including the host's binary files in the created runtime image. The same behaviour is true for Zulu OpenJDK 11.0.10+9 x64.
Found the issue: the problem was with my reference to the jmods directory of both the Linux and the MacOS JDK distributions.
For the Linux one I mistakenly setup the build to download version 11.0.1 instead of 11.0.2, which ended up leading to the logic to flatten the hierarchy not flattening it. This means that the build/JREs/linux/jmods reference wasn't targeting any existing folder, meaning that jlink doesn't find the JDK modules there hence the host files being included.
The MacOS JDK has a completely different file structure so the flattening logic was just wrong. Ultimately this lead to the same missing jmods folder symptom.
With both issues fixed the jlink tool now correctly packages the target JDK's files when building cross-platform runtime images.
my understanding is you need to have a distributor to use openjdk someone like (oracle openjdk, adoptopenjdk) but on docker repo for openjdk how do I find out who is the distributor if I just use their reference documentation
{the code below in copied from openjdk official docker repo}
FROM openjdk:11
COPY . /usr/src/myapp
WORKDIR /usr/src/myapp
RUN javac Main.java
CMD ["java", "Main"]
moving from java 8 to java 11
It's all written there on the docker page: https://hub.docker.com/_/openjdk/
openjdk:<version>
This is the defacto image. [...] These are the suite
code names for releases of Debian and indicate which release the image
is based on. [...]
openjdk:<version> (from 12 onwards), [...]
Starting with openjdk:12
the default image as well as the -oracle and -oraclelinux7 variants
are based on the official Oracle Linux 7 image which is provided under
the GPLv2 as per the Oracle Linux End User Agreement (EULA). [...]
TL;DR: the images are maintained by the Docker community, versions < 12 ship the OpenJDK build from Debian or Alpine Linux, later versions ship the Oracle builds.
By the way, until Version including 8, the Oracle JDK was more freely available. Anyway, Linux distributions built their own binaries. The binary distributions by AdoptOpenJDK, Amazon Corretto, etc. are only there, because Oracle doesn't provide binary builds freely anymore. But you can download OpenJDK and build it yourself, if you like.
Edit: You could also ssh into the image and run java -version
Edit2: Java 7 and support
I want to address your comment on my answer. You specifically asked for Java version 7. This version is quite old (first release in 2011!) and you will not find any long term support for without paying for commercial support. Period.
This version also predates the license changes to Oracle binaries, so the whole AdoptOpenJDK argument doesn't matter.
On the OpenJDK Docker Hub page, you can see different images shipping Java 7 builds, some with Alpine Linux and some with Debian Jessie. Those are - presumably, I've only verified that for Debian - builds of the open source OpenJDK project by that distribution. So the GPL with classpath exception should be the license that applies (read: you can use it commercially).
Note that even the LTS-support for Debian Jessie ends next month: https://wiki.debian.org/LTS
That shouldn't be necessarily a problem, depending on where you want to run that image (i.e., facing the public internet vs. private intranet).
If you have to stick with such an old version of Java, you have few options (maybe taking a modern linux image and build OpenJDK yourself [that will be painful, I imagine]).
Edit3: Recent version 7 support and v8+ from AdoptOpenJdk
OK, so you clarified in your comment, that you are not actually looking for version 7 builds.
I did, however, find an up-to-date and supported build of Java 7, by Azul: https://hub.docker.com/r/azul/zulu-openjdk
But you said you're running version 8, looking to go to 11. Then I would highly recommend AdoptOpenJDK, which is currently the most popular build. They offer Docker images as well (Note: they offer different JVMs: Hotspot is the default and highly recommended, OpenJ9 is based on a development by IBM)
I can find java, javac and javadoc but there is no javah.exe in my jdk\\bin folder.
I tried to reinstall the JDK but it is still missing. How can I get it, why is it missing?
I found a similar question where the operating system was Linux but I can not find answers for Windows users.
My OS is Windows 10. The Java version is 10.0.1.
The tool javah.exe was removed in Java 10. The reason is simple, it is obsolete. From JEP 313: Remove the Native-header Generation Tool (javah):
Motivation
The tool has been superseded by superior functionality in javac, added in JDK 8 (JDK-7150368). This functionality provides the ability to write native header files at the time that Java source code is compiled, thereby eliminating the need for a separate tool.
Focusing on the support provided by javac eliminates the need to upgrade javah to support recent new paradigms, such as API access via the Compiler API in javax.tools.*, or the new java.util.spi.ToolProvider SPI added in JDK 9.
So you can just use javac.exe if you are on Java 8 or newer.
javah has been superseded by the -h option added to javac in JDK 8.
It is deprecated since Java 9.
See here for details.
I'm trying to install JDK8 on Debian Stretch. The recommended way is to use JavaPackage.
I have successfully packaged JDK6 and JDK7 using this method:
Download the JDK archive from Oracle
fakeroot make-jpkg jdk-7u55-linux-x64.tar.gz
dpkg -i the-resulting.deb
I can successfully create a .deb from the JDK8 archive, but when I install it with dpkg I'm missing a lot of dependencies.
gnome-icon-theme gtk-update-icon-cache java-common libasound2 libasound2-data libatk1.0-0 libatk1.0-data libcroco3 libdrm-amdgpu1 libdrm-intel1 libdrm-nouveau2 libdrm-radeon1 libdrm2 libgail-common libgail18 libgl1-mesa-dri libgl1-mesa-glx libglapi-mesa libgtk2.0-0 libgtk2.0-bin libgtk2.0-common libllvm3.9 libpciaccess0 librsvg2-2 librsvg2-common libtxc-dxtn-s2tc libx11-xcb1 libxcb-dri2-0 libxcb-dri3-0 libxcb-glx0 libxcb-present0 libxcb-sync1 libxcomposite1 libxcursor1 libxdamage1 libxfixes3 libxi6 libxinerama1 libxrandr2 libxshmfence1 libxtst6 libxxf86vm1 x11-common
I can install them manually but I'm not sure why I didn't have this dependency problem with the earlier JDKs. I'm writing an install script and it would please me to only install a single .deb rather than having to install all the extra dependencies separately.
make-jpkg supports JDK8 according to its man page.
make-jpkg builds a Debian package from the given Java distribution FILE.
Supported java binary distributions currently include:
* Oracle (http://www.oracle.com/technetwork/java/javase/downloads) :
- The Java Development Kit (JDK), version 6, 7 and 8
- The Java Runtime Environment (JRE), version 6, 7 and 8
- The Java API Javadoc, version 6, 7 and 8
(Choose tar.gz archives or self-extracting archives, do _not_ choose the RPM!)
Can anyone provide some insight as to why the .deb's created from earlier JDKs don't require any extra dependencies. Or perhaps it's just a case of their dependencies already existing in a stock Debian install.
Edit: I found this thread at Server Fault which goes some way to explaining it:
The reason this happens is that you are building a deb package from a binary distribution, i.e. a precompiled JDK. Usually, Debian packages are built from source, not from binaries. In order to do so, the person building the package would add all libraries the source depends on to a certain file (debian/control). Without those libraries installed, the source cannot be compiled and therefore would not result in a package.