javafx self-contained package - javafx-2

I created the javafx standalone application using netbeans by copying the following snippet into build.xml file
<target name ="-post-jfx-deploy">
<fx:deploy width="${javafx.run.width}" height="${javafx.run.height}"
nativeBundles="all"
outdir="${basedir}/${dist.dir}" outfile="${application.title}">
<fx:application name="${application.title}" mainClass="${javafx.main.class}"/>
<fx:resources>
<fx:fileset dir="${basedir}/${dist.dir}" includes="*.jar"/>
</fx:resources>
<fx:info title="${application.title}" vendor="${application.vendor}"/>
</fx:deploy>
</target>
I had jdk environment for x64 bit version so it created application that runs in only x64 bit version of windows or operating systems. Can anyone tell how should I change the deploy method to make application runnable on x86 bit systems. By default netbeans took up 64bit version of jdk environment

You could combine Maven with Ant on the following way:
Defining a Maven artifact for JDK
Using maven-dependency-plugin
Using unzip Ant task
Using <fx:platform>
Defining Maven artifact for JDK
Defining Maven artifacts for JDK x86 and JDK x64. It may sounds weird at first time, but thinking in a continuous integration environment, it makes sense at all.
You just zip an ordinary JDK folder and deploy it as a Maven artifact.
Then your Maven project will depend on:
<properties>
<jdk.version>1.8.112</jdk.version>
<!-- can be '64' or '32' -->
<cpu.arch>64</cpu.arch>
</properties>
</dependencies>
<!-- other dependencies goes here -->
<dependency>
<groupId>com.my.company</groupId>
<artifactId>jre-linux-${cpu.arch}</artifactId>
<version>${jre.version}</version>
<type>zip</type>
<scope>runtime</scope>
</dependency>
</dependencies>
Note: I'm running on Debian, but it's totally applicable to Windows environment too.
Using maven-dependency-plugin
Add the maven-dependency-plugin. It will copy all your dependencies (includind your JDK zip file defined on dependencies section) to the /target/dist/lib folder.
We'll use it soon.
The plugin configuration looks like:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>install</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<includeScope>runtime</includeScope>
<outputDirectory>${application.dist}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
Using unzip Ant task
Now before your JavaFX Ant tasks, you must tell Ant to extract your JDK dependency into a folder.
It must be set BEFORE the task who will bundle your JavaFX application.
<unzip src="${application.dist}/lib/jdk-linux-${cpu.arch}-${jdk.version}.zip"
dest="${extra.dir}/jdk"/>
Using <fx:platform>
And finally, at your <fx:deploy> tag you must add a <fx:platform> child tag, adding the basedir attribute as your previous jdk folder, like:
<fx:deploy ...>
<fx:platform javafx="8.0+" basedir="${extra.dir}/jdk" />
</fx:deploy>
The Maven logs will be similar to this:
[INFO] --- maven-antrun-plugin:1.7:run (default) # my-app ---
[INFO] Executing tasks
main:
[unzip] Expanding: /home/danilo/development/temp/my-app/target/dist/lib/jdk-linux-64-1.8.112.zip into /home/danilo/development/temp/my-app/target/extras/jdk
Using base JDK at: /home/danilo/development/temp/my-app/target/extras/jdk/jre
Using base JDK at: /home/danilo/development/temp/my-app/target/extras/jdk/jre
Creating app bundle: /home/danilo/development/temp/my-app/target/dist/bundles/my-app
Debian packages should specify a license. The absence of a license will cause some linux distributions to complain about the quality of the application.
Using default package resource [menu icon] (add package/linux/my-app.png to the class path to customize)
Using default package resource [Menu shortcut descriptor] (add package/linux/my-app.desktop to the class path to customize)
Using default package resource [DEB control file] (add package/linux/control to the class path to customize)
Using default package resource [DEB preinstall script] (add package/linux/preinst to the class path to customize)
Using default package resource [DEB prerm script] (add package/linux/prerm to the class path to customize)
Using default package resource [DEB postinstall script] (add package/linux/postinst to the class path to customize)
Using default package resource [DEB postrm script] (add package/linux/postrm to the class path to customize)
Using custom package resource [DEB copyright file] (loaded from package/linux/copyright)
dpkg-deb: construindo pacote 'my-app' em '/home/danilo/development/temp/my-app/target/dist/bundles/my-app-1.0.deb'.
Package (.deb) saved to: /home/danilo/development/temp/my-app/target/dist/bundles/my-app-1.0.deb
Config files are saved to /tmp/fxbundler8773603423891700338/linux. Use them to customize package.
Bundler RPM Bundle skipped because of a configuration problem: Can not find rpmbuild {0} or newer.
Advice to fix: Install packages needed to build RPM, version {0} or newer.
[INFO] Executed tasks
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8:34.875s
[INFO] Final Memory: 22M/253M
[INFO] ------------------------------------------------------------------------
Conclusion
When you need to deliver your application on a x86 environment, just override the cpu.arch Maven property at build time:
mvn -Dcpu.arch=32 clean install
Now it's easier to set up your continuous integration. If you would use Jenkins CI, for example, you can create 2 different jobs and run it as needed.
I pushed the whole project to a Github repository. You can check it here: https://github.com/daniloguimaraes/javafx-multiple-jre-versions

