i want to run a java project in jenkins in mac.i have the following .sh file and its code is given below:
#!/bin/bash
echo $#
${jvmargs[#]}
DIR=$(dirname $0)
args=( "$#" )
javaProps=( )
server_jvmargs=( -Djava.awt.headless=true -Xms1024m -Xmx1024m"${jvmargs[#]}" )
XX_HOME="$DIR"
client_classpath="$XX_HOME/lib/others/*:$XX_HOME/lib/http/*:$XX_HOME/lib/selenium-java-2.37.0/*:$XX_HOME/lib/selenium-java-2.37.0/libs/*:$XX_HOME/lib/TestNG/*:$XX_HOME/lib/mailactivation/*:$XX_HOME/bin"
BIN_PATH="$XX_HOME/bin"
SRC_PATH="$XX_HOME/src"
rm -rfv "$BIN_PATH"
chmod 777 "$BIN_PATH"
mkdir -p "$BIN_PATH"
cd $DIR
javac \
-cp "$client_classpath" \
-d "$BIN_PATH" \
-sourcepath $SRC_PATH src/com/*.java
java \
"${server_jvmargs[#]}" \
"${javaProps[#]}" \
-Dxx.home="$XX_HOME" \
-Duser.dir="$XX_HOME" \
-cp "$client_classpath" \
org.testng.TestNG temp-testng-customsuite.xml
i set the custom workspace and use this run.sh file in build setup(Execute Shell). But it shows the following error:
Started by user Ali Azam JenkinTest
Building in workspace /Users/aliazam/Desktop/App/eclipse/workspace/Training
java.io.IOException: Failed to mkdirs: /Users/aliazam/Desktop/App/eclipse/workspace/Training
at hudson.FilePath.mkdirs(FilePath.java:1164)
at hudson.model.AbstractProject.checkout(AbstractProject.java:1268)
at hudson.model.AbstractBuild$AbstractBuildExecution.defaultCheckout(AbstractBuild. java:610)
at jenkins.scm.SCMCheckoutStrategy.checkout(SCMCheckoutStrategy.java:86)
at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:532)
at hudson.model.Run.execute(Run.java:1741)
at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
at hudson.model.ResourceController.execute(ResourceController.java:98)
at hudson.model.Executor.run(Executor.java:410)
Finished: FAILURE
can anyone please help me to solve this problem????
Related
Background
I'd like to update my JavaFX+Swing desktop application's build process to cross-compile installer-free native binaries for Linux, MacOS, Windows, and JVM targets. The project uses Warp-Packer and BellSoft's FULL version of Liberica OpenJDK 19 to generate a self-extracting, self-running executable for Windows and Linux. In effect, end users can start using the application as follows:
Download the binary.
Run the binary.
I'd like to switch from Warp-Packer to GraalVM for various technical reasons.
Problem
I've tried creating a binary using BellSoft's Native Image Kit, Oracle's GraalVM, and Gluon's GraalVM without success.
Environment
The build environment:
$ java -version
OpenJDK 64-Bit Server VM (build 19.0.1+11, mixed mode, sharing)
$ gradle --version
Gradle 7.6-rc-1
$ uname -a
Linux hostname 6.0.1-arch2-1 #1 SMP PREEMPT_DYNAMIC Thu, 13 Oct 2022 18:58:49 +0000 x86_64 GNU/Linux
Links to the exact versions of OpenJDK and Gradle being used:
https://download.bell-sw.com/java/19.0.1+11/bellsoft-jdk19.0.1+11-linux-amd64-full.tar.gz
https://services.gradle.org/distributions/gradle-7.6-rc-1-bin.zip
The GraalVMs:
BellSoft's Native Image Kit: https://download.bell-sw.com/vm/22.3.0/bellsoft-liberica-vm-full-openjdk17.0.5+8-22.3.0+2-linux-amd64.tar.gz
Oracle's GraalVM: https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-22.3.0/graalvm-ce-java19-linux-amd64-22.3.0.tar.gz
Gluon's GraalVM: https://github.com/gluonhq/graal/releases/download/gluon-22.1.0.1-Final/graalvm-svm-java17-linux-gluon-22.1.0.1-Final.tar.gz
Note that the application's build.gradle file targets JDK 17:
java {
sourceCompatibility = VERSION_17
targetCompatibility = VERSION_17
}
Further, the application targets JavaFX 19, which could be a problem:
javafx {
version = '19'
modules = ['javafx.controls', 'javafx.swing']
configuration = 'compileOnly'
}
Build
This section provides the complete steps to reproduce the problems I've encountered with each GraalVM implementation.
Native Image Kit
NIK fails due to a bug:
cd /tmp
wget https://download.bell-sw.com/vm/22.3.0/bellsoft-liberica-vm-openjdk17.0.5+8-22.3.0+2-src.tar.gz
mkdir nik
cd nik
tar xf ../bell*gz
grep -n InteropFactoryN graal/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/javafx/JavaFXReflection.java
This shows:
243: "com.sun.javafx.embed.swing.newimpl.InteropFactoryN",
In full context:
static void registerSwing(DuringAnalysisAccess access) {
registerReflectionClasses(access,
"com.sun.javafx.embed.swing.SwingFXUtilsImpl",
"com.sun.javafx.embed.swing.newimpl.InteropFactoryN",
"javafx.embed.swing.SwingNode",
"jdk.swing.interop.LightweightFrameWrapper");
}
If any reflected class doesn't exist, NIK terminates with an error. For example:
Fatal error: org.graalvm.compiler.debug.GraalError: com.oracle.svm.core.util.VMError$HostedError: class com.sun.javafx.embed.swing.newimpl.InteropFactoryN not found
The InteropFactoryN class was removed sometime between javafx-swing 11.0.2 and 12.0.2:
https://repo1.maven.org/maven2/org/openjfx/javafx-swing/11.0.2/javafx-swing-11.0.2-sources.jar
https://repo1.maven.org/maven2/org/openjfx/javafx-swing/12.0.2/javafx-swing-12.0.2-sources.jar
https://repo1.maven.org/maven2/org/openjfx/javafx-swing/17.0.2/javafx-swing-17.0.2-sources.jar
Verified using:
$ jar -tvf javafx-swing-12.0.2-sources.jar | grep FactoryN
$ jar -tvf javafx-swing-17.0.2-sources.jar | grep FactoryN
$ jar -tvf javafx-swing-11.0.2-sources.jar | grep FactoryN
2166 Wed Jan 16 10:19:04 PST 2019 com/sun/javafx/embed/swing/newimpl/InteropFactoryN.java
NIK is built upon OpenJDK 17, and the above confirms that the class was removed and not re-instated. Complete instructions to replicate the bug (Java and Gradle must be installed and available via the PATH):
cd /tmp
git clone https://github.com/DaveJarvis/keenwrite
cd keenwrite
gradle jar
mkdir -p src/main/resources/META-INF/native-image
wget "https://download.bell-sw.com/vm/22.3.0/bellsoft-liberica-vm-full-openjdk17.0.5+8-22.3.0+2-linux-amd64.tar.gz"
tar xf *gz
rm *gz
mv bell* nik
export LD_LIBRARY_PATH="$(pwd)/nik/lib:$LD_LIBRARY_PATH"
# Run the app and use many options.
java \
-agentlib:native-image-agent=config-output-dir=src/main/resources/META-INF/native-image \
--add-opens=javafx.controls/javafx.scene.control=ALL-UNNAMED \
--add-opens=javafx.controls/javafx.scene.control.skin=ALL-UNNAMED \
--add-opens=javafx.graphics/javafx.scene.text=ALL-UNNAMED \
--add-opens=javafx.graphics/com.sun.javafx.css=ALL-UNNAMED \
--add-opens=javafx.graphics/com.sun.javafx.text=ALL-UNNAMED \
--add-exports=javafx.base/com.sun.javafx.event=ALL-UNNAMED \
--add-exports=javafx.graphics/com.sun.javafx.application=ALL-UNNAMED \
--add-exports=javafx.graphics/com.sun.javafx.geom=ALL-UNNAMED \
--add-exports=javafx.graphics/com.sun.javafx.text=ALL-UNNAMED \
--add-exports=javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED \
--add-exports=javafx.graphics/com.sun.javafx.scene.text=ALL-UNNAMED \
--add-exports=javafx.graphics/com.sun.javafx.scene.traversal=ALL-UNNAMED \
-jar build/libs/keenwrite.jar $#
# Exit the app when most of the features have been exercised.
# Fails due to missing reflective class, InteropFactoryN.
./nik/bin/native-image \
--add-modules=javafx.controls,javafx.swing \
--verbose \
-H:+ReportExceptionStackTraces \
--no-fallback \
--report-unsupported-elements-at-runtime \
-Djava.awt.headless=false \
-cp src/main/resources/META-INF/native-image \
-jar build/libs/keenwrite.jar
Gluon
Gluon fails because the JavaFX modules cannot be found. Here are the build instructions:
cd /tmp
git clone https://github.com/DaveJarvis/keenwrite
cd keenwrite
gradle clean jar
mkdir -p src/main/resources/META-INF/native-image
wget "https://github.com/gluonhq/graal/releases/download/gluon-22.1.0.1-Final/graalvm-svm-java17-linux-gluon-22.1.0.1-Final.tar.gz"
tar xf *gz
rm *gz
mv graalvm* graalvm
export LD_LIBRARY_PATH="$(pwd)/graalvm/lib:$LD_LIBRARY_PATH"
java \
-agentlib:native-image-agent=config-output-dir=src/main/resources/META-INF/native-image \
--add-opens=javafx.controls/javafx.scene.control=ALL-UNNAMED \
--add-opens=javafx.controls/javafx.scene.control.skin=ALL-UNNAMED \
--add-opens=javafx.graphics/javafx.scene.text=ALL-UNNAMED \
--add-opens=javafx.graphics/com.sun.javafx.css=ALL-UNNAMED \
--add-opens=javafx.graphics/com.sun.javafx.text=ALL-UNNAMED \
--add-exports=javafx.base/com.sun.javafx.event=ALL-UNNAMED \
--add-exports=javafx.graphics/com.sun.javafx.application=ALL-UNNAMED \
--add-exports=javafx.graphics/com.sun.javafx.geom=ALL-UNNAMED \
--add-exports=javafx.graphics/com.sun.javafx.text=ALL-UNNAMED \
--add-exports=javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED \
--add-exports=javafx.graphics/com.sun.javafx.scene.text=ALL-UNNAMED \
--add-exports=javafx.graphics/com.sun.javafx.scene.traversal=ALL-UNNAMED \
-jar build/libs/keenwrite.jar $#
./graalvm/bin/native-image \
--verbose \
-H:+ReportExceptionStackTraces \
--no-fallback \
--report-unsupported-elements-at-runtime \
-Djava.awt.headless=false \
-cp src/main/resources/META-INF/native-image \
-jar build/libs/keenwrite.jar
This fails because GraalVM cannot find JavaFX and Swing. I tried a variety of ways to instruct native-image where to find the JavaFX modules, including:
--module-path /opt/jdk/jmods/ --add-modules=javafx.controls,javafx.swing
I've also downloaded both the JavaFX 19 SDK and the JavaFX 19 jmods and tried using them, such as:
--module-path $(pwd)/javafx-sdk-19 --add-modules=...
--module-path $(pwd)/javafx-jmods-19 --add-modules=...
Neither of those approaches worked.
Oracle
Using the regular GraalVM failed well before any JavaFX issues would be encountered:
cd /tmp
git clone https://github.com/DaveJarvis/keenwrite
cd keenwrite
gradle jar
wget https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-22.3.0/graalvm-ce-java19-linux-amd64-22.3.0.tar.gz
tar xf graalvm*
rm *gz
mv graalvm* graalvm
./graalvm/bin/gu install native-image
./graalvm/bin/native-image \
--verbose \
-H:+ReportExceptionStackTraces \
--no-fallback \
--report-unsupported-elements-at-runtime \
-Djava.awt.headless=false \
-jar build/libs/keenwrite.jar
This results in the following error:
Fatal error: java.lang.RuntimeException: There was an error linking the native image: Linker command exited with 1
I think the error is caused by:
/usr/bin/ld: /tmp/keenwrite/graalvm/lib/static/linux-amd64/glibc/libawt.a(awt_LoadLibrary.o):(.bss.jvm+0x0): multiple definition of `jvm'; /tmp/keenwrite/graalvm/lib/static/linux-amd64/glibc/libawt_xawt.a(XlibWrapper.o):(.bss.jvm+0x0): first defined here
The full log is at:
https://textdoc.co/kweRFKOHDCV9ZE3A
Supplementary build process details are described on my blog.
Question
How do you cross-compile a JavaFX+Swing application using GraalVM to create a native Linux executable on Linux? More specifically, what steps do I need to run to build a native binary for my application using GraalVM?
Bounty
For some reason StackOverflow didn't update the bounty text. Here's the criteria for awarding:
The answer must provide the exact and complete set of commands to run that will produce a native executable on Linux. Further, the binary must be able to open and render an R Markdown file in the GUI as well as export the file to a PDF. That is, no functionality is lost. The resources and resource bundles don't have to work, but it'd be great if they did.
With the latest releases of Spring Boot 2.3.0, spring-graalvm-native 0.7.0.BUILD-SNAPSHOT, GraalVM 20.1.0.r11 and the corresponding blog posts
https://spring.io/blog/2020/04/16/spring-tips-the-graalvm-native-image-builder-feature
https://blog.codecentric.de/en/2020/05/spring-boot-graalvm
I also started to play around with one of my apps.
Luckily I was able to compile my app without any big hurdles. My compile.sh script looks as follows
#!/usr/bin/env bash
echo "[-->] Detect artifactId from pom.xml"
ARTIFACT=$(mvn -q \
-Dexec.executable=echo \
-Dexec.args='${project.artifactId}' \
--non-recursive \
exec:exec);
echo "artifactId is '$ARTIFACT'"
echo "[-->] Detect artifact version from pom.xml"
VERSION=$(mvn -q \
-Dexec.executable=echo \
-Dexec.args='${project.version}' \
--non-recursive \
exec:exec);
echo "artifact version is '$VERSION'"
echo "[-->] Detect Spring Boot Main class ('start-class') from pom.xml"
MAINCLASS=$(mvn -q \
-Dexec.executable=echo \
-Dexec.args='${start-class}' \
--non-recursive \
exec:exec);
echo "Spring Boot Main class ('start-class') is '$MAINCLASS'"
GREEN='\033[0;32m'
RED='\033[0;31m'
NC='\033[0m'
echo "[-->] Cleaning target directory & creating new one"
rm -rf target
mkdir -p target/native-image
echo "Packaging $ARTIFACT with Maven"
mvn -ntp package > target/native-image/output.txt
echo "[-->] Expanding the Spring Boot fat jar"
JAR="$ARTIFACT-$VERSION.jar"
rm -f $ARTIFACT
echo "Unpacking $JAR"
cd target/native-image
jar -xvf ../$JAR >/dev/null 2>&1
cp -R META-INF BOOT-INF/classes
LIBPATH=`find BOOT-INF/lib | tr '\n' ':'`
CP=BOOT-INF/classes:$LIBPATH
GRAALVM_VERSION=`native-image --version`
echo "Compiling $ARTIFACT with $GRAALVM_VERSION"
{ time native-image \
--verbose \
--no-server \
--no-fallback \
--enable-all-security-services \
-H:Name=$ARTIFACT \
-Dspring.native.remove-unused-autoconfig=true \
-Dspring.native.remove-yaml-support=true \
-Dspring.native.remove-xml-support=true \
-Dspring.native.remove-spel-support=true \
-Dspring.native.remove-jmx-support=true \
-cp $CP $MAINCLASS >> output.txt ; } 2>> output.txt
if [[ -f $ARTIFACT ]]
then
printf "${GREEN}SUCCESS${NC}\n"
mv ./$ARTIFACT ..
exit 0
else
cat output.txt
printf "${RED}FAILURE${NC}: an error occurred when compiling the native-image.\n"
exit 1
fi
But now my troubles start: My app relies on some CSVs during startup to load data.
The data is loaded like this
InputStream is = CSVUtil.class.getResourceAsStream("/myData.csv");
The file is present at /src/main/resources/myData.csv
As said the compilation works without an issue but once I start the app it can't find the CSV.
Caused by: java.lang.NullPointerException: null
at java.io.Reader.<init>(Reader.java:167) ~[na:na]
at java.io.InputStreamReader.<init>(InputStreamReader.java:113) ~[na:na]
at ch.aaap.raw.CSVUtil.getData(CSVUtil.java:33) ~[na:na]
...
It seems that it's not part of the compilation. Any hints how I can make the native-image command aware about the fact that I need these CSVs?
Looks like adding following argument helps
-H:IncludeResources='.*/*.csv$'
I am containerizing a component. It requires Linux + Python and Java.
Linux + Python - I am using Alpine 3.5 & Python 3.5 image.
Here is my Docker file.
Dockerfile:
#
# Health Monitoring Docker File
#
#ARG JAVA_BASE=1.0
#FROM csf-docker-delivered.repo.lab.pl.alcatel-lucent.com/java_base:17.6-1
#WORKDIR /etc/alternatives
#RUN CGO_ENABLED=0
FROM registry1-docker-io.repo.lab.pl.alcatel-lucent.com/python:3.5-alpine
#COPY --from=build /etc/alternatives/* .
#RUN rm -rf /var/cache/apk/* && \
# rm -rf /tmp/*
#
#RUN apk update
#
#RUN apk add --update --no-cache\
# build-base \
# openjdk8-jre \
# && pip install virtualenv \
# && rm -rf /var/cache/apk/*
#RUN apk update && apk upgrade && \
# apk add openjdk8 && \
# mkdir /tmp/tmprt && \
# cd /tmp/tmprt && \
# apk add zip && \
# unzip -q /usr/lib/jvm/default-jvm/jre/lib/rt.jar && \
# apk add zip && \
# zip -q -r /tmp/rt.zip . && \
# apk del zip && \
# cd /tmp && \
# mv rt.zip /usr/lib/jvm/default-jvm/jre/lib/rt.jar && \
# rm -rf /tmp/tmprt /var/cache/apk/* bin/jjs bin/keytool bin/orbd bin/pack200 bin/policytool \
# bin/rmid bin/rmiregistry bin/servertool bin/tnameserv bin/unpack200
COPY ./jdk-8u201-linux-x64.tar.gz /
RUN tar xf /jdk-8u201-linux-x64.tar.gz
ENV JAVA_HOME=/jdk1.8.0_201/bin
ENV NGDB_HOME /opt/nsn/ngdb
#RUN yum -y install openjdk-8-jdk-headless
#RUN apt-get install openjdk-8-jdk-headless
#COPY ./openjdk-8_8u181-b13.orig.tar.gz /
#RUN tar xf /openjdk-8_8u181-b13.orig.tar.gz
RUN mkdir -p /opt/nsn/ngdb/monitoring/scripts
RUN mkdir -p /opt/nsn/ngdb/monitoring/utils
RUN mkdir -p /var/local/monitoring/output
RUN mkdir -p /var/local/monitoring/work
RUN for directory in boundaryStatus postgresUsersCount backlogHadoop tableCount_Usage Dimension_Count tableCount_Day tableCount_Week tableCount_Month sendSummaryReport; do mkdir -p $directory;done
COPY ./utils/* /opt/nsn/ngdb/monitoring/utils/
COPY ./scripts/* /opt/nsn/ngdb/monitoring/scripts/
COPY ./conf/* /opt/nsn/ngdb/monitoring/conf/
COPY ./postgresql-9.2-1004.jdbc4.jar /opt/nsn/ngdb/monitoring/utils/
RUN mkdir -p /opt/nsn/ngdb/monitoring/python-dependencies
COPY ./html3-1.17.tar.gz /opt/nsn/ngdb/monitoring/python-dependencies
COPY ./py4j-0.10.8.1.zip /opt/nsn/ngdb/monitoring/python-dependencies
#RUN tar xf /opt/nsn/ngdb/monitoring/python-dependencies/html3-1.17.tar.gz
#WORKDIR /html3-1.17/
#RUN python /html3-1.17/setup.py install
RUN unzip /opt/nsn/ngdb/monitoring/python-dependencies/py4j-0.10.8.1.zip
WORKDIR /py4j-0.10.8.1
RUN python /py4j-0.10.8.1/setup.py install
But if i try to add Java Image & Python Alpine Image using "FROM", I am able to get only one thing in my container.
When i searched, i came across Multi stage builds, but when i did like below it is throwing a error "Unknown flag: from"
FROM csf-docker-delivered.repo.lab.pl.alcatel-lucent.com/java_base:17.6-1
WORKDIR /etc/alternatives
FROM registry1-docker-io.repo.lab.pl.alcatel-lucent.com/python:3.5-alpine
COPY --from=0 /etc/alternatives/* .
Can some one please help me out?
And addition to this,
I am trying to install py4j as a external module through which i am calling java classes.
i have set WORKDIR and then installation of py4j module goes smooth.
Later if i try to set WORKDIR to other module ex: html, and when i try
RUN python setup.py install
It gives error stating "No Such file or Directory"
Can you please help on this?
I am running jenkins blue ocean image. I want to pass startTLS option for jenkins like-
JAVA_ARGS="-Djava.awt.headless=true -Dmail.smtp.starttls.enable=true".
For that I need to edit jenkins conf file. Failed searching at the following locations-
/etc/defaults/jenkins and /etc/sysconfig/jenkins , also, tried searching wildcard like find / -iname jenkins, but no luck.
Run jenkins image as-
$ docker run \
--rm \
-u root \
-p 8080:8080 \
-v jenkins-data:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-v "$HOME":/home \
jenkinsci/blueocean
$ docker exec -it <image_id> bash
Does anyone knows how to edit jenkins conf file here? please let me know if some more information is needed.
If you look at the documentation for docker image jenkins/jenkins which is what jenkinsci/blueocean is deriving from. You can add those options through a JAVA_OPTS environment variable. So you would do:
$ docker run \
--rm \
-u root \
-p 8080:8080 \
-v jenkins-data:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-v "$HOME":/home \
-e JAVA_OPTS="-Djava.awt.headless=true -Dmail.smtp.starttls.enable=true"
jenkinsci/blueocean
Here is a link:
https://github.com/jenkinsci/docker/blob/master/README.md
We have our own build system for android for a multitude of reason. We currently build the apk with aapt. Problem is now there is a dependency to a jar file that contains custom resources. For example the jar file looks like this:
/META-INF
/foo.properties
/my_custom_dir/
/i_hate_my_life/
using the following command :
aapt p --auto-add-overlay -f \
-M src/main/AndroidManifest.xml \
-I $(ANDROID_HOME)/platforms/android-19/android.jar \
-S src/main/res/ \
-S $(ANDROID_HOME)/extras/android/support/v7/appcompat/res/ \
-S $(ANDROID_HOME)/extras/google/google_play_services/libproject/google-play-services_lib/res/ \
-F bin/SampleApp.unaligned 1>/dev/null
totally ignores those extra directories and my app crashes well because that jar needs those little buggers.
I've tried the -j switch and that only includes the classes. Anyone have a clue other than to write a custom script or unzip the third party jar and use appt add (barf)?
Before you say use ant or gradle...it's not an option!
UPDATE:
For now I have this nastyness in my Makefile and it's working...
#mkdir -p bin/tmp/
#for i in $(JARS_MIN); do\
cp $$i bin/tmp/; \
done;
#cd bin/tmp/; \
for i in `ls`; do\
unzip -o $$i; \
rm $$i; \
rm -rf META-INF/; \
rm -rf com/; \
rm -rf org/; \
rm -rf android/; \
rm -rf edu/; \
rm -rf javax/; \
rm -rf net/; \
done;
cd bin/tmp/; zip -g -r ../SampleApp.unaligned *