What is the maven standard to make different kind of builds? - java

I have a build cycle that is quite uncommon for Maven, and I don't know if I'm missing a feature or something.
I have a product that has 6 combinations of builds (for now), not mentioning the builds that vary depending on the environment set in the profiles (development, testing, release).
These combinations actually are the result of two variables, which are the application server that it'll run (Weblogic or JBoss), and the other is the database to be used (Oracle, PostgreSQL, MySQL). When I release that, I need to archive the 6 different .war combinations into a Nexus repository through a Jenkins build.
Each type of build changes 8-10 variables to make a proper build for the environment to be deployed.
I wanted something simple to change, just like the profile option, so I would change once just one variable and all the variables of the build would change automatically.
The only way to do this is making 6 different profiles for each environment resulting on 18 profiles like development-weblogic-mysql, release-jboss-postgresql, etc.?
Or there is a feature in Maven that I'm missing?

you can specify partial profiles for app container, db and environment
Then activate multiple profiles when building for example:
mvn package -P weblogic,mysql,development
also should you be doing environment specific builds (development/release/test)?

Related

Maven dependency based on argument

I have a Maven project with a number of modules. When building, I have an argument that determines which directory config files and such are copied from, depending on environment it will be running in - ie UAT, DEV, TEST, etc. I do not want to use profiles. Now, I want to package all integration tests into a separate jar that can be executed from command line as well as in integration-test phase. Basically there will be only one test class with one method that does something like
Class.forName("...").getMethod("main").invoke(null, args);
Only problem, is that since I do not want to use profiles Id have to add/remove the dependency on the test solution jar depending on if I want to run integration tests or not. I would like to do something like
mvn clean install -Denv=IT
and let it be. Is there a way to do so?
The standard mechanism for running different kinds of build in Maven is to use profiles (Maven is a highly opinionated build framework, so you are forced to play by its rules)
Your also appear to be building binaries to match the system you intend to deploy. This is generally a bad idea, you are better advised to look at some mechanism that allows the run-time configuration of your application. (In J2EE there is JNDI, but could be just a simple property file). This allows you to certify a single binary that ideally is pushed into a shared repository for sharing between development, test and production.

Switch between development and production in a java webapp

My team develops a Vaadin web application. When we are giving a release for production, we have to manually make several changes in few files before building the war file. For an example, we have to change log4j settings in log4j2.xml and set vaadin productionMode to true in web.xml.
We are using Intellij IDEA for development. We build the webapp using Maven
Is there a better way to keep two build modes so that we can easily switch between production and development mode?
If your intention is to generate different deliverables of each one of your environments, a posible solution is to use Maven profiles.
http://maven.apache.org/guides/introduction/introduction-to-profiles.html
If you define different profiles with a different set of resources for each one, say 'AVE', 'UAT', 'NFT', whatever, you can then call Maven with a designated profile in order to generate the application you need
mvn clean deploy -P AVE
mvn clean deploy -P UAT
etc.
If you don't want to keep different versions of your *.properties and web.xml and maintain all of them (which would be a burden and quite error-prone), you can also use profiles, but combine it with filtering (http://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html) in order to keep only 1 copy of each properties, web.xml, etc. in your code. This way you can have some properties like 'productionMode' you mention depending on properties defined in the AVE, UAT, NFT, etc. profiles in your pom.xml.

Jenkins building for different environments

I currently have a Jenkins instance installed on a Development box. This builds fine and deploys to our development environment without any issues.
During the build process my project makes use of a single properties file containing details such as a database connection URL (Details such as these will obviously vary depending on the environment I'm pointing to).
What I would like to know is what is the best way to configure my project so that when I want to release to Production the WAR file built by Jenkins contains the Production properties instead of Development?
(Note I am also using Maven in my project).
I know 3 options:
We have used maven.-profiles for that in the past, but they have the disadvantage, that the release-plugin of maven doesn't work with profiles, so we had to change the versions manually and were unable to deploy the artifacts in a remote repository like nexus.
Another Option is mavens assembly-plugin. That can be used together with the release-plugin, as far as I know.
We decided to write a simple tool that changes the war-files after the maven-build process. It runs in a seperate Jenkins-Job. The Idea is, that building and configuring are two seperate steps. The Artifacts comming out of maven are always in a default-configuration. And if we need the configuration for the production release we start a jenkins job that does the configuration of the war-files.
You can create different maven profiles, like dev, prod, then in the profile setting, use/filter the corresponding resource files like .../(dev|test|prod)/project.properties And in Jenkins, when you build for different platform, build with -Pdev or -Pprod to get the war for the right target.
You may want to check maven profile, maven resource filtering for detailed configuration.
something not related, connect Database via jndi if possible.

build project into different repositories with different jdks

I am facing problem where I need to build same project into different local repositories where each repository is based on different JDK version (1.6 and 1.7). Is it possible to configure for example settings.xml and its profiles to be able build projects this way?
Modifying pom files is not a solution for me since there is quite large number of projects which should be prepared this way and I am not only one who works and updates pom files.
I found only solution for switching repositories via mvn call http://jira.codehaus.org/browse/MNG-3588
Maven uses JAVA_HOME variable to find the java compiler to be used. So one solution will be to set the JAVA_HOME appropriately on different environments.

How can I disable Maven install and deploy phases using profiles?

My Maven project contains 3 different profiles, dev, stage, and prod, that contain different configuration settings. I would like to make it so that the install and deploy phases cannot be executed (or execute but do nothing) if the active profile is not prod, to keep dev and stage builds out of the repo. Is there a way to do this?
I'm guessing it involves adding the <plugin> to the dev and stage profiles and manually binding it to a "none" phase or something like that.
If that's what you really want to do, then just run the "package" phase on dev and staging, and in your maven settings file the provided user should not have write privileges to the repository.
What I would recommend doing, though, is to keep your configuration files outside of the build artifact, so that you only have one build that gets promoted between environments. As part of a script for deploying a build, you can automatically copy the correct settings, getting a similar effect.
Regardless of whether how you want to do this is the best idea, what you could do is use the Maven Enforcer Plugin to validate that the profile property is set to the value of your 'prod' profile. The plugin binds by default to the validate phase, so you would need to bind it to the package phase, or only the 'prod' profile will be usable.
The specific recipe I would use for this:
There's a built-in rule called requireProperty you can use to make assertions on properties and their values. You could set a property from your prod profile and then (outside any profile) configure the enforcer plugin to check to see that said property is set to the value you expect. This is hokie, however.
I strongly suggest that you externalize environment-specific configuration values into property placeholders and use profiles only to set those values rather than switching out environment-specific config files or affecting the contents of the artifact that you're generating.

Categories

Resources