Maven Clean: excluding directory inside target from being deleted - maven

I have tried many variants but could not make this work. One example (child pom.xml):
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<configuration>
<filesets>
<fileset>
<directory>target</directory>
<useDefaultExcludes>true</useDefaultExcludes>
<excludes>
<exclude>myFolder</exclude>
</excludes>
</fileset>
</filesets>
</configuration>
</plugin>
Maven always tries to delete my folder. Why?

As also suggested by #AR.3 in the answer here, the clean phase and goal would -
By default, it discovers and deletes the directories configured in
project.build.directory, project.build.outputDirectory,
project.build.testOutputDirectory, and
project.reporting.outputDirectory.
Still, if you want to exclude a specific folder from being deleted you can follow the inverse approach(a simple hack) to do it as follows -
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<excludeDefaultDirectories>true</excludeDefaultDirectories>
<filesets>
<fileset>
<directory>target</directory>
<followSymlinks>false</followSymlinks>
<useDefaultExcludes>true</useDefaultExcludes>
<includes>
<include><!--everything other that what you want to exclude--></include>
</includes>
</fileset>
</filesets>
</configuration>
</plugin>
More about excludeDefaultDirectories from a similar link -
Disables the deletion of the default output directories configured for
a project. If set to true, only the files/directories selected via the
parameter filesets will be deleted.
EDIT
It is indeed possible to exclude a specific folder from being deleted using a direct approach:
<configuration>
<excludeDefaultDirectories>true</excludeDefaultDirectories>
<filesets>
<fileset>
<directory>target</directory>
<includes>
<include>**</include>
</includes>
<excludes>
<exclude><!-- folder to exclude --></exclude>
</excludes>
</fileset>
</filesets>
</configuration>

From the documentation of the clean:clean goal:
This attempts to clean a project's working directory of the files that were generated at build-time. By default, it discovers and deletes the directories configured in project.build.directory, project.build.outputDirectory, project.build.testOutputDirectory, and project.reporting.outputDirectory.
Files outside the default may also be included in the deletion by configuring the filesets tag.
This means that whatever you declare in the filesets element, the target directory will always be deleted (EDIT unless excludeDefaultDirectories is set to true, see below edit). Given the above description, a workaround is to do the following:
Temporarily override the above properties to point to something other than the default target directory, before cleaning the directories.
Use the filesets mechanism to tell which directories to exclude from the target directory (same as what you already did).
Restore the properties after cleaning the directories.
The pre-clean and post-clean lifecycle phases can be used to do steps 1 and 3.
EDIT: (thanks to nullpointer for pointing it out)
Setting the goal parameter excludeDefaultDirectories to true will exclude the default directory from being deleted, in which case you can use the filesets approach without the hack of overriding the Maven properties.

Per the comment by #Christian, this solution uses a profile to determine whether or not to let maven-clean delete the excluded folder (and subfolders with /**). In my use case, a process generates parser source files in target/generated-sources prior to compilation. I usually want to keep them to save time. I'm also lazy (like most of us developers) and don't like to type. Commands to build the project:
Profile inactive, keep the parser source: mvn clean install
Profile activated, really, truly clean: mvn clean install delete-parsers
The code:
<properties>
<!-- By default, clean will skip the parser source files
generated in this folder and its subfolders. -->
<skip.parser.source>generated-sources/**</skip.parser.source>
</properties>
<profiles>
<!-- Activate this profile to delete parser sources. -->
<profile>
<id>delete-parsers</id>
<!-- Setting this property to null removes the exclusion
in maven-clean. -->
<properties>
<skip.parser.source />
</properties>
</profile>
</profiles>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<configuration>
<!-- Required so maven standard folders won't be deleted. -->
<excludeDefaultDirectories>true</excludeDefaultDirectories>
<filesets>
<fileset>
<!-- Delete everything in target/** -->
<directory>target</directory>
<includes>
<include>**</include>
</includes>
<!-- But NOT this folder when the profile is activated. -->
<excludes>
<exclude>${skip.parser.source}</exclude>
</excludes>
</fileset>
</filesets>
</configuration>

Related

How to auto clear Tomcat temp directory on server startup through maven

I want to delete all the files and subdirectories from the temp folder of Tomcat 8+ version.
In my application ActiveMQ is integrated which will create one folder inside temp folder of Tomcat on the server startup. So I want to clear my temp folder before creating another folder by ActiveMQ on server startup.
Is there any way to define any maven plugin to achieve this or there is any other way to get this done?
As I can understand you need to clean directories that are not exposed to maven.
So check this clean plugin for maven
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<filesets>
<fileset>
<directory>some/relative/path</directory>
<includes>
<include>**/*.tmp</include>
<include>**/*.log</include>
</includes>
<excludes>
<exclude>**/important.log</exclude>
<exclude>**/another-important.log</exclude>
</excludes>
<followSymlinks>false</followSymlinks>
</fileset>
</filesets>
</configuration>
</plugin>

