Is it possible to use jlink for cross compilation (bundling) application for different operating systems? [duplicate] - java-9

I created runtime image using jlink on my Linux machine. And I see linux folder under the include folder. Does it mean that I can use this runtime image only for Linux platform? If yes, are there any ways to create runtime images on one platform for another (e.g. on Linux for Windows and vice versa)

The include directory is for header files, such as jni.h, that are needed when compiling C/C++ code that uses JNI and other native interfaces. It's nothing to do with jlink.
The jlink tool can create a run-time image for another platform (cross targeting). You need to download two JDKs to do this. One for the platform where you run jlink, the other for the target platform. Run jlink with --module-path $TARGET/jmods where $TARGET is the directory where you've unzipped the JDK for the target platform.

Being generally unable to add anything to Alan Bateman's answers in terms of information, I'll offer a working example. This example illustrates using jlink on Mac OS and then running the binary on Ubuntu in a Docker container.
The salient points are as follows.
Given two simple modules, we compile on Mac OS:
javac -d build/modules \
--module-source-path src \
`find src -name "*.java"`
jar --create --file=lib/net.codetojoy.db#1.0.jar \
-C build/modules/net.codetojoy.db .
jar --create --file=lib/net.codetojoy.service#1.0.jar \
-C build/modules/net.codetojoy.service .
Assuming that the Linux 64 JDK is unpacked in a local directory (specified as command-line arg), we call jlink (on Mac OS in this example). JAVA_HOME is the crux of the solution:
# $1 is ./jdk9_linux_64/jdk-9.0.1
JAVA_HOME=$1
rm -rf serviceapp
jlink --module-path $JAVA_HOME/jmods:build/modules \
--add-modules net.codetojoy.service \
--output serviceapp
Then, assuming we've pulled the ubuntu image for Docker, we can execute the following in a Docker terminal (i.e. Linux):
docker run --rm -v $(pwd):/data ubuntu /data/serviceapp/bin/java net.codetojoy.service.impl.UserServiceImpl
TRACER : hello from UserServiceImpl
To re-iterate this feature of Java 9/jlink: Linux does not have Java installed and the Linux binary was built on Mac OS.

Related

How can i build a real relocatable SDK with Pre-Built/Installed Crosstool-NG toolchain via buildroot in a docker container?

