Maven signed jar gives warning "unsigned application" - java

I'm using Maven for a project that creates a JAR that's embedded in my web application to sign PDF documents using a smartcard.
In my pom.xml I use the maven-jarsigner-plugin as follows:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jarsigner-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>sign</id>
<goals>
<goal>sign</goal>
</goals>
</execution>
<execution>
<id>verify</id>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
<configuration>
<keystore>/path/to/my/keystore.jks</keystore>
<alias>my-key-alias</alias>
<storepass>********</storepass>
<keypass>********</keypass>
<verbose>true</verbose>
<certs>true</certs>
<arguments>
<argument>-tsa</argument>
<argument>https://timestamp.geotrust.com/tsa</argument>
</arguments>
</configuration>
</plugin>
The project builds fine, without any errors. For 99% they are just [INFO] messages, except some [WARNING] messages from the Maven Shade plugin:
[WARNING] maven-shade-plugin has detected that some .class files
[WARNING] are present in two or more JARs. When this happens, only
[WARNING] one single version of the class is copied in the uberjar.
[WARNING] Usually this is not harmful and you can skeep these
[WARNING] warnings, otherwise try to manually exclude artifacts
[WARNING] based on mvn dependency:tree -Ddetail=true and the above
[WARNING] output
When I manually check the resulting jar using the CLI jarsigner it is fine:
Niels-MBP:target niels$ jarsigner -verify my-applet.jar
jar verified.
The jar also verifies without problems on other computers. However, when I include the jar in my web application, users get the message: "security warning: Do you want to run this application? Un unsigned application from the location above is requesting permission to run."
UPDATE: When I run the jarsigner with the -verbose option, all .class files are marked as sm (signature verified, entry is listed in manifest) and are missing the k option (at least one certificate was found in keystore). This may be the cause of the error. END UPDATE
The page is served over HTTPS. The jar is on the same domain (even the same folder) as the HTML page and included like this:
<script src="https://www.java.com/js/deployJava.js"></script>
<script>
var attributes = {
id: 'myApplet',
code: 'nl.company.project.applet.MyAppletApplet',
archive: 'my-applet.jar',
width: 200,
height: 200
};
deployJava.runApplet(attributes, '1.7');
<script>
Any help with this would be appreciated!
Niels

The company where I purchased the code signing certificate - Xolphin - tracked down the problem for me. It had something to do with an incorrect added certificate/alias in the keystore. I recreated the keystore and the problem is gone.
For others facing the same warning: make sure that you uncheck 'Keep temporary files on my computer' in your Java settings (System Preferences -> Java -> Temporary Internet Files -> Settings). It caused me to search further after the problem was fixed, even though I used different filenames for different versions of my JAR file.

Related

Creating executable JAR in IntelliJ (Java 18, JavaFX 18 Maven project), "WARNING: Unsupported JavaFX configuration..."