Maven archetype not substituting properties for module directory name

I created an archetype of a multi-module project, and my intention is to substitute required property __implementation__ for directory names. The result is, __rootArtifactId__ was substituted, but the __impelementation__ was not.
archetype-metadata.xml:
<module id="${rootArtifactId}-${implementation}-impl" dir="__rootArtifactId__-__implementation__-impl" name="${rootArtifactId}-${implementation}-impl">
<fileSets>
<fileSet filtered="true" packaged="true" encoding="UTF-8">
<directory>src/main/java</directory>
<includes>
<include>**/*.java</include>
</includes>
</fileSet>
<fileSet filtered="true" encoding="UTF-8">
<directory></directory>
<includes>
<include>pom.xml</include>
</includes>
</fileSet>
</fileSets>
</module>
properties:
artifactId=basic
implementation=foo
resulting directory: basic-__implementationName__-impl
The substitutions happen just fine in: pom.xml and *.java, but have problems with directories
Is there a way to make archetype use properties for directory names?
For this problem I did the following:
cloned maven-archetype source code through git
git clone --branch maven-archetype-2.4 https://git-wip-us.apache.org/repos/asf/maven-archetype.git
Performed the modification mentioned here ARCHETYPE-455
Performed maven install on the maven-archetype project (some unit tests do not work)
mvn install -DskipTests
Afterwards, directory names are correctly replaced.

Maven overwrite resource file in dependency

I have two Maven modules, A and B. A is a dependency of B. Both modules have a resource file named default.properties located in src/main/resources. I need to keep the filenames the same and the location of the file the same in both projects because both A and B are using code which expects the file to be named and located where it is. When building B, A's default properties is in the final jar. I wish to have B's properties when I build B. How can I do this?
I know this is 3 years old but I had the same problem and this is the closest question I found, but still without correct answer so maybe someone will find it useful.
Example maven-assembly descriptor based on jar-with-dependencies (fixes overriding of log4j.properties by dependencies):
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>jar-with-dependencies</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>false</useProjectArtifact>
<unpack>true</unpack>
<unpackOptions>
<excludes>
<exclude>log4j.properties</exclude>
</excludes>
</unpackOptions>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>${project.build.outputDirectory}</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
</assembly>
The key is to provide different rules for dependencies and the actual project (top of hierarchy). Those can be split by using <useProjectArtifact>false</useProjectArtifact> and providing separate rules in fileSets for the project. Otherwise none of log4j.properties would be packed, including the top one.
Ok, Maven Resources Plugin and Assembly plugin did not cut it, so I dug some more.
It seems this is doable with Maven Shade plugin.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<!-- Main class -->
<mainClass> <!-- fully qualified package and class name --> </mainClass>
<manifestEntries>
<Class-Path>.</Class-Path>
</manifestEntries>
</transformer>
</transformers>
<filters>
<filter>
<artifact>org.something:SomeDependency</artifact>
<excludes>
<exclude>*.properties</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
So, inside the <configuration> ... </configuration> -tags I've defined two things: a transformer-implementation that takes care of modifying the jar-manifest to be runnable and use the current directory as classpath root, and excluding all the files ending with .properties from inside of dependency org.something:SomeDependency.
The actual filtering part is where you can exclude the files you don't want to end up in the final jar built by shade. You can exclude the files from all the dependencies and the current project using <artifact>*:*</artifact> inside the defined <filter>, or you can select only certain dependency using <artifact>dependcyGroupId:dependencyArtifact</artifact>, for example <artifact>junit:junit</artifact>, or even using wildcards for one or the other (<artifact>*:junit</artifact>). The excluded files are then defined inside the <excludes>...</excludes> -tags. Again, you can use exact filenames or wildcards. This should get you going with your current problem, although I'd suggest reading the documentation from the plugin-site, because shade can do a lot more than this.

How do I set directory permissions in maven output?

I am using the maven-assembly-plugin to package my build.
I am able to perform some copying of file sets and modify file permissions fine, but I am unable to modify directory permissions. From the documentation, I am trying to use on the directories I care about. However, regardless of what permissions I specify, directories are ALWAYS created based off of the current umask (0022).
Does anyone know of a clean way to modify directory permissions in this way during a Maven build. The only thing that works is umask 0, but I would rather not be forced to do this, since everyone working on this project would have to have this set.
Example maven assembly.xml:
<?xml version="1.0"?>
<assembly>
<id>zip-with-dependencies</id>
<formats>
<format>dir</format>
<format>tar.gz</format>
</formats>
<includeBaseDirectory>true</includeBaseDirectory>
<dependencySets>
<dependencySet>
<includes>
<include>foo:bar</include>
</includes>
<outputDirectory>/resources/blah</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>true</unpack>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>${basedir}/src/main/web</directory>
<includes>
<include>some_dir</include>
</includes>
<outputDirectory>web</outputDirectory>
<fileMode>0777</fileMode>
<directoryMode>0777</directoryMode>
</fileSet>
</fileSets>
</assembly>
I had the same problem. I tested all the above solutions and none of them worked for me.
The best solution I had in mind and that worked for me was to pre create these parent folders as empty folders, before actually writing to them.
So, to relate to the original problem, you should use:
<fileSet>
<directory>./</directory>
<outputDirectory>/resources</outputDirectory>
<excludes>
<exclude>*/**</exclude>
</excludes>
<directoryMode>0700</directoryMode>
</fileSet>
This should be put before the actual copy to the subfolder of resources in your example.
./ - is simply some existing folder. It can be any other folder, as long as it exists. Note that we exclude any file from the fileSet.
So the result would be an empty folder with the appropriate set of permissions.
On a side note, whoever uses tar to pack the files, without this set, the tar file won't have the permissions set for this parent folder. So extraction will result with a new folder, but with permissions of the extracting user + his umask.
0700 was used only for the sake of the example, of course.
I've solved this problem with a combination of settings in the pom.xml and the assembly descriptor.
In pom specify the defaults for the entire zip file.
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.2</version>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptors>
<descriptor>src/main/assembly/descriptor.xml</descriptor>
</descriptors>
<archiverConfig>
<directoryMode>0755</directoryMode>
<defaultDirectoryMode>0755</defaultDirectoryMode>
<fileMode>0644</fileMode>
</archiverConfig>
</configuration>
</plugin>
Then in the assembly descriptor I provide the overrides for individual folders that shouldn't have the default permissions.
<fileSets>
<fileSet>
<directory>src/conf</directory>
<outputDirectory>conf</outputDirectory>
<fileMode>0600</fileMode>
<directoryMode>0700</directoryMode>
</fileSet>
<fileSet>
<directory>src/db</directory>
<outputDirectory>db</outputDirectory>
</fileSet>
<fileSet>
<directory>src/bin</directory>
<outputDirectory>bin</outputDirectory>
<fileMode>0755</fileMode>
</fileSet>
Here the files in the bin directory will be given executable state for all users. The conf directory and files in it are accessible only by the owner, and the db directory inherits the permissions from the settings in the pom.
The assembly file settings are described at http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html
I couldn't find any official documentation on the configuration section other than the JIRA issue that amra identified.
I found a JIRA issue describing this behavior. A workaround should be
<configuration>
<archiverConfig>
<fileMode>420</fileMode> <!-- 420(dec) = 644(oct) -->
<directoryMode>493</directoryMode> <!-- 493(dec) = 755(oct) -->
<defaultDirectoryMode>493</defaultDirectoryMode>
</archiverConfig>
</configuration>

