Using war excludes in the pom.xml - java

The maven documentation for this has to be wrong.
Here are the various permutations I have tried with all failing to exclude the file:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warSourceExcludes>**/*server.properties</warSourceExcludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webResources>
<resource>
<!-- this is relative to the pom.xml directory -->
<directory>src/main/resources/com/mycom/myapplication/</directory>
<!-- there's no default value for this -->
<excludes>
<exclude>**/*server.properties</exclude>
</excludes>
</resource>
</webResources>
</configuration>
</plugin>
A mail list entry suggests using this older version and a string list:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.0.1</version>
<configuration>
<webResources>
<resource>
<!-- this is relative to the pom.xml directory -->
<directory>src/main/resources/com/pictage/provendirect/</directory>
<!-- there's no default value for this -->
<excludes>**/*server.properties</excludes>
</resource>
</webResources>
</configuration>
</plugin>
Which results in:
(found static expression: '/*server.properties' which may act as a default value).
Cause: Cannot assign configuration entry 'excludes' to 'interface java.util.List' from '/*server.properties', which is of type class java.lang.String
Also tried:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.0.1</version>
<configuration>
<packagingExcludes>
**/server.properties
</packagingExcludes>
</configuration>
</plugin>
Any ideas? I am going crazy with this.

A more careful reading of the maven docs suggests:
<configuration>
<webResources>
<resource>
should only be used when excluding resources outside /src/main/resources. To do it inside this folder, you need to use warSourceExcludes and possibly warSourceDirectory parameters if the property isn't in the root of the directory.
I cry a little inside when it takes me hours to to do something via configuration in maven when it could have been handled in two seconds with a scripting language but I guess it's the 'right' way to implement it.

Related

Eclipse (latest) artifact builder does not include ressources

