Concat messages.properties with maven - maven

We have some default message files and we want to be able to customize them by maven profiles.
Therefore we configured two resource entries
<resource>
<directory>${basedir}/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>${basedir}/profiles/${additionalWebcontent}/java</directory>
<filtering>true</filtering>
</resource>
currently the files from ${basedir}/resources are overwritten by files from ${basedir}/profiles/${additionalWebcontent}/java.
Is it possible to append the content from the files from ${basedir}/profiles/${additionalWebcontent}/java to the content of the files from ${basedir}/resources ?
An example content would be
${basedir}/resources/messages/messages.properties
greeting=Hello World!
logout=Logout
login=Logout
${basedir}/profiles/${additionalWebcontent}/java/messages/messages.properties
greeting=Hello Folks!
Expected Result:
${project.build.directory}/classes/messages/messages.properties
greeting=Hello World!
logout=Logout
login=Logout
greeting=Hello Folks!

Related

Maven Filtering Include/Exclude Understanding

Hello I'm trying to understand the filtering include/exclude in Maven as I am a Maven noob. I was looking up how to read the version from the pom file in JAVA and found the solution but I have a few questions about the filtering. I understand the filtering with include and/or exclude in the same resource block, but I'm not understanding what is happening when you include/exclude in different resource blocks of the same file/folder.
My folder structure with simplified RandomFolder and its contents:
src
├── main
│ ├── resources
│ ├── RandomFolder
│ ├──aFile.dll
│ ├──someFile.txt
│ └── pom.properties
pom.properties file contains:
version=${revision}
#1
This is how I currently have it (simplified) as a working solution. I understand it's filtering the pom.properties file and replacing '${revision}' with '1.0.0' aka 'version=1.0.0'. Would the pom.properties file be filtered (aka 'version=1.0.0') when mvn package is ran and a jar file is generated? I would assume so, but wanted to make sure.
I also understand that typically you wouldn't specify the filename in the filtering and instead it would be **/*.properties, but since this was the only properties file I think it's easier and cleaner to have the filename and it shouldn't cause any issues (let me know if I am wrong on this assumption).
...
<properties>
<revision>1.0.0</revision>
</properties>
...
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/pom.properties</include>
</includes>
</resource>
</resources>
...
</build>
#2
I believe this is the way tutorial websites would normally represent include and exclude in a resource block. Really unnecessary in this example as it filters everything besides the pom.properties (found and tested that the excludes block overwrites the includes block no matter the order).
No question here. Just wanted to state that I know about this approach.
...
<properties>
<revision>1.0.0</revision>
</properties>
...
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/pom.properties</include>
</includes>
<excludes>
<exclude>**/pom.properties</exclude>
</excludes>
</resource>
</resources>
...
</build>
#3
Why does this work? I would assume its filtering the file first so that the file reads '1.0.0' then is not filtering, but I want to make sure. This stems from a similar solution I found to get the pom version (see #5 further down). I tested this and it filters the pom.properties file.
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/pom.properties</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/pom.properties</exclude>
</excludes>
</resource>
</resources>
...
</build>
#4
The flip flop of #2 with the exclude block before the include block, which seems kinda unnecessary. I would assume its not filtering the file first then filtering the file so that the file reads '1.0.0', but I want to make sure. I tested this and it filters the pom.properties file.
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/pom.properties</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/pom.properties</include>
</includes>
</resource>
</resources>
...
</build>
#5
This I don't really know. This was a top solution found for: Maven resource filtering exclude
And the link provided in that solution I feel doesn't explain the reasoning for its' solution: https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html
So is it filtering everything except the pom.properties file but then not filter everything including the pom.properties file? Why? What's the purpose of this? Are they both the same thing? Or a double negative? Does it impact what appears in the build/package?
This 'solution' did not filter the pom.properties file when I tested it.
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>**/pom.properties</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<includes>
<include>**/pom.properties</include>
</includes>
</resource>
</resources>
...
</build>
Please let me know if you need additional information. I would really appreciate it if you can go through each section (#1 to #5) and answer them. Thank you in advance!
Solution
Robert Scholte's response helped me understand that filtering also copied over files. This is something I did not understand before as I thought it was just modifying the file(s) in the desired folder(s).
With additional help with understanding exclusions from:
http://www.avajava.com/tutorials/lessons/how-do-i-exclude-particular-resources-from-being-processed.html
I was able to answer my questions.
#1. Still not sure, but I believe the pom.properties file would be filtered in jar.
#2. N/A. No question to answer.
#3. For #3, #4, #5 I created a test.properties in same folder as pom.properties and contains the same contents.
Testing required me to use command: mvn clean install -DskipTests to visually see the differences between #3, #4 and #5.
This would be the result after creating the test.properties file and running the above command (without the block in pom file) for a visual reference:
src
├── main
│ ├── resources
│ ├── RandomFolder
│ ├──aFile.dll
│ ├──someFile.txt
│ └── pom.properties
target
├── classes
│ ├── MultipleGeneratedFolders
│ ├── RandomFolder
│ ├──aFile.dll
│ ├──someFile.txt
│ ├── pom.properties
│ └── test.properties
So for #3, it filtered only the pom.properties and moved to a '/target/classes/' path (same level as 'src'). But because of the second resource block, it copies over all the contents in the RandomFolder and the test.properties file to '/target/classes/' path without filtering them!
#4. Exact same result as #3. Everything is copied over '/target/classes/', but only pom.properties file is filtered.
#5. Here is the interesting one. The first resource block with filtering true and excluding pom.properties is filtering everything (since there is no , it defaults to everything) and then copies to '/target/classes/' path. So this means the test.properties file gets filtered! The second resource block with filtering false and including pom.properties is not filtering the pom.properties file (so it leaves as raw text) then copies over to '/target/classes/' path. Basically, everything besides pom.properties gets filtered and copied over to '/target/classes/' path.
Summary of Conclusions
In short, filtering refers to replacing the variables in files with the properties block in the pom file, such as ${revision}. Filtering does not require or (if neither are specified it defaults to including all files) and copies selected files to the target folder.
If you filter (set to TRUE) and only a specific pattern or file, it will only filter the selected files and copy them to the target folder.
If you filter (set to TRUE) and only , it will filter everything except for the specified pattern or file and copy only the filtered files to the target folder.
If you don't filter (set to FALSE) and only a specific pattern or file, it will only copy the selected files to the target folder without filtering them.
If you don't filter (set to FALSE) and only a specific pattern or file, it will copy all files except the selected files to the target folder without filtering them.
(I could be wrong in my conclusions so take it may not be completely accurate, but 'good enough for government work' as they say)
You can run mvn process-resources -X to see more details about which files are copied.
But this is how it works:
per resource-block the fileset to copy is selected by choosing all includes (default is all), minus all excludes (default none).
If filtering is set to true, the placehoders in these files will be replaced, otherwise they will be copied as is.

Spring cloud loading keystore from classpath vs file

I have a spring cloud config server that uses keystore to decrypt values from git server. If I reference the keystore using file path, it works as expected and decrypts the {cipher} values. However, if I try to load the keystore from classpath it stops working with this error :
CipherEnvironmentEncryptor.decrypt - Cannot decrypt key: username (class java.lang.IllegalStateException: Cannot load keys from store: class path resource [mykey.p12])
Im setting the encrypt properties on the class instead of yaml since I need to lookup different passwords from external vault system for dev/prod keystores.
I can also see p.12 file under target/classes after the build, so it is not filtered out during the build. Not sure what I'm missing.
SpringApplication sa = new SpringApplication(Myclass.class);
Properties springProperties = new Properties();
springProperties.setProperty("encrypt.enabled", "true");
springProperties.setProperty("encrypt.key-store.location", "file:///Users/user/IdeaProjects/project/src/main/resources/configuration/mykey.p12"); //working fine
springProperties.setProperty("encrypt.key-store.location", "classpath:/configuration/mykey.p12"); //does not work
springProperties.setProperty("encrypt.key-store.type", "PKCS12");
springProperties.setProperty("encrypt.key-store.password", "password");
springProperties.setProperty("encrypt.key-store.secret", "password");
springProperties.setProperty("encrypt.key-store.alias", "vault");
sa.setDefaultProperties(springProperties);
sa.run(args);
Using
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
<version>2.2.0.RELEASE</version>
<name>spring-cloud-config-server</name>
My issue was actually related to this : generated certificate stops working when moved to resources folder
I had maven filtering configuration on the resources which was corrupting the final p12 file. For now I just moved files that need filtering to another resource directory and it works.
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/resources-filtered</directory>
<filtering>true</filtering>
<includes>
<include>*.yml</include>
<include>logback.xml</include>
</includes>
</resource>
</resources>

Why does Maven include change the structure of my required files

I want to include the directory "dirA" into my .jar
The structure is the following
-mvnModule
-dirA
-dirB
someFiles
-dirC
someFiles
-src
.......
When I do this:
<resources>
<resource>
<directory>dirA/*</directory>
</resource>
</resources>
Why is it that if I investigate the .jar-File, all Files are just under the root (mvnModule). Maven removes my structure, which leads to FileNotFoundExcpetions at runtime. I do not want to change all the paths in the code...is there a way to include it with the correct/original structure?

sass-maven-plugin using add_import_path option

Is it a way to use add_import_path option in maven plugin configuration or I had to use compassConfigFile ?
Setting buildDirectory to the path where are import files is a solution ?
I use this plugin :
http://www.geodienstencentrum.nl/sass-maven-plugin/update-stylesheets-mojo.html
Error :
failed: File to import not found or unreadable: theme.
Load paths:
And I don't have the directory I need in Load paths
I tried
<sassOptions>
<load_paths>${project.basedir}/src/main/webapp/theme/colors/red</load_paths>
</sassOptions>
without success
You need to specify the load_paths as an array, this seems to work for me:
<load_paths>['${project.basedir}/src/main/webapp/theme/colors/red']</load_paths>
The thing that makes it work is the [ ] around the string, making it an array it seems in the ruby-end of things, so the sass gem gets it the way it wants
So I found a solution
<configuration>
<sassOptions>
<always_update>true</always_update>
<style>${sass.OutputStyle}</style>
</sassOptions>
<useCompass>true</useCompass>
<compassConfigFile>${project.basedir}/src/main/webapp/style/config.rb</compassConfigFile>
<resources>
<resource>
<source>
<directory>${project.basedir}/src/main/webapp/style/themes/colors/cyan</directory>
</source>
<destination>${project.build.directory}/${project.build.finalName}/style/themes/colors/cyan</destination>
</resource>
<resource>
<source>
<directory>${project.basedir}/src/main/webapp/style/themes</directory>
</source>
<destination>${project.build.directory}/${project.build.finalName}/style/themes/colors/cyan</destination>
</resource>
</resources>
The first resource load scss files for import in the second resource imported files are avaible. First resource generate nothing in destination but node is needed.

How do I access maven project version in javadoc overview page?

I am using PDFDoclet with maven-javadoc-plugin and I've come quite a long way with it now. I have the maven and javadoc config almost at a point that is good enough but my immediate problem now is that I can't work out how to push the project version number into the PDF title page.
Before you leap to answer my question by telling me to use maven's <resource> filtering, let me outline why that isn't working.
Filtering works by taking the original file from somewhere in the src folder, doing variable substitution and putting the output in the target folder.
Javadoc works by reading files in src/main/java and src/main/javadoc and AFAIK outputting the results into target. This means filtering is useless for Javadoc since it won't read anything from target
My results show that any maven variables in javadoc comments don't get substituted.
What trick can I use to get those variables substituted into the javadoc?
The solution can't involve filtering the javadoc output after the site:site task, unless resource filtering works on PDFs.
This is the configuration, FWIW:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<configuration>
<show>package</show>
<docfilessubdirs>true</docfilessubdirs>
<tags>
<tag>
<name>pdfInclude</name>
<placement>X</placement>
<head></head>
</tag>
</tags>
</configuration>
<reportSets>
<reportSet>
<id>PDF</id>
<reports>
<report>javadoc</report>
</reports>
<configuration>
<name>PDF</name>
<description>PDF doc</description>
<destDir>pdf</destDir>
<doclet>com.tarsec.javadoc.pdfdoclet.PDFDoclet</doclet>
<docletPath>${basedir}/pdfdoclet/pdfdoclet-1.0.3-all.jar</docletPath>
<useStandardDocletOptions>false</useStandardDocletOptions>
<additionalparam>-pdf my_tech_doc-${project.version}.pdf
-config ${basedir}/pdfdoclet/pdfdoclet.properties</additionalparam>
</configuration>
</reportSet>
</reportSets>
</plugin>
and the pdfdoclet.properties:
# http://pdfdoclet.sourceforge.net/configuration.html
#
#Lets the doclet print additional output in the console and to a logfile.
debug=true
#Print "Author" tags
author=false
#Print "Version" tags
version=true
#Print "since" tags
tag.since=true
#Create summary tables
summary.table=false
#Create hyperlinks
create.links=true
#Encrypt the PDF file
encrypted=false
#Allow printing of the PDF file
allow.printing=true
#Create a bookmark frame
create.frame=true
#Print a title page
api.title.page=true
api.copyright=None
api.author=Hansruedi
#Enables the tag-based filter
filter=true
filter.tags=pdfInclude
font.text.name=resources/arial.ttf
page.orientation=portrait
The PDFDoclet-specific api.* properties should result in a title page as the first page of the PDF, but it doesn't work. If there is a trick that I've missed here and I could get that title page produced, then that might also allow a solution for this somehow.
I realised I can do a quick and dirty hack with the maven <resources> functionality:
<resource>
<directory>${basedir}/src/main/resources</directory>
<targetPath>${basedir}/src/main/javadoc</targetPath>
<filtering>true</filtering>
<includes>
<include>**/overview.html</include>
</includes>
</resource>
This copies my overview.html and filters it, outputting it into the javadoc source directory.
The dirtiness is that this filtered version could then accidentally end up under version control, although using svn I can add it to the ignore list.

Resources