Make .deb for JDK8 with JavaPackage - java

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.

Related

Upgrading Jenkins Java version from 8 to 11

I'd like to upgrade java from 8 to 11 as recommended for Jenkins 2.303.1, I'm reading the guide in https://www.jenkins.io/doc/administration/requirements/upgrade-java-guidelines/, but I don't know what to do in step:
Use a package manager to install the new JVM. Make sure the default
JVM is the newly installed version. If it is not, use the correct java
command in the Jenkins startup scripts (/etc/default/jenkins or
/etc/init.d/jenkins).
does it mean install Java 11 and set java 11 is default one?
Note: since June 2022, you do not have a choice anymore.
JDK 11 will need to be the one running Jenkins.
It does not have to be the "default" on your system. Only the one selected in the command use to run Jenkins.
Jenkins requires Java 11 (Basil Crow)
Beginning with Jenkins 2.357 (released on June 28, 2022) and the forthcoming September LTS release, Jenkins requires Java 11.
Additionally, beginning with Jenkins 2.355 (released on June 14, 2022) and Jenkins 2.346.1 LTS (released on June 22, 2022), Jenkins supports Java 17.
Plugins have already been prepared in JENKINS-68446.
Use the Plugin Manager to upgrade all plugins before and after upgrading to Jenkins 2.357.
Warning regarding JAXB
Prior to Java 11, Java Architecture for XML Binding (JAXB) was part of the Java Platform, and one could use it without adding a third-party dependency.
Beginning with Java 11, JAXB is no longer a part of the Java Platform and requires adding a third-party dependency.
Thanks to work done several years ago by Baptiste Mathus and others, a JAXB Jenkins plugin is available, which provides the JAXB library to Jenkins plugins in the form of a plugin-to-plugin dependency.
The vast majority of plugins have already been prepared to support Java 11 via the JAXB plugin in JENKINS-68446.
Jenkins users need only upgrade plugins to compatible versions as documented in the Released As field in Jira.
It is critical to use the Plugin Manager to upgrade all plugins before and after upgrading to Jenkins 2.357.
Failure to upgrade plugins to compatible versions may result in ClassNotFoundException, NoClassDefFoundError, or other low-level Java errors.
Upgrade
Docker
The official Jenkins Docker images have been based on Java 11 for many months, with Java 8 available as a fallback and Java 17 available in preview mode.
Beginning with Jenkins 2.357, the Java 8 images will be retired and the Java 17 images will transition from preview to general availability (GA). Users of the official Jenkins Docker images need not install or configure Java on their own, as it comes preinstalled in the image.
OS packages
Users of the official Jenkins OS packages for Debian, Red Hat, and SUSE Linux distributions should note that these packages are agnostic to the Java vendor. >
In other words, you must bring your own Java package. One straightforward way to do this is to install Java 11 from your Linux distribution, as described on the package download site
Recommenced Garbage collection options
-XX:+AlwaysPreTouch
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=${PATH}
-XX:+UseG1GC
-XX:+UseStringDeduplication
-XX:+ParallelRefProcEnabled
-XX:+DisableExplicitGC
-XX:+UnlockDiagnosticVMOptions
-XX:+UnlockExperimentalVMOptions
-Xlog:gc*=info,gc+heap=debug,gc+ref*=debug,gc+ergo*=trace,gc+age*=trace:file=${PATH}/gc.log:utctime,pid,level,tags:filecount=2,filesize=100M
-XX:ErrorFile=${PATH}/hs_err_%p.log
-XX:+LogVMOutput
-XX:LogFile=${PATH}/jvm.log
Agents
For best results, it is recommended to run agents with the same version of Java as the version used on the controller.
Use the Versions Node Monitors plugin to verify that agents are running a compatible version of Java.
Running the Jenkins remoting process on an agent with Java 11 or 17 does not imply that you need to run your builds with the same version of Java.
You can continue to use any desired version of Java for individual builds.
I opted to not install Java on the system, and followed the below approach:
Go to Java 11 Downloads (registration on oracle.com required)
Download the latest Java 11 Compressed Archive (zip) file. At the time of writing: jdk-11.0.15_windows-x64_bin.zip
Unzip this on your build server, keep the path where you extracted to for step 5
Backup Jenkins Home, especially your jenkins.xml file (same folder as jenkins.war).
In Jenkins.xml, update Executable to extracted path, e.g. C:\Java\jdk-11.0.11\bin\java.exe
Restart Jenkins Service
However you have (OpenJDK) 11 installed, as long as you have either JAVA_HOME=/path/to/jdk11 and PATH=$JAVA_HOME/bin:$PATH or explicitly run /path/to/jdk11/bin/java -jar jenkins.war or if you type java -version and it returns "11", you are fine.
Note: that is to launch jenkins. You can set the JDK available to your jenkins jobs from within Manage | Global Tools Configurationtion.
2nd Note (updated): the documentation has been updated (2021-09-16) ... The default Docker image jdk as of 2.303.1 is now 11, so you don't need to append ”-jdk11", rather users must append "-jdk8" if users want to stick to 8.
if you have Centos you can do the following(i have done this for Centos7 and Jenkins 2.367)
sudo yum install java-11-openjdk
yum install output
if have issues with repos and you want do this manually
you get the rpm's that you want and then :
first update the dependency .
sudo rpm -Uvh tzdata-java-2020a-1.el7.noarch.rpm
and then
sudo rpm -Uvh java-11-openjdk-headless-11.0.8.10-1.el7.x86_64.rpm
sudo rpm -Uvh java-11-openjdk-11.0.8.10-1.el7.x86_64.rpm
then you can give
sudo update-alternatives --config java
to find the java path of java 11 --> /usr/lib/jvm/java-11-openjdk-11.0.8.10-1.el7.x86_64/bin/java
it should not be the default, if you don't want to ,you can just copy it
and use it to jenkins nodes Java path at configure nodes
jenkins JavaPath
You have two options: You can globally install Java 11 on your system, for example using a package manager like apt. You would then make Java 11 your default Java.
The other option is to manually install Java, for example OpenJDK, and extract it to, for example, /opt/java and adjust the Jenkins startup script to use that specific Java installation.
I just upgraded a Jenkins installed from apt packages (from: http://pkg.jenkins-ci.org/debian/) with the following steps (inspired by: https://www.jenkins.io/doc/book/installing/linux/)
First, install java 11:
sudo apt install openjdk-11-jre
Then check java -version
which may still show openjdk version "1.8.[x]"
If so, do choose a java-11 alternative with:
update-alternatives --config java
Then java -version should show openjdk version "11.0.[x]"
Then you can do:
systemctl restart jenkins
docker exec -it <container_id> /bin/bash
If permission denied error, then,
docker exec -u 0 -it <container_id> /bin/bash
sudo apt-get update
sudo apt-get install openjdk-11-jdk
export PATH=$JAVA_HOME/bin:$PATH
java -version

jlink packages current platform's binaries

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.

Create jre from OpenJDK Windows

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:

How to use Typesafe Stack deb repo with Oracle Java 6 instead of OpenJDK?

I'd like to install Typesafe Stack to Ubuntu Server via their Deb repo, but without downloading all the OpenJDK packages. I have Oracle JDK 6 installed and in my PATH via update-alternatives and installing OpenJDK breaks some stuff.
What would be the best way to do this? It doesn't appear that I can use apt-get --no-install-recommends flag for this:
$> sudo apt-get install --no-install-recommends typesafe-stack sbt
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
ca-certificates-java default-jre default-jre-headless g8 java-common libaccess-bridge-java libaccess-bridge-java-jni openjdk-6-jre
openjdk-6-jre-headless openjdk-6-jre-lib
Suggested packages:
equivs icedtea-plugin sun-java6-fonts ttf-sazanami-gothic ttf-kochi-gothic ttf-sazanami-mincho ttf-kochi-mincho ttf-telugu-fonts ttf-oriya-fonts
ttf-kannada-fonts ttf-bengali-fonts
Recommended packages:
icedtea-netx icedtea-6-jre-cacao icedtea-6-jre-jamvm
The following NEW packages will be installed:
ca-certificates-java default-jre default-jre-headless g8 java-common libaccess-bridge-java libaccess-bridge-java-jni openjdk-6-jre
openjdk-6-jre-headless openjdk-6-jre-lib sbt typesafe-stack
0 upgraded, 12 newly installed, 0 to remove and 7 not upgraded.
Need to get 33.0 MB of archives.
After this operation, 86.9 MB of additional disk space will be used.
Do you want to continue [Y/n]? n
Abort.
PS - I know the Typesafe Stack components work with my current setup, since I had it installed and running fine with their prior installer.
I'm currently looking at the 'scala' and 'scala-library' packages at Ubuntu's own 'universe' repository, instead of Typesafe repository. These packages depend on 'java6-runtime' (I run Ubuntu 12.10, 'Quantal'). This might not be the case for the packages found at the Typesafe repository, but the principle should be the same.
The equivs package can be used to create a fake package stub (e.g. Package: local-java-runtime) that falsely claims to provide the undesired JRE (e.g.: Provides: java6-runtime).
This way you can manually install whichever Scala-supporting JRE you desire, then install the stub package you created, and apt-get install scala will no longer complain (the stub package will satisfy the dependency without APT having to pull in a JRE).
Take a look here to read up on equivs and see how it is done.
BTW, for at least the Linux distribution I'm running I see that 'openjdk-7-jre' already provides 'java6-runtime', so perhaps the 'java6-runtime' dependency will be less of an inconvenience than in the past.
Old question, has been answered for a long time now in my comments under my OP, just making it official now. On Debian-based systems just use Debian Alternatives, see setup scripts in my comments above. It's brilliant, just works, and provides the following benefits:
Use the exact version of Java/Scala/Haskell/etc you want, not what's in the Debian/Ubuntu/etc repos. Useful when the repo version lags the current version, or your app requires a specific version of the platform different from the repo.
Haskell platform. Install multiple GHC and Haskell Platform versions side-by-side, say in /opt/haskell/ghc/[version] and /opt/haskell/platform/[version], and easily toggle between them with update-alternatives --config. Same with Java, Scala, or any other sdk/platform.
Upgrade to new versions of GHC and Haskell Platform (or Java, Scala, etc) without overwriting or deleting the previous. If this causes regressions in your apps, easily roll back to the prior working version with a simple update-alternatives --config.
Keep all files of GHC and Haskell Platform together in a single location like /opt/haskell/ghc/[version] and /opt/haskell/platform/[version], instead of spread out over /usr/bin, /usr/lib, and /usr/share as with an apt-get or dpkg -i installation. The files are kept in /opt/haskell/ and update-alternatives soft links them to their system directories.
Easily uninstall with update-alternatives --remove-all (script included), and rm -rf /opt/haskell.
Run haskell via system PATH instead of user PATH (eg, no need to add /opt/haskell/ghc/bin to your PATH in .profile)
Get used to using update-alternatives, it's a great tool that makes managing manually installed, multi-version software painless. Java, Scala, and any other binary or compiled platform all work equally well with it.

Specifying alternatives in RPM dependencies

I've got a Java app that I am packaging as an RPM. Ideally I would like to specify Java as a dependency. I need to install in both Fedora and RHEL environments. The problem is RHEL Java is called 'java', while Fedora doesn't provide Oracle/Sun's distribution, leaving one to manually download from Oracle's website. Oracles distribution of Java is called either 'jre' or 'jdk' depending on which package you select.
Normally in a RPM SPEC file I would write:
Depends: java >= 1.6
But since the RHEL provides 'java', and Fedora via Sun/Oracle provides 'jre' or 'jdk' (and I can't use OpenJDK), I'm in a bit of a bind. Documentation so far hasn't shown a way to do 'java >= 1.6 || jre >= 1.6 || jdk >= 1.6' etc. Because the Java packages aren't under my control I can't just change one or the other to specify a 'Provides: Java'.
At present I see only two options:
Omit Java as a dependency
Create one RPM for Fedora, one for RHEL
I'm not keen on either option. Are there any other ways to achieve Java dependency where the providers all have different names?
Edit: A third option - create my own Java virtual package for Fedora that has a dependency on Sun's JDK RPM.
I've gone with creating my own java virtual package for Fedora that has a dependency on sun's jdk rpm.
Relevant portion of SPEC file in case it helps anyone else:
Name: fedora-virtual-java
Version: 1.6
Provides: java
Requires: jdk > 1.6

Categories

Resources