Maven YUI Compressor Plugin Causing process-resources phase to not run?

I have a maven project that builds a war file.
Including the yui compressor in my maven build file is causing files, found in src/main/resources/ unrelated to any js files, processed during the process-resources to be empty when they are copied into the target directory. Very weird, indeed. Once the yuicompressor plugin is removed from the cycle, the other resources are processed just fine.
Anyone ever seen that (please, say yes ;-) )?
Here's my config:
The YUI Compressor config:
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<goals>
<goal>compress</goal>
</goals>
<phase>process-resources</phase>
</execution>
</executions>
<configuration>
<excludes>
<exclude>**/extjs*/**/*.js</exclude>
<exclude>**/extjs*/**/*.css</exclude>
</excludes>
<nosuffix>true</nosuffix>
</configuration>
</plugin>
And the Resources config, containing the files that are empty when copied into the target dir:
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
To repeat: the files (log4j.xml, etc) in the resources directory are being copied over to the target directory, but they are empty.
Thanks for your help!
What is happening is the YUI Compressor plugin has the resources directory as one of the locations to include for compressing implicitly. It was being run after the resources plugin executed, overwriting the xml and .properties files in the resources dir with empty files (because xml and .properties files don't contain javascript). My fix was to add new excludes to the plugin's config:
<excludes>
<exclude>**/*.xml</exclude> <!-- <-- this one here -->
<exclude>**/*.properties</exclude> <!-- <-- and this one -->
<exclude>**/extjs*/**/*.js</exclude>
<exclude>**/extjs*/**/*.css</exclude>
</excludes>
This is still less than ideal, however, because any resources without an xml or .properties suffix will still be parsed by the yui compressor; I'm back to the original problem.
I tried this exclude, but it didn't work:
<exclude>**/resources/*.*</exclude>
does anyone have any idea why the above wouldn't work, or have an idea how to tell the yui plugin not to process anything in resources?

Resources