i'm currently confused that eclipse ignores my configured pom building instructions.
Used : Eclipse 2023-03 / 2022-12 (both same failure)
parent pom :
...
<modules>
<module>my-module</module>
<module>my-webapp</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>my-module</artifactId>
<version>1.0</version>
</dependency>
...
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.12.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<excludes>
<exclude>**/module.dtd</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.14.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>17</source>
<target>17</target>
<showDeprecation>true</showDeprecation>
<showWarnings>true</showWarnings>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
my-module structure (pom refers to parent without any build instructions - packaging -> jar) :
src/main/java
---...
src/main/resources
src/main/resources/META-INF/test/file.xml
src/main/resources/example/bootstrap/file2.xml
my-webapp (refers to parent pom - packaging -> war) :
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webResources>
<resource>
<directory>${config.path}</directory>
<targetPath>WEB-INF/config</targetPath>
<includes>
<include>**/*</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
Build with mvn clean install results in a deployable war file which contains my-module.jar in lib folder as expected, size matches also the generated jar file in my-module targets folder.
so targets generated .war/.jar are correct.
Now i setup inside eclipse a default tomcat server above v.9.0.50+ (tried multiple versions, also latest 9.0.71). and added my-webapp(example-context) to the server (cleaned before and then publish).
at this point i inspected my unzipped war file inside tomcat webapproot (tried meta and tomcat location (both same failure)) , and was completly confused that my my-module-1.0.jar file only contains only META-INF/maven (pom.xml + pom.properties) and my java classes so that it doesen't match the size as expected (due to missing resource files).
Is there any trick or option to configure eclipse to build the artifact with resources as instructed by my poms or any other vaiable soloution ?
If i use intellij, it worked out of the box but i prefer eclipse for my project
Tried different versions of eclipse , tomcat , maven and plugin versions (latest) but nothing seems to work.
Sometimes if i change my resource or java files of my-mopdule, eclipse makes a redeploy and then the artifact contains the correct my-module-1.0.jar with resources included but after another mvn clean install its gone and i need to modify any files again up to 10 times if it happens again.

How to include filtered resources into WEB-INF/classes using maven-resources-plugin?

I'm using the maven-resources-plugin because I need to use a custom delimiter when doing my filtering. My artifact is a WAR.
I have some resources in my src/main/resources directory. Normally, when packaging a WAR, anything in this directory ends up in WEB-INF/classes. But I need those resources to be filtered first, then placed into the WEB-INF/classes directory. I'm having a hard time configuring the maven-resources-plugin to do that. Is there a way?
My POM looks like this:
<build>
<finalName>my-app</finalName>
<filters>
<filter>${basedir}/src/main/properties/base.properties</filter>
</filters>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<overwrite>true</overwrite>
<useDefaultDelimiter>false</useDefaultDelimiter>
<delimiters>
<delimiter>#</delimiter>
</delimiters>
<outputDirectory>${project.build.directory}</outputDirectory>
<resources>
<resource>
<directory>
${basedir}/src/main/resources
</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Short answer:
The phase is wrong, validate is the second phase, should only be used for validation of the build environment and comes before the default process-resources phase, so your correct files become overriden.
Long answer:
Basically, you have two options two fix your problem:
Use a different / new execution for copying
If you really need different behaviours.
In that case, your phase is wrong. What happens is:
in the phase validate (Why there?), the resources are correctly filtered and copied
in the phase process-resources, the default-resources execution of the resources plugin runs the goal copy-resources, which overrides your filtered resources again in the unfiltered state.
If you really want to do it this way, put the resources into a different directory than src/main/resources, change the phase of of the execution to somewhat appropriate (as to not confuse) and please also change the id of the execution (to something like copy-specially-filtered-resource - the id can be used to explain why there is the need for a second execution)
Also, the output directory is wrong (would need to be: ${project.build.outputDirectory}, directory points only to the target folder.
<build>
<finalName>my-app</finalName>
<filters>
<filter>${basedir}/src/main/properties/base.properties</filter>
</filters>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<id>copy-special-resources</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<overwrite>true</overwrite>
<useDefaultDelimiter>false</useDefaultDelimiter>
<delimiters>
<delimiter>#</delimiter>
</delimiters>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
<resources>
<resource>
<directory>
${basedir}/src/main/filtered
</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Also, in this case, I would place the filters into the execution configuration as well (everything else is misleading).
Preferred: Simply reconfigure the resources plugin
Way shorter and easier would be to simply reconfigure the resources plugin, activate filtering for the resources globally and use the default execution (however, this would also be active for test-resources):
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<finalName>my-app</finalName>
<filters>
<filter>${basedir}/src/main/properties/base.properties</filter>
</filters>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<useDefaultDelimiter>false</useDefaultDelimiter>
<delimiters>
<delimiter>#</delimiter>
</delimiters>
</configuration>
</plugin>
</plugins>
</build>
Hint: Using the override config is usually a smell...
First why not reading the documentation of maven-war-plugin
Based on the documentation you can define a configuration to use a supplemental directory and activate filtering for that directory like this:
<configuration>
<filters>
<filter>properties/config.prop</filter>
</filters>
<nonFilteredFileExtensions>
<!-- default value contains jpg,jpeg,gif,bmp,png -->
<nonFilteredFileExtension>pdf</nonFilteredFileExtension>
</nonFilteredFileExtensions>
<webResources>
<resource>
<directory>resource2</directory>
<!-- it's not a good idea to filter binary files -->
<filtering>false</filtering>
</resource>
<resource>
<directory>configurations</directory>
<!-- enable filtering -->
<filtering>true</filtering>
<excludes>
<exclude>**/properties</exclude>
</excludes>
</resource>
</webResources>
</configuration>
I would recommend to make a supplemental directory like src/main/filtered-resources which you configure to do filtering and the default resources directory I wouldn't change (no filtering by default). This makes it easier to understand.
If you want to change the delimiters you can add the configuration to the maven-war-plugin like this:
<delimiters>
<delimiter>#</delimiter>
</delimiters>
So in the end there is no need to make supplemental configuration for maven-resources-plugin etc.

Maven Exclude Files During Build

