Maven Plugin to mark empty directories - maven

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"/>

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.

Make maven clean not fail when only folder remains

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.

Maven webapp with non-default web resource directory

Maven sets the default webapp directory to src/main/webapp as per http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html.
We use a IDE-configured server for development, which uses the files from this directory to serve. The server doesn't work from another directory and serves directly from the file system. This has the benefit that every change we make to the source files is visible instantly.
However, all the files in the webapp directory are not minified, not concatenated, etc. I have currently setup grunt to take the files from the webapp directory and put the deployment-ready resources in src/main/webapp/dist.
The problem: when building a war, the contents of src/main/webapp are copied into the war, but I want only the deployment-ready files from src/main/webapp/dist to be copied into the war.
I've tried countless google searchs for the topic and I'm feeling stupid. As already stated, I found "http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html", which says "these settings can be overridden via the project descriptor", but it does not show how. I found http://maven.apache.org/pom.html#Build_Element which doesn't show the webapp directory. I've found "http://maven.apache.org/guides/mini/guide-using-one-source-directory.html" which again, doesn't specify how to change the directories.
I know I can just specify src/main/webapp/dist as an additional resource directory and it will be copied into root war directory. But I don't want all the development files available in the production build.
Also, if someone knows of a better way of handling my general approach, I would like to hear it as well.
I found the setting, finally. http://maven.apache.org/plugins/maven-war-plugin/war-mojo.html
Add
<warSourceDirectory>src/main/webapp/dist</warSourceDirectory>
to the maven-war-plugin configuration, like so:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warSourceDirectory>src/main/webapp/dist</warSourceDirectory>
</configuration>
</plugin>

Maven Thrift Plugin

I am trying to automate the generation of source files from the .thrift files and later the packaging. As far as I know, the maven-thrift-plugin is restrictive in the sense that source and destination directories are fixed. Is there any way I can specify the source and destination directories? I could probably achieve this by using the maven-antrun-plugin but I don't want to pollute my pom unnecessarily if I don't have to.
Thanks.
As far as I can see from the source (https://github.com/dtrott/maven-thrift-plugin/blob/master/src/main/java/org/apache/thrift/maven/ThriftCompileMojo.java) there are configuration properties that control this behaviour.
Try these properties, they should work:
thriftSourceRoot
thriftTestSourceRoot
outputDirectory
These props should be added to the <configuration> section along with <thriftExecutable>, etc:
<plugin>
<groupId>org.apache.thrift.tools</groupId>
<artifactId>maven-thrift-plugin</artifactId>
<version>0.1.10</version>
<configuration>
<thriftExecutable>/usr/local/bin/thrift</thriftExecutable>
<thriftSourceRoot>${basedir}/src/main/my_custom_thrift_root</thriftSourceRoot>
</configuration>
<executions>
...
</plugin>
I also ended up going the maven-antrun-plugin route, here is a functional example: https://github.com/cobbzilla/cobbzilla-wizard/tree/master/wizard-thrift
pom.xml uses maven-antrun-plugin to exec the thrift target in build.xml
build.xml does the thrift compilation and packaging.
Generated sources go back into the source tree; I don't like derived files polluting my upstream source control, so the generated files are under a thrift package, and the package directory is in a .gitignore file. A bit kludgy.
A better way I learned about since writing that code is to compile multiple java source directories in a single maven project, which would be cleaner.

Is Maven really flexible?

I understand how Maven works with .java files in src/java/main. But may it be used for a more general case? Let us put it more abstract: Suppose I already have some a.exe that reads some (not necessarily only .java) sources from directories A1, A2, A3 and puts some files (maybe some are generated .java) to directories B1, B2. I also have some b.exe that currently reads files from B1, B2, B3 and generates something else. Some more similar steps. (A real life problem stands behind).
I would like to write a POM.xml file so that maven will do this work. Is that possible? I assume that a.exe and b.exe should be warped as maven plugings.
Next, in Maven docs I see :
<build>
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
<scriptSourceDirectory>${basedir}/src/main/scripts</scriptSourceDirectory>
<testSourceDirectory>${basedir}/src/test/java</testSourceDirectory>
<outputDirectory>${basedir}/target/classes</outputDirectory>
<testOutputDirectory>${basedir}/target/test-classes</testOutputDirectory>
...
</build>
What bothers me is that "sourceDirectory" looks by itself as a hard coded name. Will Maven accept A1 and A2 tags instead?
(Will you consider accepting some of your previous questions, so that other people will be more willing to answer you?)
Maven stress for Convention over Configuration. You can treat sourceDirectory as one of the conventions, which we have predefined some elements to use with the (Java) compiler plugin.
What you want to do can be achieved. You can write a plugin/MOJO yourself, which read from whatever directory you want and invoke whatever external exe you want. By having reasonable default values in your MOJO, you can have your project POM look something like
<project>
:
:
<build>
<plugins>
<plugin>
<groupId>yourPluginGroup</group>
<artifactId>generate-A-data</artifactId>
<!-- if you want extra configuration, you can have <configuration> elements -->
</plugin>
<plugin>
<groupId>yourPluginGroup</group>
<artifactId>generate-B-data</artifactId>
</plugin>
</plugins>
</build>
<project>
Not that bad huh?
However, it is quite questionable to say whether Maven is "flexible". I believe flexibility is never the aim of Maven. Maven is specialized for building, it defines different skeletons for you to follow (e.g. build phases, dependency scopes), you can never make Maven as "flexible" as other script-based tools like Ant.
The answer is: NO, MAVEN IS NOT FLEXIBLE. Here is a simple task I could not solve even with the help from all the maven forums of this world: Write a POM that
compiles some directory full of Java files
does something else (if you please - executes a sample Hello World Mojo plugin)
compiles some other directory with some other Java files.
NO WAY !
You may be able to do this without writing plugins, by binding the exec plugin and the compiler plugin to the 'generate-sources' or 'process-classes' phases. The build helper plugin might also be useful for adding source paths.
For the original case, you could try the following bindings:
build-helper-maven-plugin bound to the initialize phase, adding any necessary source directories (eg B1 and B2)
exec-maven-plugin bound to the generate-sources phase, with two executions, one for a.exe and one for b.exe
For the Hello World Mojo case, what if you add the following to the process-classes phase (in order)?
Hello World Mojo plugin
Build Helper plugin to add source directory
Compiler plugin
The only downside I can see is that the first source directory will be recompiled. But the compiler should be smart enough to know that nothing has changed, and whether it's a problem depends on why you actually want to do this. Why do you need the class files from directory A before you run Hello World? Perhaps you're really looking at two separate pieces of code that should become separate modules?

Resources