Manipulating __artifactId__ during file generation by maven archetype - maven

Building a Maven archetype where files are generated using _artifactId_. archetype.xml looks like:
<sources>
<source>src/main/java/__artifactId__.java</source>
<source>src/main/java/__artifactId__CommandExecutor.java</source>
<source>src/main/java/__artifactId__EventListener.java</source>
</sources>
Generating a project using this archetype can lead to Java file names that do not follow the naming convention such as sample-plugin.java and sample-pluginCommandExecutor.java.
How can I make sure _artifactId_ is converted to appropriate Java file name, such as SamplePlugin.java and SamplePluginCommandExecutor.java.

I'm not an archetype expert, in fact I just did it once but
faced with a very similar problem.
I was not able to find a way to customize file or directory names
in any way, I mean use one of the archetype parameters and transform
it.
So there are 2 kinds of solution I used
Add a new archetype parameter where you specify the class name
Use a standard Name (like ArtifactClass.java) and then create an maven profile (enabled if this file is present) with an ant script that changes the name (just remember inside your files you can use velocity to customize it)
Hope it helps
tonio

Related

spring boot loading property file from custom folder

I need to load a property file from src/main/resources/config folder. The loading part is written in a common dependency project where we dont have any control. We are just passing the file name expressed through a dependency. The code snippet in the dependent jar is like below, the standard resource loading.
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(propertyFileName);
Spring will always look for recources under recources folder directly, in this case its unable to load the file as its in the custom folder and its not under classpath.
How do we explicitly set the custom folder as additional classpath folder?
With maven we could do something like below which works fine. Is there any OOTB way to achieve this with annotation in spring boot?
`<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/resources/config</directory>
</resource>
</resources>`
Updated
`// This works if config.properties is directly under resource folder
// What if config.properties is under resources/config folder.
// Dont say to pass argument as /config/config.properties, there are some other limitations.
// So in that case with the same approach, config should come under classpath, so that the below
// method will work always when the property name is passed.
// As mentioned earlier, we can use maven resource settings to achieve this.
// The question here is, is there any way to explicitely advise spring to load property from this folder.
// I have seen something like loader.path config, not sure that helps!
InputStream stream = SpringBootStarter.class.getResourceAsStream("/config.properties");`
Before answering, when you say: Spring will always look for recources under recources folder directly, in this case its unable to load the file as its in the custom folder and its not under classpath., this is not correct.
Spring can look anywhere on your system. Here is how you can load different properties file with Spring and Spring boot:
#PropertySource("classpath:config/common.properties") => Will look under the class path for a file located under the config folder, at the root of your classpath.
#PropertySource("file:/config/common.properties") => Will look for the file common.properties at the root of your filesystem, here under /config/common.properties.
Now, there is the question of "what is the classpath", it seems like it is worth more explanation.
The classpath is for the JVM what the filesystem is for your OS. When you execute some java code (.jar file for instance), the JVM stores all the files you specify. You can specify files when executing java -classpath /a/shared/folder,/a/dependency/app.jar,myApp.jar MainClass. (See this for some others ways: https://javarevisited.blogspot.com/2012/10/5-ways-to-add-multiple-jar-to-classpath-java.html).
Quite often, what happens for developers (before we use Spring) was this:
We develop our application, and use maven for managing the dependencies
We execute our app with the IDE, everything works just as fine, life is wonderful
We are ready to go live (in production). We generate the famous myApp.jar and try executing the application java -jar myApp.jar and... Nothing works. You have issues with java (I assume you setup the main-class in the Manifest...) and you get something like Caused by: java.lang.ClassNotFoundException: my.dependency.OtherClass...
Finally, you realize life is hard and you are not ready to go live right now. You need to have something you can execute easily.
One possible solution to this, to avoid having classpath issues is to put everything in your JAR (called in spring-boot the FAT jar) and you use java -jar myApp.jar and it is working fine.
By default, when you generate a maven project, automatically you have some folders included like:
src/main/java => your java files and packages
src/main/resources => your config files (like .properties)
src/test/java => Your java test files
src/test/resources => the resources handy for your tests
When you generate your jar (more or less every configuration you added to your maven project, but let's say it is okay), what happens is the compiler takes all the folders and files under src/main/java and src/main/resources and put them at the root of your jar. (Don't hesitate to have a look inside your jar files. This is just a Zip, you can open it, browse it, and see for yourself).
With that said, when you say How do we explicitly set the custom folder as additional classpath folder?, and you talk about a custom folder located under src/main/resources, then when you generate your Jar, the custom folder will be in jar, and therefor, in your classpath.
If you still have troubles, this actions will help you:
Unzip your jar files and check what is inside. If you don't see any config/ folder in it, maybe your Jar generation is wrong
Try using #PropertySource(...) to load properties file, in your classpath and in your filesystem, to see how it works and what you achieve
Have also a look to this:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
Don't hesitate to migrate more and more of your old code to Spring-boot, will be a lot easier for you.

Rename set of files using some patterns in maven

I need to rename set of files in maven without using Maven-Antrun-plugin in a single execution or command.
I have many property files with same suffix ab_bc.properties,de_bc.properties,etc and I need to replace the suffix to some other name like ab_BR.properties,de_BR.properties.
Is there any plugin available to do the same in Maven?
I tried Maven-assmbly plugin and copy-rename plugin but adding lot of files makes it more complex.
You can give this plugin a try or have a look on workarounds with the Maven Assembly plugin, see related question here.
Hope that helps :)