I am having problems getting Maven to build my webapp without including extraneous development file, such as unminified script and css files.
First i tried using exclude in combination with webResources
<build>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warName>ReportRocket-1</warName>
<webResources>
<resource>
<directory>src/main/webapp/resources/</directory>
<excludes>
<exclude>annotated-js/*.js</exclude>
<exclude>compiled-js/*.js</exclude>
<exclude>css/*.css</exclude>
<exclude>less/*.less/exclude>
</excludes>
<directory>src/main/webapp/WEB-INF</directory>
<excludes>
<exclude>connection.json</exclude>
<exclude>reportRocket.jsp</exclude>
</excludes>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
The result was the contents of WEB-INF being duplicated in the project root and no excluded directories or files.
So, I looked around here and found this: maven2: excluding directory from WAR but running mvn clean package using either warSourceExcludes or packagingExcludes results in the directories i'm trying to exclude not being, well, excluded...
The build section of my pom.xml
<build>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warName>ReportRocket-1</warName>
<packagingExcludes>
src/main/webapp/resources/annotated-js/,
src/main/webapp/resources/compiled-js/,
src/main/webapp/resources/css/,
src/main/webapp/resources/less/,
src/main/webapp/WEB-INF/connection.json
</packagingExcludes>
</configuration>
</plugin>
</plugins>
</build>
Building the project with these settings results in the following project structure:
META-INF
resources
//desired folders
annotated-js
compiled-js
css
less
WEB-INF
// desired files
connection.json
This is my first time using a build tool, so i'm probably overlooking something simple but in the meantime, this is driving me crazy. Any suggestions or obvious problems with my xml?
First you should read the documentation of the maven-war-plugin cause the packagingExclude is intended for a different purpose, but in your case you need to do the configuration in that way:
<configuration>
<webResources>
<resource>
<!-- this is relative to the pom.xml directory -->
<directory>src/main/webapp/resources/</directory>
<!-- there's no default value for this -->
<excludes>
<exclude>annotated-js/**</exclude>
</excludes>
</resource>
</webResources>
</configuration>

No classes in war maven

I'm pretty new in using og maven, an I got stuck. mvn clean install does not generate classes :(
I'm using the following code in my pom :
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<webXml>WebContent\WEB-INF\web.xml</webXml>
<archiveClasses>true</archiveClasses>
</configuration>
</plugin>
Please read the usage page first, it will show the expected folder structure.
So java sources are expected in src/main/java.
BTW: If you still want to use WebContent, set the warSourceDirectory to WebContent, remove all other configuration.
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<optimize>true</optimize>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webResources>
<resource>
<directory>src/main/webapp</directory>
<filtering>true</filtering>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>

Maven: Where to put generated resources for tomcat-maven-plugin?

I have CSS and JavaScript files in src/main/webapp directory of my project.
I want to join add joined and minified version of these resources to my WAR file and to the place where tomcat-maven-plugin picks it up.
I used yuicompressor-maven-plugin to create the files and put it to ${project.build.directory}/${project.build.finalName}. It works great for maven package and those resources make their way to WAR file, but somehow tomcat-maven-plugin does not see those at all. Should I use a different directory for it?
My pom:
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>1.1</version>
<configuration>
<path>/MyApp</path>
<warDirectory>${project.build.directory}/${project.build.finalName}</warDirectory>
</configuration>
</plugin>
<plugin>
<version>2.5.1</version>
<inherited>true</inherited>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<optimize>true</optimize>
<debug>true</debug>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.2</version>
<configuration>
<webResources>
<resource>
<directory>${basedir}/src/main/resources/META-INF</directory>
<filtering>true</filtering>
<targetPath>META-INF</targetPath>
<includes>
<include>context.xml</include>
</includes>
</resource>
</webResources>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addClasspath>true</addClasspath>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.3.0</version>
<executions>
<execution>
<phase>process-resources</phase>
<configuration>
<excludes>
<exclude>**/*</exclude>
</excludes>
<aggregations>
<aggregation>
<output>${project.build.directory}/${project.build.finalName}/js/commons-pack.js</output>
<includes>
<include>${project.build.sourceDirectory}/../webapp/js1.js</include>
<include>${project.build.sourceDirectory}/../webapp/js2.js</include>
...
What should I do to make mvn tomcat:run to also pick up my generated files?
Use warSourceDirectory:
<warSourceDirectory>${project.build.directory}/${project.build.finalName}</warSourceDirectory>
Instead of this configuration property (warDirectory) for the tomcat-maven-plugin:
<warDirectory>${project.build.directory}/${project.build.finalName}</warDirectory>
According to the tomcat-maven-plugin documentation, warSourceDirectory is where the web resources get picked up, and its default value is ${basedir}/src/main/webapp. This means that if you don’t set that property, you need to generate your unified/minified JavaScript file under ${basedir}/src/main/webapp.
If you set warSourceDirectory to the output folder, this means you need to generate this file before starting Tomcat.
Alternatively, you can also use the run-war goal instead of run, e.g. mvn tomcat6:run-war. This wil use the exploded war in your build directory (and thus filtered resources). See this site. There is also run-war-only which skips the packaging phase.
Note the plugin is now maintained at Apache (so upgrade a bit :-) ) see http://tomcat.apache.org/maven-plugin-2.0/.
Even it works using install I'm not sure it's the optimum solution (regarding io and build time).
The tomcat run must be able to use resources from more than one directory (I'm not sure it's possible with the current tomcat embeded api).
Can you add a feature request here https://issues.apache.org/jira/browse/MTOMCAT
Thanks

Categories