Related

Spring Boot build-image with Npm installed

I want to achieve the following: Packaging my Spring-Boot app into a Dockerimage where i can call a npx command in order to call a 3rd Party Node Library which i need in my App.
My Pom looks like this:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build-image</goal>
</goals>
</execution>
</executions>
<configuration>
<image>
<name>my-app</name>
<buildpacks>
<buildpack>gcr.io/paketo-buildpacks/nodejs</buildpack>
<buildpack>gcr.io/paketo-buildpacks/java</buildpack>
</buildpacks>
</image>
</configuration>
</plugin>
</plugins>
</build>
Now with mvn package the plugin will be executed, but first:
it will fail with an error:
Invalid response received when loading image
"pack.local/builder/ayvwrfbvbm:latest"
However if i start the whole thing via pack the Image gets created
pack build my-app --builder paketobuildpacks/builder:base --buildpack paketo-buildpacks/nodejs --buildpack paketo-buildpacks/java
But in the created image i can not call node, nor npm nor npx, since it seems these layers are not added there.
If i then add a package.json and a server.js to my App-Root it seems that the npm-install layer is added but still i can not call node nor npm nor npx from within my container.
Please someone can show me a way how to create an image that runs a spring-boot app which then can call a 3rd party npm cli via
Runtime.getRuntime().exec("npx my3rdParty-cli");
A few notes.
When you add two buildpacks like --buildpack paketo-buildpacks/nodejs --buildpack paketo-buildpacks/java, it doesn't mean they will both run. Both will examine your code and determine if they can run, what is called the detection process, but ultimately only one of the two buildpack groups you've set will get picked to build your application.
When you run the build at the top, it'll print a list of the buildpacks selected to execute, so you can see exactly what's executing.
===> DETECTING
6 of 24 buildpacks participating
paketo-buildpacks/ca-certificates 3.2.4
paketo-buildpacks/bellsoft-liberica 9.4.0
paketo-buildpacks/syft 1.13.0
paketo-buildpacks/executable-jar 6.2.4
paketo-buildpacks/dist-zip 5.2.4
paketo-buildpacks/spring-boot 5.13.0
...
Right now, the Node.js buildpack and Java buildpacks are separate, so you'll either get one or the other. This is why it runs Java by default, but if you add a package.json file it runs Node.js. They are independent of each other.
There is an open issue to add Node.js into the Java buildpack group so that use cases like this can be supported.
If you are trying to use Node.js/NPM at build time, you can do something like in the demo here where you use a Maven plugin to install Node.js. It'll then be available if you need to perhaps build a front-end and bundle it with your Java app.
If you actually need Node.js/NPM at runtime, that's a trickier problem. 3.) isn't going to do that. You need something that would install Node.js into the actual runtime container. Having the support from 2.) would do that, but in the meantime, there are some options available. In particular, option 4.) from that link. You can use the apt-buildpack to install Node.js and then call out to it from your Java app.

eclipse ear project error "the deployment descriptor of the module cannot be loaded or found"

