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.
Related
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)?
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.
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.
What is the 'best practice' way of separating Maven deployment configuration from the build config?
I have a war project, that is built by Jenkins. I'd like Jenkins to deploy this to Elastic Beanstalk, but alas the best solution available at the moment is to use the beanstalk-maven-plugin.
I'm not sure it makes sense for the POM.xml to include information about deployment; after all, at build time that .war could end up anywhere.
In this situation, is there some way of using Maven modules to store the beanstalk-maven-plugin config in a separate POM to that of the actual software project?
I think you have to solutions.
Just add the beanstalk-maven-plugin definition to your regular pom.xml. The configuration can be stored in separate properties file or provided via system properties in command line (-D option). Add beanstalk goal to command line of maven in Jenkins. So, each build will be deployed on beanstalk. Alternatively you can define yet another project in Jenkins that just runs the deployment without compilation. You can run this deployment project on scheduled basis or via projects dependencies in Jankins.
Create yet another maven project. It will just run beanstalk plugin. I personally do not see serious advantages to do this.
I think about three things:
a. I'm not sure (I'm admit I was a bit busy trying to come up with 0.2.7-RC7), but I think the Elastic Beanstalk Configuration Files are supported in Java.
So it perhaps could be a good idea to separate (I admit managing config in Beanstalker is Boring)
b. Another option is using war overlays in maven-war-plugin's overlay feature, and create a war which depends on your other war.
In my personal case, if you ask, I do have a separate deployment profile in Maven, and that feature often come in handy
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.