I have a Java 18, JavaFX 18 Maven project which has a lot of libraries, beside the javaFX libraries, that needs to be included in the artifact. I want to create an artifact, a jar, which contains all dependencies. I started following this video to create the jar: https://www.youtube.com/watch?v=UKd6zpUnAE4
Summarizing my steps, and referring to the steps in the video:
In IntelliJ in Project Structure/Project Settings/Libraries I removed all Maven added libraries, and added C:\Program Files\Java\javafx-sdk-18.0.2\lib
After, in Run/Edit Configurations... I added a VM options, and in that window I added
--module-path "C:\Program Files\Java\javafx-sdk-18.0.2\lib"
--add-modules javafx.controls,javafx.fxml
After, in the video, "Ken" the host of the video creates a class, with a main() method, that runs the application original main() class. I did not need this step, because I already has a class that does the same.
After, File/Project Structure/Project Settings/Artifact/ I added a JAR/From modules with dependencies/ and I choose the class I recently created, and shortened the path until the source folder (src)
Following this step, after I clicked add (+), and added the content of "...javafx-sdk-18.0.2/bin" all dll's and everything (all files).
Here, at this point, separate from the video, I also created a folder named "jars" and put all Maven dependencies jars in that folder.
According to the video, after these steps, with a double click on the artifact the jar runs without a problem.
However, I needed I more step. My dependency jars are signed jars, so I needed to open the artifact with WinRAR and remove the *.SF, *.DSA and *.RSA files. Earlier this caused me problems so I followed the idea here: Invalid signature file digest for Manifest main attributes exception while trying to run jar file, and here: "Invalid signature file" when attempting to run a .jar
After this, everything should be fine, however not :( The jar doesn't run on double click. When I run it from command line, I receive the following error:
$ java -jar jHasher.jar
jan. 15, 2023 3:19:07 DU. com.sun.javafx.application.PlatformImpl startup
WARNING: Unsupported JavaFX configuration: classes were loaded from 'unnamed module #3a178016'
javafx.fxml.LoadException:
unknown path:53
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2707)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2685)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2532)
at view.GUI.start(GUI.java:29)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:847)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:484)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at com.sun.javafx.fxml.BeanAdapter.put(BeanAdapter.java:263)
at com.sun.javafx.fxml.BeanAdapter.put(BeanAdapter.java:54)
at javafx.fxml.FXMLLoader$Element.applyProperty(FXMLLoader.java:523)
at javafx.fxml.FXMLLoader$Element.processValue(FXMLLoader.java:373)
at javafx.fxml.FXMLLoader$Element.processPropertyAttribute(FXMLLoader.java:335)
at javafx.fxml.FXMLLoader$Element.processInstancePropertyAttributes(FXMLLoader.java:245)
at javafx.fxml.FXMLLoader$ValueElement.processEndElement(FXMLLoader.java:778)
at javafx.fxml.FXMLLoader.processEndElement(FXMLLoader.java:2924)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2639)
... 11 more
Caused by: java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:119)
at java.base/java.lang.reflect.Method.invoke(Method.java:577)
at com.sun.javafx.fxml.ModuleHelper.invoke(ModuleHelper.java:102)
at com.sun.javafx.fxml.BeanAdapter.put(BeanAdapter.java:259)
... 19 more
Caused by: java.lang.UnsupportedOperationException: Cannot resolve 'win10-document'
at org.kordamp.ikonli.AbstractIkonResolver.resolve(AbstractIkonResolver.java:61)
at org.kordamp.ikonli.javafx.IkonResolver.resolve(IkonResolver.java:73)
at org.kordamp.ikonli.javafx.FontIcon.setIconLiteral(FontIcon.java:251)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
... 22 more
I have searched the following error message. I also found some posts on StackOverflow, however they are not clear to me, and I was not able to fix this issue. Please, guide me how to proceed. All suggestions are highly appreciated.
After several hard day, I was able to create the executable jar. I'd like to share the know-how with you.
After 5th step, skipping the WinRAR for removing the *.SF, *.DSA and *.RSA files. I added maven-shade-plugin to my pom.xml. The shade plugin can automatically remove these unwanted files, but unfortunately by itself cannot create a runnable JAR, because throws again exceptions and doesn't run on double click (JavaFX 18 Maven IntelliJ: Graphics Device initialization failed for: d3d, sw Error initializing QuantumRenderer: no suitable pipeline found).
To avoid this exception and include the unlocated/missing JavaFX files we have to repack the already packed JAR. To do that, I used the spring-boot-maven-plugin. After setting up the plugins (code below), you have to run the plugins with maven in a correct order! My maven command was the following: mvn clean package spring-boot:repackage
That it, finally the created JAR (JAR of the JAR) can run on double click.
My pom.xml's corresponding parts:
Shade plugin setting:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>controller.Start</mainClass>
</transformer>
</transformers>
<minimizeJar>true</minimizeJar>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
The Spring-boot-maven-plugin setting (this should be placed outside the plugins section, at the very end of the pom.xml):
<pluginManagement>
<plugins>
<plugin>
<!-- mvn clean package spring-boot:repackage -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>spring-boot</classifier>
<mainClass>
controller.Start
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
Make sure to run the plugins in the correct order, as mentioned above! I found this resource very useful: https://www.baeldung.com/spring-boot-repackage-vs-mvn-package