Setup:
Host : Ubuntu 20.04 Docker container
WorkspacePath : /workspace
External ToolChain : Pre-Built and installed at /workspace/crosstool_ng/arm-**
BuildSystem : BuildRoot at /workspace/buildroot
BuildrootOutput : /workspace/buildroot/images/*
With above setup am trying to build BSP(make) and SDK(make sdk) in my docker container. Everything goes well,
but make sdk generates a tarball conaining sysroot and toolchain and that toolchain is still pointing symbolic link to fix/absolute path that docker conainer starting from /workspace/**.
If I take that tarball and move to host or any other PC then it will not work. We have that relocate_sdk.sh script but that's not helping me also.
Workaround:
If I buld my SDK directly on host then this fix path will be still there so it works but that i dont want.I want a relocatable sdk that i can give to anyone.
Can someone help me with this issue (specially it needs to be built under docker)

How to add go-cross to Yocto SDK? Or otherwise compile Go for Yocto on other machines?

I have been using the Yocto SDK to compile C and C++ code for Yocto so that every machine does not need the 150GB+ Bitbake environment. Yocto version is 2.4 (Rocko)
Now I would like to have the same functionality for Golang, but I can't figure out how to do it.
If I'm on the Bitbake machine, I can call the binary arm-arch-gnueabi-go binary found under the directory tmp/work/x86_64-linux/go-cross-arm/ to compile code. But if I copy those binaries to another machine, it links to libraries with hard-coded paths on the Bitbake machine so that won't work.
Is there a way to include arm-arch-gnueabi-go in the SDK when I run populate_sdk on the image? Or is there another easy way to compile Go for the target on other machines?
You can add the following lines in local.conf file or image recipe:
TOOLCHAIN_HOST_TASK_append = " \
packagegroup-go-cross-canadian-${MACHINE} \
"
TOOLCHAIN_TARGET_TASK_append = " \
${#multilib_pkg_extend(d, 'packagegroup-go-sdk-target')} \
"

How to generate an executable of a modular Java app with javapackager?

Environment: Win10, Oracle JDK 9, Eclipse, jlink, javapackager
Context: I'm trying to generate an executable file with javapackager
having a java custom runtime image made with jlink, reading the javapackager documentation. Not an installable.
Jlink created a zip file, containing all my java class files and resources encapsulated (it means I don't have access to them from System Explorer) + the custom jre. It comes with a .bat launcher to run the app. All works fine.
Walkthrow: 1st I found out that there is a jpackage utility of OpenJDK available from OpenJDK14 to make java modular app executable, which is stil under development. I didn't find any way to work with that.
Later I investigated Inno Setup, but it doesn't fulfil my needs (because I didn't want an installer)
Later I discovered that since Oracle JDK 8 there is javapackager tool to generate runnables for each plattform (max, linux, windows..).
I'm not able to make javapackager work.
This is one of various attempts of the command I executed on Windows cmd.
javapackager
-deploy
-native exe
--add-modules myModule,javafx.graphics,javafx.controls
--module-path "C:\path\to\javafx-jmods;C:\path\to\target\classes;C:\path\to\more\jmods"
-outdir "C:\myApp"
-outfile MyApp
-appclass myPackage.MyApp
-name "MyApp"
With the previous command I get the error:
Error: No application jars foun
So, I realized I was mixing the -deploy command and its options with the -createjar command and its options.
Can someone explain how to generate a .exe with javapackager?
Edit 1
Tried jpackage (using jdk 14 with Wix installer needed as dependency):
jpackage --package-type exe -o outputdir --name myApp --add-modules myapp,javafx.graphics,javafx.controls
--module-path "C:\path\to\some\jmods;C:\path\to\myTarget;C:\path\to\javafx-sdk-11.0.2plugin" -m myapp/App
Output: myApp.1.0.exe. It opens a cmd and a "installer", but does not executes myApp as there is not the custom java runtime environment included.
Install the JDK provided with jpackage like any JDK and set your JAVA_HOME to it.
As a preparation for the packaging I have instructed Maven to copy all dependent jar files of the project into the installer/input folder.
Then go to the main folder of your project and call
$JAVA_HOME/bin/jpackage \
--name yourAppName \
--output installer/output \
--input installer/input \
--main-jar yourAppMain.jar \
--main-class xxx.yyy.yourAppMainClass
The result should now be in the installer/output folder.
For more detailed information about the options you can call
$JAVA_HOME/bin/jpackage --help
There is also an option to use a different JDK with the jpackager but this is more advanced.
If your project is build using Gradle then you can easly use the Badass jlink plugin: https://github.com/beryx/badass-jlink-plugin
to build an installer / package using jpackage
Here's an artilce how to build an app image using OpenJDK 11 and using OpenJDK 14 with jpackage only for building the installer / package:
https://walczak.it/blog/distributing-javafx-desktop-applications-without-requiring-jvm-using-jlink-and-jpackage

Link Dynamic library to Netbeans Platform Project

Sorry if this is a beginner question but I am trying to solve this for many hours without success.
I have a problem getting a platform netbeans project (contains number of modules suits) to run in Ubuntu or Mac.
In Ubuntu 18.04, if I run the project from launcher it raises an error related to a missing dynamic library. I tried to add the missing library path to the system e.g. .bashrc but this solve the problem partly. The project now runs only if I start netbeans from the terminal.
I tried to add the path globally e.g. in /etc/ld.so.conf.d but this does not work.
Same error happens in Mac OS but starting netbeans from the terminal does not solve the problem.
It same netbeans platform project does not have properties or option to add dynamic library e.g. .so file.
Here is what works for me:
In Ubuntu: soft link the libraries to the system lib folder e.g.
for a in \myprojectdeps\lib* ; do sudo ln -s \myprojectdeps\lib/$a /usr/lib/$a ;done
In Mac: soft link the libraries to the user Java lib folder
for a in \myprojectdeps\lib* ; do ln -s \myprojectdeps\lib/$a ~/Library/Java/Extensions/$a ;done

Gradle build fails in jenkins:alpine container: UnsatisfiedLinkError: linux-amd64/libnative-platform.so: libstdc++.so.6:

Recently I started using Jenkins in a Docker container with Oracle Java 8. When building a project with Gradle I get this error message:
UnsatisfiedLinkError: linux-amd64/libnative-platform.so: libstdc++.so.6: cannot open shared object file: No such file or directory
In Jenkins I selected "Force GRADLE_USER_HOME to use workspace" with no luck at all. The file libnative-platform.so is in the directory expected but gradle won't work. I tried installing Gradle in the container and same result. My last setup is with Gradle Wrapper.
I looked everywhere but I had no luck on my quest. I appreciate if someone can shed a light on this.
You can make this work by installing the libstdc++ package in Alpine
apk add --no-cache libstdc++
libstdc++.so.6: cannot open shared object file
libnative-platform.so of the JRE/JDK is linked against gnu libc but Alpine images are based on musl libc.
The easy solution is to use a glibc based docker image like Debian, if you want to stick with Alpine you might find some clues in this github issue.
The problem is that Oracle JDK is linked against GNU C library (glibc) that is not available here.
Alpine Linux doesn’t use glibc as conventional distributions like Debian, Fedora or Gentoo. Instead, it uses musl libc, a lightweight, fast, simple and standards-conform C library (i.e. everything that glibc is not).
The solution is very simple, just install OpenJDK from the Alpine repository (package openjdk8). Don’t worry about compatibility, Oracle JDK 8 is just branded distribution of OpenJDK 8, the code base is nearly identical.
If you insist on Oracle JDK for whatever reason and don’t care about security at all*, then don’t use Alpine Linux, but some conventional distribution…
You can read more in my article JRuby on Alpine Linux on the JRuby wiki.
* Oracle JDK has restricted cryptography by default, because of U.S. policy. It’s distributed with Ask.com adware. And because it’s distributed only as a BLOB, you can’t know what else bad is inside…

Resources