Set permissions on tar created by maven assembly plugin

With the Maven assembly plugin I know I can set the permissions of the files contained within my tar such as here. However can I use the plugin to set the permissions of the tar itself?
Maybe I should just the ant plugin but this is a little messy
I haven't tested this, but you might be able to use "exec-maven-plugin" to do this.
How to change permission of jar packaged by maven? I am using maven assembly plugin
"Use maven:exec plugin to execute chmod"
So the idea is that you would add another plugin to the pom.xml file that sets the permission on the tar itself.
The only drawback that I see is that you have to have the name of the file in the plugin xml code in the pom file. That's fine as I have that listed in in the maven-assembly-plugin. But the file extension is found in assembly.xml (.zip, or .tar-gz), so if you change the file extension in assembly.xml, you would have to remember to change it in the pom.xml file. Not a big hassle, but it might be easy to miss on your first review.

Activate a profile based on environment

Here's my scenario:
Maven 2.0.9 is our build system
We install code to multiple environments
All of our environment-specific properties are contained in property files, one for each environment
We currently read these properties into maven using the properties-maven-plugin; this sub-bullet is not a requirement, just our current solution
Goal:
Perform certain parts of the build (ie. plugin executions) only for certain environments
Control which parts are run by setting values in the environment-specific property files
What I've tried so far:
Maven allows plugins executions to be put inside pom profiles, which can be activated by properties; unfortunately these must be system properties - ie. from settings.xml or the command-line, not from properties loaded by the properties-maven-plugin
If possible, we'd like to keep everything encapsulated within the build workspace, which looks something like this:
project
pom.xml
src
...
conf
dev.properties
test.properties
prod.properties
build-scripts
build.groovy <-- the script that wraps maven to do the build
install.groovy <-- ... wraps maven to do the install
Running a build looks like:
cd build-scripts
./build.groovy
./install.groovy -e prod
Is there any possible way to accomplish these goals with the version of maven we are using? If not, is it possible with a newer version of maven?
This isn't possible using just Maven. (See also How to activate profile by means of maven property?) The reason is that profiles are the first thing evaluated before anything else to determine the effective POM.
My suggestion is to write some preprocessor that parses your environment specific property files and converts them to the required system properties before launching Maven. This script can be included in your ~/.mavenrc so that it runs automatically before Maven is launched. Here is an example script that that assumes the properties file is in a fixed location:
properties=`cat /etc/build-env.properties`
while read line; do
MAVEN_OPTS="$MAVEN_OPTS -D$line"
done <<< "$properties"
If the properties file is not fixed, you'll just need to add something to the script to discover the location (assuming it is discoverable).

Does Maven Have a mechanism to read the machine name

I'm writing a Maven project and I'd like to include a file in the generated WAR that will contain some build time information. Typically this will be things like
The build time/date stamp
The user name of the person who built the WAR
The version of the app as specified in the POM
These are all fairly easy as there are maven properties which will give me the information I need.
I'd also like to include the machine name. I know Windows stores this information in an environment variable called "COMPUTERNAME", while *nix uses the hostname command.
Is there some platform independent way of grabbing this information so that I can write it into my text file?
I did this by invoking the Maven Ant task. Within that I used the following Ant tasks:
<tstamp> to generate a timestamp property
<propertyfile> to create a properties file containing properties like the above timestamp, the username etc.
You could use the Ant <exec> task to execute hostname and nominate an output property to write this value into.
This created a properties file in the src/main/resources dir that I then embedded in the .war file
As Andrew Logvinov says,
Look up hostname from Maven
Thanks :-)

Resources