Maven inject plugin settings.xml - maven

I'm currently setting up a CI/CD chain for multiple projects. I'd like to inject a maven plugin with every build of our Jenkins server (this one: https://github.com/cedricwalter/git-branch-renamer-maven-plugin). Is there a way to inject the plugin into a build without adding it to every pom.xml in every project?

You can do that with mavenSettings.xml using the profile section: https://maven.apache.org/settings.html
Then set that mavenSettings.xml to the Maven instalation used by Jenkins.
...
<profiles>
<profile>
<id>AllwaysOn</id>
<activation>
<activeByDefault>true</activeByDefault>
...
</activation>
<!-- add plugin config here -->
</profile>
</profiles>
...
Then you can add your specific plugin configuration there.

Related

How to deploy only part of a multi module maven project?

I have a multi-module maven project, and would like to deploy only 2 sub modules:
pom.xml // parent pom
module1
--pom.xml
module2
--pom.xml
module3
--pom.xml
only module1.jar and module2.jar should be deployed.
I have found the solution in the following question:
How to Deploy only the sub-modules using maven deploy?
The following property should be added to the pom.xml set to false for the modules that should not be deployed:
<properties>
<maven.deploy.skip>true<maven.deploy.skip>
<properties>
From my personal experience, we had a multi maven project. Where many modules was features that some clients had it and some other clients dint had them. For example when we build for 'clientA' we wanted Jenkins to package 'module1', 'module2' and 'module3' but when we build for 'clientB' we wanted only to package 'module1' and 'module2' to just give him the base functionality.
So, its not absolutely wrong to deploy/release part of a multi module project. In the above example there are a case where you need to build some of the modules and a case where you want to build all the modules. In those cases you can do that with profiles.
Example: in parent pom.xml
<profiles>
<profile>
<id>base-functionality</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<modules>
<module>/module1</module>
<module>/module2</module>
</modules>
</profile>
<profile>
<id>new-feature</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<modules>
<module>/module3</module>
</modules>
</profile>
</profiles>
and then on Jenkins job for "clientA":
clean package -Pbase-functionality,new-feature
where on Jenkins job for 'clientB':
clean package -Pbase-functionality
Note: as khmarbaise stated on comment below this approach has same pitfalls and should be avoided if possible.

In a Maven multi-module project, how can I run a full build and run a specific plugin on one child?

I have a multi-project maven project. One child only has a specific plugin and I want it to be optional (so not bound to a specific phase).
How can I run a full clean install on the entire project and additionally run a project's specific plugin?
I've encountered this post but it looks like an overkill, and it is not so easy in my specific case.
Your best option is to use maven build profiles.
In example, use this snippet in child module:
<profiles>
<profile>
<id>only-in-child-module</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
....
</plugins>
</build>
</profile>
</profiles>
This build profile will not be active unless you explicitly ask maven for it like:
mvn clean install -Ponly-in-child-module

Spring Set Production / Development level JDBC properties

I have a JDBC.properties file that contains db connection information
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.dialect=org.hibernate.dialect.MySQLDialect
jdbc.databaseurl=jdbc:mysql://127.0.0.1/mydb
jdbc.username=root
jdbc.password=
Now when I use it in the server my info changes
jdbc.username=root
jdbc.password=mypassword
What I do now is manually change this information before making war file and upload it to the server.
Now I was wondering if there is any way I could set this information so that i don't have to change this information every time before upload
How to do this??
Don't put your properties inside your war file. Externalize them. Put them somewhere in a well known path (/etc/myapp/jdbc.properties).
You shouldn't be creating different artifacts for your production,development and test environment. It should be the same. Recreating the artifact means a new version which (in theory) means new testing. Even if you use maven profiles.
The approach I tend to use is to put some defaults in an internal properties file and optionally load a file from outside the war. That way you provide your users with the possibility to override the default configuration.
<context:property-placeholder location="classpath:/jdbc.propertes,file:/etc/myapp/jdbc.properties" igonre-resource-not-found="true" />
That way your defaults are inside the application and users can override it by specifying other properties in the /etc/myapp/jdbc.properties file.
You could use spring profiles. This blog post should give you the idea: http://spring.io/blog/2011/02/11/spring-framework-3-1-m1-released/
You should use a build tool like Maven and do this with resource filtering and profiles.
Doing it through Spring profiles is probably one way, but in my opinion it makes more sense to be handling it through the build.
Consider the following with Maven:
src/main/resources/jdbc.properties:
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.dialect=org.hibernate.dialect.MySQLDialect
jdbc.databaseurl=${jdbc.databaseurl}
jdbc.username=${jdbc.username}
jdbc.password=${jdbc.password}
pom.xml:
<project ...>
...
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
...
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<jdbc.databaseurl>jdbc:mysql://127.0.0.1/mydb</jdbc.databaseurl>
<jdbc.username>username</jdbc.username>
<jdbc.password>password</jdbc.password>
</properties>
...
</profile>
<profile>
<id>prod</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<jdbc.databaseurl>jdbc:mysql://212.123.45.6/mydb</jdbc.databaseurl>
<jdbc.username>username</jdbc.username>
<jdbc.password>secret-password</jdbc.password>
</properties>
...
</profile>
</profiles>
...
</project>
For development, invoke:
mvn clean package ... -Pdev
Likewise for production:
mvn clean package ... -Pprod
Maven filtering allows you to replace properties in your .properties resources based on properties defined in Maven via <properties/> (either in a profile, or not).
References:
- Resource filtering
- Profiles

Maven: filtering seam components.xml in target directory

I'm trying to convert an Ant project to Maven. The existing build uses Ant-style properties in src/main/webapp/WEB-INF/components.xml, which is a Seam file.
I'm able to get the properties expanded in the actual resulting war file, via the maven-war-plugin. But I can't seem to get the properties expanded in target/myproject/WEB-INF/components.xml.
This means that when I try to run the Jetty plugin, it doesn't see the expanded properties.
I tried defining the properties in both an external file, and also right in the build. My profile section looks like the following:
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<filters>
<filter>src/main/filters/components-dev.properties</filter>
</filters>
</build>
<properties>
<debug>true</debug>
<jndiPattern>FOO</jndiPattern>
</properties>
</profile>
</profiles>
When you run mvn jetty:run it executes the lifecycle up through test-compile. The web resources don't get filtered until the war plugin runs as part of package. I found a question on stackoverflow that seems similar, does that solution work for you?

What is the best way to parameterize a Maven script to switch between Spring configurations?

What is the best way to parameterize a Maven script to switch between Spring configurations?
I have Maven building a WAR file for a web app. I have alternative spring configurations - one for integration testing with mock objects, one for live production use with real objects.
Ideally, I would like to have one Maven build script that can build either WAR file. At present, I just hack the spring config file before building, commenting in and out the mocks and real objects.
What is the best way to go about this?
I suggest that you use the build profiles.
For each profile, you will define a specific Spring configuration:
<profiles>
<profile>
<id>integration</id>
<activation>
<activeByDefault>false</activeByDefault>
<property>
<name>env</name>
<value>integration</value>
</property>
</activation>
<!-- Specific information for this profile goes here... -->
</profile>
<profile>
<id>production</id>
<activation>
<activeByDefault>false</activeByDefault>
<property>
<name>env</name>
<value>production</value>
</property>
</activation>
<!-- Specific information for this profile goes here... -->
</profile>
...
You will then activate one profile or the other by setting the parameter env : -Denv=integration for the first profile, -Denv=production for the second profile.
In each profile block, you can specify any information specific to your environment. You can then specify properties, plugins, and so on. In your case, you may change the configuration of the resources plugin in order to include the adequate Spring configuration. For example, in integration profile, you can specify where Maven will search the Spring configuration file:
<profile>
<id>integration</id>
<activation>
<activeByDefault>false</activeByDefault>
<property>
<name>env</name>
<value>integration</value>
</property>
</activation>
<build>
<resources>
<resource>/path/to/integration/spring/spring.xml</resource>
</resources>
</build>
</profile>

Resources