CodeCov cannot find reports

I am trying to get codecov to run and process the reports generated by Jacoco for my multibuild Java Gradle project. However, when I run the codecov script (bash <(curl -s https://codecov.io/bash)), I get the following output:
x> No CI provider detected.
Testing inside Docker? http://docs.codecov.io/docs/testing-with-docker
Testing with Tox? https://docs.codecov.io/docs/python#section-testing-with-tox
project root: .
Yaml found at: .codecov.yml
==> Running gcov in . (disable via -X gcov)
==> Python coveragepy not found
==> Searching for coverage reports in:
+ .
--> No coverage report found.
Please visit http://docs.codecov.io/docs/supported-languages
I have verified that the reports are created by jacoco in build/reports/jacoco/codeCoverageReport, and that the xml report in fact exists.
I setup the jacoco reporting following the guide here (Github). The main difference between my gradle code and the code on that github is I have xml.destination "${buildDir}/reports/jacoco/report.xml" excluded, because Gradle will fail to process with it included.
.codecov.yml
codecov:
require_ci_to_pass: true
coverage:
precision: 3
round: up
range: "70...100"
status:
project: true
patch: yes
changes: no
parsers:
gcov:
branch_detection:
conditional: yes
loop: yes
method: yes
macro: no
comment:
layout: "reach,diff,flags,tree"
behavior: default
require_changes: false
I figured it out. Running bash <(curl -s https://codecov.io/bash) -h listed the options available to me, where I found out that there is a -f <file> option to specify the exact file to use.
From here, I simply use that in my travis file to get it to upload correctly:
bash <(curl -s https://codecov.io/bash) -f build/reports/jacoco/codeCoverageReport/codeCoverageReport.xml
I am using maven with java15
add into pom.xml (under build section):
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.6</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
add into .travis.yml:
script:
- mvn clean package
after_success:
- bash <(curl -s https://codecov.io/bash)
Worked well for me.

Cannot load UIMA PEAR package through the package installer GUI

I have a problem related to installing a UIMA PEAR package containing an Annotator component. I am using PearPackageMavenPlugin for the job with the following setup:
<plugin>
<groupId>org.apache.uima</groupId>
<artifactId>PearPackagingMavenPlugin</artifactId>
<version>2.6.0</version>
<extensions>true</extensions>
<executions>
<execution>
<phase>package</phase>
<configuration>
<!-- PEAR file component classpath settings -->
<classpath>$main_root/bin</classpath>
<!-- PEAR file main component descriptor -->
<mainComponentDesc>desc/S4DocumentUimaAnnotator.xml</mainComponentDesc>
<!-- PEAR file component ID -->
<componentId>S4DocumentAnnotator</componentId>
<!-- PEAR file UIMA datapath settings -->
<datapath>$main_root/resources</datapath>
</configuration>
<goals>
<goal>package</goal>
</goals>
</execution>
</executions>
</plugin>
`
I have constructed a special maven profile building the project in a bin directory instead of target so all my compiled classes are there that is why I have pointed the classpath setting of the plugin at $main_root/bin.
Finally when I load the built pear package I get the following error:
Verification of S4DocumentAnnotator failed =>
org.apache.uima.resource.ResourceInitializationException: The class com.ontotext.s4.api.components.uima.S4DocumentUimaAnnotator is not a valid Analysis Component. You must specify an Annotator, CAS Consumer, Collection Reader, or CAS Multiplier. If you are calling ResourceManager.setExtensionClassPath, this error can also be caused if you have put UIMA framework jar files on the extension classpath, which is not allowed. (Descriptor: file:/home/ceco/s4_stuff/my_pear/S4DocumentAnnotator/desc/S4DocumentUimaAnnotator.xml)
at org.apache.uima.analysis_engine.impl.PrimitiveAnalysisEngine_impl.initializeAnalysisComponent(PrimitiveAnalysisEngine_impl.java:228)
at org.apache.uima.analysis_engine.impl.PrimitiveAnalysisEngine_impl.initialize(PrimitiveAnalysisEngine_impl.java:170)
at org.apache.uima.impl.AnalysisEngineFactory_impl.produceResource(AnalysisEngineFactory_impl.java:94)
at org.apache.uima.impl.CompositeResourceFactory_impl.produceResource(CompositeResourceFactory_impl.java:62)
at org.apache.uima.UIMAFramework.produceResource(UIMAFramework.java:279)
at org.apache.uima.UIMAFramework.produceResource(UIMAFramework.java:331)
at org.apache.uima.UIMAFramework.produceAnalysisEngine(UIMAFramework.java:448)
at org.apache.uima.pear.tools.InstallationTester.testAnalysisEngine(InstallationTester.java:218)
at org.apache.uima.pear.tools.InstallationTester.doTest(InstallationTester.java:113)
at org.apache.uima.pear.tools.InstallationController.verifyComponentInstallation(InstallationController.java:1110)
at org.apache.uima.pear.tools.InstallationController.verifyComponent(InstallationController.java:1993)
at org.apache.uima.tools.pear.install.InstallPear.installPear(InstallPear.java:389)
at org.apache.uima.tools.pear.install.InstallPear.access$000(InstallPear.java:80)
at org.apache.uima.tools.pear.install.InstallPear$RunInstallation.run(InstallPear.java:109)
at java.lang.Thread.run(Thread.java:744)
I do not understand why the UIMA jars are not supposed to be packaged when the idea of the PEAR package is to be self-contained and not depend on the system it is ran on?
This is what I would try:
The class com.ontotext.s4.api.components.uima.S4DocumentUimaAnnotator is not a valid Analysis Component
Check that S4DocumentUimaAnnotator is valid. Unzip the PEAR and check the xml.
If you are calling ResourceManager.setExtensionClassPath, this error can also be caused if you have put UIMA framework jar files on the extension classpath, which is not allowed.
Did you try to print the extension classpath?
Else you could try to use a plain java version of the PEAR, meaning: manually unzip it and create a normal java project with it.
One common issue I ran into several times and which creates exactly this error message is that my PEAR contains uimaj-common.jar in the lib folder. Have you checked this?
I know this one is old but what I think you should do is set the scope of the uima dependencies to provided. The PEAR needs only it's dependencies to run, the enviroment it'll be used should have the uima dependencies set to use all the uima features and pears
Provided dependencies won't be copied to the lib folder of the PEAR
There are a couple of things that could be going on, but going by your error message, the first thing I would determine is whether or not the uimaj-core jar file is being excluded from the build of the PEAR file. It should be. (Take a look at the error message above.) I just ran into this problem myself, and I got around it by adding this to my POM:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<!-- Copy the dependencies to the lib folder for the PEAR to copy. -->
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<stripVersion>true</stripVersion>
<outputDirectory>${basedir}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
<includeScope>runtime</includeScope>
<!-- An exception happens when using a PEAR if the archive includes this jar. -->
<excludeArtifactIds>uimaj-core</excludeArtifactIds>
</configuration>
</execution>
</executions>
</plugin>
I recently posted a parent POM file and a project-specific POM file to my Gist. You're welcome to take a look at what I'm doing. (One of the things I'm doing is copying over my desc directory, which contains my AE's descriptor XML file, to the root of my project directory, so that the maven-pear plugin can copy it into the PEAR archive properly.)
Parent POM:
https://gist.github.com/software-mariodiana/d46e10fca53dc6e6c0f16e20563476b8
Project-specific POM:
https://gist.github.com/software-mariodiana/e9a0f0f03a49d33dcc32655170fd4841
Good luck!

Using namespace mappings in axistools-maven-plugin

I have a maven project where java stubs are generated from wsdl files using axistools-maven-plugin.
Within pom we have following:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>axistools-maven-plugin</artifactId>
<version>${axistools-maven-plugin.version}</version>
<configuration>
<mappings>
<mapping>
<namespace>xyz</namespace>
<targetPackage>x.y.z</targetPackage>
</mapping>
<mapping>
<namespace>http://time.joda.org</namespace>
<targetPackage>com.org.joda.time</targetPackage>
</mapping>
<mapping>
<namespace>abc</namespace>
<targetPackage>a.b.c</targetPackage>
</mapping>
</mappings>
<testCases>false</testCases>
<serverSide>false</serverSide>
<subPackageByFileName>true</subPackageByFileName>
</configuration>
<executions>
<execution>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
Now in above setting we just have namespaces mapped to package. I am just not able to get how this setting is able to track where does wsdl reside in order generate stubs?
Maven documentation is not very clear on this. Any ideas on this?
EDIT:
I did some testing on this:
I removed all the mappings of namespaces and packages but still wsdl gets picked up.
Even if i change the wsdl name, it still gets picked up.
This is very surprising to me, it seems axis plugin knows about wsdl location. but how i dont knw.
So finally i solved the mystery.
I ran maven build in debug mode : mvn -X clean insatll
I noticed that maven-axistools-plugin checks the default directory as ${basedir}/src/main/wsdl to search for wsdl and hence it was always able to locate my wsdls.

How to deploy a node.js app with maven?

Most of our team consists of java developers and therefore the whole build / deployment / dependency management system is built on top of maven. We use CI so every build process runs unit test (w. karma and phantomJS for the frontend, and jasmine-node for the backend). I've managed to configure a karma maven plugin for this purpose.
This does not solve the issue of downloading node.js dependencies from package.json on build. I need to deploy my node.js / express app in existing environment, so the perfect scenario would be:
pull from the repo (done automatically with maven build)
npm install (that is - downloading dependencies from node package registry)
running tests
I was trying to find a nodejs package for maven, but to be honest - as a node.js developer I do not feel very confident when it comes to choosing the right tools, since I'm not able to distinguish a bad maven plugin from a decent one.
Maybe using a shell plugin and invoking npm install from the terminal is a better choice?
What's your opinion?
You've got two choices:
https://github.com/eirslett/frontend-maven-plugin to let maven download your npm modules from your package.json and let it automagically install node and npm all along
https://github.com/mulesoft/npm-maven-plugin to let maven download your npm packages that you have specified in the pom.xml (link dead as of April 2020, seems to be discontinued)
As a hacky solution, though still feasible you could as you've mentioned yourself, use something like maven-antrun-plugin to actually execute npm with maven.
All approaches have their pros and cons, but frontend-maven-plugin seems to be the most often used approach - but it assumes that your ci server can download from the internet arbitrary packages, whereas the "hacky" solution should also work, when your ci server has no connection to the internet at all (besides proxying the central maven repo)
I think you can find the answer in Grunt and the many available plugins.
I'm actually working on a web project where the client-side is made with AngularJS. Nevertheless, I think the deployement process may partially answer to your question :
In your pom.xml, you can do something like that:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>exec-gen-sources</id>
<phase>generate-sources</phase>
<configuration>
<target name="Build Web">
<exec executable="cmd" dir="${project.basedir}"
failonerror="true" osfamily="windows">
<arg line="/c npm install" />
</exec>
<exec executable="cmd" dir="${project.basedir}"
failonerror="true" osfamily="windows">
<arg line="/c bower install --no-color" />
</exec>
<exec executable="cmd" dir="${project.basedir}"
failonerror="true" osfamily="windows">
<arg line="/c grunt release --no-color --force" />
</exec>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
First part is the npm install task: downloading of dependencies from node package.
Second part is the bower install task: downoading of other dependencies with bower (in my case, AngularJS, but you might not need this part)
Third part is the Grunt Release part: launching a Grunt task that includes Karma unit testing.
You can find documentation about Grunt here. There are many available plugins like Karma unit testing.
I hope this helped you.
I made npm process work for my AngularJS 2 + Spring Boot application by exec-maven-plugin. I don't use bower and grunt, but think you can make it work by exec-maven-plugin too, after look at the antrun example above from Pear.
Below is my pom.xml example for exec-maven-plugin. My app has package.json and all the AngularJS .ts files are under src/main/resources, so run npm from the path. I run npm install for dependencies and npm run tsc for .ts conversion to .js
pom.xml
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<id>exec-npm-install</id>
<phase>generate-sources</phase>
<configuration>
<workingDirectory>${project.basedir}/src/main/resources</workingDirectory>
<executable>npm</executable>
<arguments>
<argument>install</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
<execution>
<id>exec-npm-run-tsc</id>
<phase>generate-sources</phase>
<configuration>
<workingDirectory>${project.basedir}/src/main/resources</workingDirectory>
<executable>npm</executable>
<arguments>
<argument>run</argument>
<argument>tsc</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
</plugin>
One little hack on this is running maven build on eclipse with Windows or Mac. It perfectly fine on eclipse with linux or even also fine on Windows command window though. When run build on eclipse with Windows, it fail to understand npm and complain about not find the file. Weird thing is npm is working fine on Windows command window. So solving the hack I create npm.bat file under system path. In my case nodejs and npm are installed under C:\Program File\nodejs. After putting this batch file. everything works fine.
npm.bat
#echo off
set arg1=%1
set arg2=%2
C:\Progra~1\nodejs\npm.cmd %arg1% %arg2%
For Mac, I got same issue on eclipse. The thing is nodejs and npm are installed under /usr/local/bin. So to solve the issue, I make symbolic link /usr/local/bin/node and /usr/local/bin/npm to under /user/bin. However /usr/bin is protected in security policy, I done that after booting from recovery disk
Since 2015, there is an alternative to the frontend-maven-plugin mentioned in
Christian Ulbrich's excellent answer:
https://github.com/aseovic/npm-maven-plugin
Usage
Basically, all you have to do to use it is to put it into your POM as usual (and use "extensions:true"):
<build>
<plugins>
<plugin>
<groupId>com.seovic.maven.plugins</groupId>
<artifactId>npm-maven-plugin</artifactId>
<version>1.0.4</version>
<extensions>true</extensions>
</plugin>
[...]
</plugins>
</build>
The plugin will then automatically bind to the Maven lifecycle. Then, you can put a script into your package.json, such as:
"scripts":
{
"package": "npm pack",
[...]
}
and the npm script "package" will run automatically as part of the Maven build lifecycle phase "package".
Compared to frontend-maven-plugin
Just like frontend-maven-plugin, it will run npm scripts inside a maven project. There are two important differences:
frontend-maven-plugin will (and must) download and install npm itself. npm-maven-plugin uses (and requires) an installed version of npm.
frontend-maven-plugin requires you to describe every npm invocation in the POM (as an "execution" section). In contrast, npm-maven-plugin simply extends the Maven build lifecycle to automatically execute an npm script with the same name for each lifecycle phase (clean, install etc.). That means there is no npm-specific configuration in the POM - it's all taken from package.json.
Personally, I prefer the npm-maven-plugin's approach because it requires less configuration in the POM - POMs have a tendency to get bloated, and everything to counter that helps. Also, putting the npm invocations into package.json feels more natural and allows reusing them when invoking npm directly.
Admittedly, even with the frontend-maven-plugin you can [and probably should] define all npm invocations as scripts in package.json, and invoke these scripts from the POM, but there is still the temptation to put them directly into the POM.

Categories