Spring Boot build-image with Npm installed - node.js

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.

Related

How to Deploy a "create-react-app" based app on jetty/tomcat

I am trying to deploy a react based app in jetty. As part of that, I thought of trying to do the same in jetty server.
I followed a link:
https://www.megadix.it/blog/create-react-app-servlet/
The above link explains details about it and at the end there is a github project for making a war. the link to that is below:
https://github.com/megadix/create-react-app-servlet
Now, I am able to deploy the war created using the above github project in tomcat 9. I am unable to understand how the dependency resolution of node_modules is happening. Also I am unable to deploy the same war in jetty(putting the war in webapps folder and starting jetty)
Thanks
Single page applications needs to be compiled into one (in same cases more) .js file. In your case, create-react-app or similar tools are responsible for fulfilling this requirement.
In the pom.xml execution list, you can see npm install, npm build commands. They are pretty much similar as mvn clean install and mvn buuild.
Dependencies are resolved from package.json dependencies field and installed under node_modules. Once dependencies are there, npm build (or create-react-app-servlet build), compiles all the source code + dependencies into a js file. This probably has a name like main.XXXXXX.js.
In the end, you have a dist folder consisting of .html, .js and other resources.
It'd be better if you share more details of what's happening with jetty deployment

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).

best practices for java fx application build tool for linux

I trying to write a JavaFX application. When I built it using Netbeans, the RPM package does not work on CentOS 6.
Is there any fool proof way to build a JavaFX application for Linux?
Disclaimer: I'm the maintainer of the javafx-maven-plugin and creator of the javafx-gradle-plugin
When using maven, you can use the javafx-maven-plugin, just set the <bundler> to "rpm":
<plugin>
<groupId>com.zenjava</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>8.4.0</version>
<configuration>
<mainClass>your.path.to.your.MainClass</mainClass>
<verbose>true</verbose>
<bundler>rpm</bundler>
<bundleArguments>
<licenseFile>license.rtf</licenseFile>
</bundleArguments>
<!-- place your license here -->
<additionalAppResources>src/main/additionalAppResources</additionalAppResources>
</configuration>
</plugin>
Then just call mvn jfx:native on the command-line to create your rpm-package having your application including the JRE inside. If you don't want the JRE sit inside the RPM-package, just add <runtime /> to the bundleArguments.
When using gradle, just look at the project-website on github ;) or ask me via mail if something is unclear.
EDIT
As a temporary workaround, please set appName to something without a dot
<configuration>
<!-- other configuration elements -->
<appName>SimpleApplicationNameWithoutDot</appName>
</configuration>

YUI fails to compress in Confluence plugin

I'm developing a confluence plugin and I'm using bower as my package manager.
When I try to compile and package the plugin the SDK tries to minify all the JS files using YUI compressor.
The minification process fails due to various reasons (reserved words, syntax errors), all caused by the packages installed by bower.
When I don't minify the code everything passes, and the plugin works fine.
I tried atlas-compile --fail-never, didn't help.
Any idea on how I can minify the code without having to modify the packages code? Or maybe put a flag that will cause only the files that are in atlassian-plugin.xml to be minified?
Thanks!
In the pom.xml, ensure that you don't compress JS with <compressResources>false</compressResources> e.g. around here...
<build>
...
<plugin>
<groupId>com.atlassian.maven.plugins</groupId>
<artifactId>maven-confluence-plugin</artifactId>
<version>${amps.version}</version>
<extensions>true</extensions>
<configuration>
...
<compressResources>false</compressResources>
...
</configuration>
</plugin>
...
I am trying to solve the same issue and I came to believe this is not possible. (It's 2016, people. This is not rocket science.)
The error I am getting is:
[INFO] --- maven-confluence-plugin:6.2.4:compress-resources (default-compress-resources) # confluence-tagging ---
[INFO] Compiling javascript using YUI
[ERROR] illegal character
And then errors in some file deep in node_modules that should definitely not be included in the plugin build.
I tried to list all available options for the compressor plugin using this command:
atlas-mvn help:describe -Dplugin=com.atlassian.maven.plugins:maven-confluence-plugin -Dgoal=compress-resources -Ddetail=true
The list says that there is no such option. I tried to configure it to use Closure Compiler instead, but it did not help much. The configuration is this:
<plugin>
<groupId>com.atlassian.maven.plugins</groupId>
<artifactId>maven-confluence-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>compress-resources</goal>
</goals>
</execution>
</executions>
<configuration>
<closureJsCompiler>true</closureJsCompiler>
</configuration>
</plugin>
Which just gives me even longer list of errors.
At this point, I am giving up.
Here are some relevant links:
https://developer.atlassian.com/docs/advanced-topics/supporting-minification-of-javascript-and-css-resources - desperately outdated
https://answers.atlassian.com/questions/221949/how-to-select-which-resources-are-compressed

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

Resources