Make maven clean not fail when only folder remains - maven

While developing an application, the command I use most often is mvn clean install. Cleaning probably isn't needed 90% of the time, but it does not hurt and might help to avoid weird issues. There are however times, when I'm working on a console application, when I have trunk open on one terminal, and target on another.
mvn clean in such a case does what I need it to - it deletes every file within the target folder - and then fails due to lock on the folder itself. Is there a way to tell it, that in such a case it should just ignore/skip deleting the folder itself and continue with install?

Yes, you can configure the maven-clean-plugin to ignore errors with the help of the failOnError attribute. It defaults to true, meaning that the plugin will fail on error.
Sample configuration to disable this:
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<failOnError>false</failOnError>
</configuration>
</plugin>
You can also do it directly on the command line, without changing the POM, by setting the maven.clean.failOnError user property:
mvn clean install -Dmaven.clean.failOnError=false
Note that this make the plugin ignore all errors, however it is not currently possible to make it ignore only certain types of errors.

Related

maven-dependency-plugin unpack goal: do not overwrite existing files

I do not ever want maven-dependency-plugin:3.1.2:unpack to overwrite existing files in any circumstances. This is my current pom.xml configuration:
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.2</version>
<executions>
<execution>
<id>unpack-zip-files</id>
<phase>generate-test-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.foo</groupId>
<artifactId>bar</artifactId>
<version>${foobar.version}</version>
<type>zip</type>
<classifier>exe-archive</classifier>
<overWrite>false</overWrite>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<includes>**/*.exe</includes>
</artifactItem>
</artifactItems>
<overWriteIfNewer>false</overWriteIfNewer>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
</configuration>
</execution>
</executions>
</plugin>
Scenario:
Projects foo and bar
foo has a .exe file as build artifact, inside a ZIP file
bar runs the .exe file during tests
In situation X, bar must use the snapshot version of the mainline development branch of foo. In that case, the directory target/lib shall be empty before mvn install. This is guaranteed by starting from an empty workspace and running mvn clean as a separate build step. This question is not about situation X.
In situation Y, bar must use a custom build of a feature branch of foo. This is done by unpacking the ZIP file with the .exe to the directory target/lib in a separate build step between mvn clean and mvn install.
We are working in situation Y, where the target/lib directory is already pre-filled with the .exe from the correct feature branch.
This is the target/lib directory before mvn is run:
+ ls -al fooBar.exe
-rw-rw-r-- 1 ubuntu ubuntu 18368427 Apr 12 21:27 fooBar.exe
+ md5sum fooBar.exe
03acc8b5c3da700c31efcd6635feb56a fooBar.exe
This is the target/lib directory after mvn is run:
+ ls -al fooBar.exe
-rwxrwxr-x 1 ubuntu ubuntu 18368393 Apr 11 23:10 fooBar.exe
+ md5sum fooBar.exe
ab6dd45c5cc4e41534ad2363c5767601 fooBar.exe
The change in md5sum is hard evidence that the existing fooBar.exe was overwritten by Maven.
Maven command used:
mvn --global-settings /home/jenkins/workspace/bar#tmp/config15592668079584895681tmp \
-Dmaven.repo.local=/home/jenkins/workspace/bar/.repository \
install \
-DgsExec=/usr/bin/gs -DcompareExec=/usr/local/bin/compare \
-Dtest=RunCucumberTest -Dcucumber.options=--plugin json:target/cucumber.json
Expected results
The mvn install command shall not overwrite existing files when overWrite, overWriteIfNewer, overWriteReleases, overWriteSnapshots are all set to false.
The md5sum of fooBar.exe shall be the same before and after running mvn install.
Question
Which magical incantations do I need to add to pom.xml so that existing files are never overwritten in any circumstances?
Documentation referenced
Apache Maven Dependency Plugin – Usage – Overwrite Rules
Apache Maven Dependency Plugin – dependency:unpack
OK, I think I know what might be happening: Like I said in my comment:
I just read your message on the mailing list and tried in one of my own projects, also using plugin version 3.1.2. Actually, just specifying <overWrite>false</overWrite> inside the <artifactItem> was enough to avoid overwriting. I just executed the unpack goal once, then manually modified an unpacked file and it did not get overwritten. I even see my-artifact-1.3.jar already unpacked in the log.
I continued experimenting some more and noticed that even when deleting many unpacked files, they will not be recreated, so the check must be on a more global level, not on a per-file basis.
Even when deleting all files or the whole output directory, the dependency will not be unpacked again. That was a sure indicator that some kind of meta information must be stored somewhere outside the output directory. The first place to look for it was of course the target directory, and obviously enough, in subdirectory target/dependency-maven-plugin-markers there are (empty) marker files like my-dependency-1.3.marker. Deleting one of those files has the effect of the dependency getting unpacked again during the next build, overwriting possibly existing files.
So the way for you to solve this problem is to avoid cleaning the target directory or at least to make sure to keep the corresponding marker file.
Update: You could also create the marker file by yourself if the EXE file you want to protect exists and if for some reason your build workflow needs the clean in between. But the latter would be a bit ugly, you should try to avoid it. With Antrun or some Beanshell or Groovy scripting it would be possible, though.
Somewhat more elegant would be a profile with auto-activation if the EXE file does not exist, then putting the dependency plugin inside the profile, i.e. it would only get active if the EXE does not exist in the first place.

Maven - Remove Generated Folders

I'm using the maven-compiler plugin to generate my .jar
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
When I do a clean install it will generate folders such as "generated-sources", "maven-archiver", "maven-status" amd "classes" in addition to my .jar
How could I automatically deleted those folders after the install or prevent them from being generated?
You cannot prevent those folders from being generated as they are essential to making the build work. generated-sources most likely contains Java source code that was generated during the build and is needed to make the rest of the code compile; classes contains the compiled Java source code that was under src/main/java and is needed to make a subsequent JAR or WAR, etc. So, without those folders, the build cannot properly work.
However, they are inherently temporary. In fact, the whole target folder is temporary. It contains data that is generated / copied at build-time and is needed to make the final artifacts. This is why it is generally a good idea to always clean before building a Maven project: it makes sure that this build folder is cleaned so that new fresh data is created (otherwise, it might rely on old build data, potentially making hard to track down bugs).
Once the final artifacts are created, they will be the only one to be considered when installing or deploying the project. If you really want to get rid of those files after the build (but I don't see why), you could always run mvn clean install clean. This will delete the target folder once the project's artifacts are installed.

JavaFX Self Installer With Inno Setup 5 - Allow user to change install directory

I am using Ant to build a self deploying EXE for a JavaFX application.
Currently Inno Setup places the EXE here: C:\Users\username\AppData\Local\application name
I would like to place this in a different location, and provide the user the option to override this. However I can't seem to find the ant settings to change this.
Is this possible?
Thanks!
Actually you can't change this using ANT. However, as you already know the deploy mechanism uses Inno Setup and you can modify its behaviour.
During the fx:deploy ANT task a default ApplicationName.iss file is created. This default file contains e.g. the setting, which is responsible for the install directory. This default file is only created, if you don't provide any customized on your own. So, I would recommend to run the ANT script, copy the default file and modify it. If you enable the verbose flag of the fx:deploy task you can use the console output to find out, where the default file is created and where the ANT task searches for your customized file before creating the default one:
<fx:deploy
...
verbose="true">
<fx:info title="${appname}" vendor="${vendor}"/>
...
</fx:deploy>
In my case I found the default file in
C:\Users\gfkri\AppData\Local\Temp\fxbundler3627681647438085792\windows
and had to put the customized file to
package/windows/ApplicationName.iss
relative to the ANT build script.
If you got so far, you'll find the line DisableDirPage=Yes in your ApplicationName.iss file. Change it to DisableDirPage=No and the user gets the possibility to change the install directory.
Further you will find the parameter DefaultDirName. If you want to install your Application to C:\Program File\ApplicationName by default you can use the constant {pf} e.g.: DefaultDirName={pf}\ApplicationName.
The original answer is not true anymore, because that feature got added to the JDK (just dont know when, but it was there when using 1.8.0u60 or so).
Just add <installdirChooser> as some <bundleArguments> and set it to true:
<plugin>
<groupId>com.zenjava</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>8.4.0</version>
<configuration>
<mainClass>your.mainclass</mainClass>
<verbose>true</verbose>
<bundleArguments>
<identifier>SOME-GUID-USED-FOR-UPDATE-DETECTION</identifier>
<installdirChooser>true</installdirChooser>
</bundleArguments>
</configuration>
</plugin>
Disclaimer: I'm the maintainer of the javafx-maven-plugin

How to update folders automatically with IntelliJ

I have a Maven configuration that copies my web resources to a directory in target. From there it is read by Jetty. What I want (and what Eclipse always did for me) is update the target/web directory when something in the src/main/webapp directory changed. I can't get IntelliJ to do the same:
The resource configuration like this:
<resource>
<directory>src/main/webapp</directory>
<excludes>
<exclude>less/</exclude>
</excludes>
<filtering>false</filtering>
<targetPath>${project.build.directory}/web</targetPath>
</resource>
Right now I have to run the Generate sources and update folders everytime I make a change. Can't IntelliJ Detect this automatically?
Notes:
I do not build a war but a folder distribution.
I already tried moving it to target/generated-sources/web but that makes no difference.
The target/web is not marked as excluded in the module configuration.
The folder is marked as a resource folder. I tried marking it as a source folder but that made no difference.
The problem can be solved by using the File watchers plug-in. This plug-in doesn't ship with IntelliJ by default but it is very useful. From there, you can watch your *.less/html/js files and re-generate them if you edit them. In my case I run the appropriate Maven goals but you can also call the less compiler directly if you want to.
In the configuration set "Output paths to refresh" to the the custom directory you are using (in my case $OutputPath$/web). After that, any change should be refreshed automatically.
I think, yes: try pressing Ctrl+Shift+A, type "Import Maven", click the checkbox "Import Maven project automatically". This will enable auto-import which copies resources as well.

Maven Plugin to mark empty directories

Is there something for Maven that I can use to create "placeholders" (e.g. a .empty or EMPTY) file for empty directories? Mercurial does not include empty directories so I need these directories filled hopefully via some automated way.
In the past, I used a Python script that does exactly this. I was hoping for a more Java-esque or Maven-esque approach.
Thanks
You could always use maven-antrun-plugin or gmaven-plugin to script putting a file in your directories. And then submit those empty files to your source control.
HOWEVER, this would have maven generate source code that is going to be checked in. Which is a bad idea (or at least not what you want to regular build to do).
If your source control does not keep track of empty directories, but they're needed for your build, I would recommend instead having a generate-source hook in your maven lifeycle that creates those. (Ideally, in your target directory to keep it clean, however since your source control won't keep track of them there is little harm in putting them right in your source folders if that makes your life easier).
Something like (consider that pseudo-code, absolutely not tested):
<build>
<plugins>
<plugins>
<artifactId>maven-antrun-plugin</...>
<executions>
<execution>
<phase>generate-source</phase>
<goals><goal>antrun</...
<configuration>
<tasks>
<mkdir dir="my directory1"/>
<mkdir dir="my directory2"/>

Resources