When importing a fully working maven ear project to eclipse I get a validation error for each included module. The messages all say:
The deployment descriptor of the module XXX cannot be loaded or found.
The project can be built successfully from the command line and the packaged EAR deploys perfectly.
The issue seems to be related to the way the wtp-m2e plugin loads the maven-ear-plugin configuration. It does not take the default EAR version into account and sets the project EAR facet version to 1.3.
The solution is to include the version explicitely in the maven -ear-plugin configuration.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<configuration>
<version>7</version>
</configuration>
</plugin>

How to include the spark-examples.jar as a dependency within a maven/sbt project?

The spark-examples.jar is apparently not published to maven. That is a complication when attempting to build atop those classes in an maven /sbt project.
Further compounding this problem is that it seems that mvn install were set up to skip when going through the process of downloading spark, building from source, and installing locally:
mvn -pl examples install
[INFO] --- maven-install-plugin:2.5.2:install (default-install) # spark-examples_2.11 ---
[INFO] Skipping artifact installation
It seems I will have to spelunk into the spark examples pom.xml to see how to re-enable installation? Overall this is a non trivial process: any pointers to a quicker path appreciated.
It appears that a band-aid would be as hinted in the OP: remove the skip from the install plugin invocation:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<configuration>
<!-- <skip>true</skip> -->
</configuration>
A more straightforward approach to adding the spark-examples dependency would still be appreciated (and likely awarded).

Cannot run program "npm" in directory

When i am traversing the to src/main/app/ folder structure where i have the package.JSON & gruntfile, i am able to run npm install and grunt command. But when i am trying to run the mvn jetty:run and a property file in the root folder of the project when POM file is present, it is throwing error that it cannot run npm install in the folder structure src/main/app/.
This is the exact error:
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.2.1:exec (n
pminstall) on project my-abc-web: Command execution failed. Cannot
run program "npm" (in directory "C:\Users\Achyut_J01\Documents\GitHub\infras\my-abc\my-abc-web\src\main\app"): CreatePro
cess error=2, The system cannot find the file specified -> [Help 1]
It's a Windows Machine.
I used this workaround to have a cross-platform Maven build : declare the npm executable name as a Maven variable, and use Maven filters to modify this executable name when running on Windows.
It can work the same for Grunt, Bower etc.
This workaround is not necessary any more if you use exec-maven-plugin >=1.6.0 (thanks Manmay for the information in the comments): it was a bug of this plugin (see https://github.com/mojohaus/exec-maven-plugin/issues/42), that has been fixed in 1.6.0 (see https://github.com/mojohaus/exec-maven-plugin/pull/46)
<properties>
<npm.executable>npm</npm.executable>
</properties>
(...)
<build>
<plugins>
(...)
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.5.0</version>
<executions>
<execution>
<id>exec-npm</id>
<phase>process-resources</phase>
<configuration>
<executable>${npm.executable}</executable>
<arguments>
<argument>install</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
</plugin>
(...)
</plugins>
</build>
<profiles>
<profile>
<id>platform-windows</id>
<activation>
<os>
<family>windows</family>
</os>
</activation>
<properties>
<!-- Override the executable names for Windows -->
<npm.executable>npm.cmd</npm.executable>
<grunt.executable>grunt.cmd</grunt.executable>
<bower.executable>bower.cmd</bower.executable>
</properties>
</profile>
</profiles>
In Windows Platform, use npm.cmd to replace npm
Evidently you are on a Windows system. npm is a batch file and not an executable. There are issues running a batch file from maven exec plugin. You may want to explore the workaround suggested in the link, like
deconstruct the .bat script into its actual commands
use cmd.exe and pass node as parameter - refer to this.
See the link for details: https://stackoverflow.com/a/48184182/4282901
In the directory where node is installed rename the batch file so that the existing npm.cmd file is picked. See screenshot below:
This method is preferable if you build the projects targeting linux and windows both. Moreover, also if the no. of pom files is also large.
Make sure that the directory in which node and npm are installed is added to your PATH variable. If it is, you shouldn't have to change your .pom files at all. This is tested on 1.6.0, so you may have to use the workaround mentioned by #Mossroy if you use 1.5.0.
npm is a shell script.
renaming it npm.sh on windows worked for me.
Windows searched 'npm' and did not find,
it then tries npm.bat which exists

Maven dependency on another Maven project

I'm currently having trouble trying to add add the dependency of another Maven project (specifically Aerospike) into my project. I already did a mvn install on the Aerospike project so in my repository (on Linux: ~/.m2/repository/com/aerospike/aerospike-client/3.0.6) I see a aerospike-client-3.0.6.jar.lastUpdated file. However, when I add the dependency
<dependency>
<groupId>com.aerospike</groupId>
<artifactId>aerospike-client</artifactId>
<version>3.0.6</version>
<scope>compile</scope>
</dependency>
into my project and perform an mvn install, it returns this error:
[INFO] ------------------------------------------------------------------------
[INFO] Building in-memory database poc 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[WARNING] The POM for com.aerospike:aerospike-client:jar:3.0.6 is missing, no dependency information available
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.601s
[INFO] Finished at: Fri Aug 16 11:49:43 EDT 2013
[INFO] Final Memory: 18M/954M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal on project: Could not resolve dependencies for project: Failure to find com.aerospike:aerospike-client:jar:3.0.6 in http://repository.jboss.org/nexus/content/groups/public was cached in the local repository, resolution will not be reattempted until the update interval of jboss-public-repository-group has elapsed or updates are forced -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/DependencyResolutionException
Thanks in advance!
Problem
The console output says that Maven is searching for com.aerospike:aerospike artifact in the JBoss public repository but that artifact isn't there.
Failure to find com.aerospike:aerospike-client:jar:3.0.6 in
http://repository.jboss.org/nexus/content/groups/public
The OP stated that he installed it locally.
Discussion
Maven is trying to download a locally installed artifact from a remote repository that does not have that artifact. By default dependencies are first searched in local repository. AFAIK, the only thing that can override this behavior are the artifact update policies defined in settings.xml.
AFAIK, the offline build (-o) should override any such policies.
I tried to reproduce this situation by deleting dependencies from my local repo and intentionally declaring nonexistent dependencies and Maven acted as documented (offline build does not try to download). I have not played with update policies though.
Solution
Following up on the comments, I have verified the offline build procedure in the following environment:
Apache Maven 3.1.0
Java version: 1.7.0_25, vendor: Oracle Corporation
OS name: "linux", version: "3.2.0-23-generic", arch: "amd64", family: "unix"
The offline build procedure in short:
download all the online dependencies
install all the offline dependencies
run offline build
All the commands are run from the project root folder.
First, comment all the dependencies that are not found in any remote repository from your pom, e.g.:
<!--
<dependency>
<groupId>does</groupId>
<artifactId>not</artifactId>
<version>exist</version>
</dependency>
-->
Prepare the offline build by downloading all the dependencies:
mvn dependency:go-offline
If you don't comment out the missing dependencies this goal will fail. You can verify it by observing that Maven has successfully downloaded all the artifacts in your console output.
Next, install the missing dependencies manually in your local repo:
mvn install:install-file -Dfile=<PATH_TO_MISSING_DEP_JAR_FILE>
-DgroupId=does
-DartifactId=not
-Dversion=exist
-Dpackaging=jar
That will produce not-exist.jar (a copy of <PATH_TO_MISSING_DEP_JAR_FILE>) and not-exist.pom along with metadata files in your local repository under <LOCAL_REPO_PATH>/.m2/repository/does/not/exist/
Verify that those files exist under that exact directory structure.
Default locations of your local repository for different platforms are here, but if it isn't there, then run:
mvn help:effective-settings > settings.log
which will dump the interpolated settings for your project to settings.log file. Open it with a text editor and read the path of your local repo under:
<settings>
...
<localRepository>/path/to/local/repo/</localRepository>
...
</settings>
Now you can run your build in offline mode:
mvn clean install -o
You can set offline mode in your settings file also, but that will set offline mode for a specified user or system-wide as opposed to command line switch which is per project when you want it.
Conclusion
Carefully run this procedure exactly as described, and if you still can't build your project, then please run:
mvn help:effective-pom > pom.log
mvn help:effective-settings > settings.log
and post the contents of pom.log and settings.log files here.

Resources