How to Set up a Consistent Developer Environment
Consistency is important when establishing a shared development environment. Without it, the set up process for a new developer can be slow, error-prone and full of omissions. Additionally, because the environment will tend to evolve inconsistently once started that way, it will be the source of time-consuming development problems in the future.
While one of Maven’s objectives is to provide suitable conventions to reduce the introduction of inconsistencies in the build environment, there are unavoidable variables that remain, such as different installation locations for software, multiple JDK versions, varying operating systems, and other discrete settings such as user names and passwords.
To maintain build consistency, while still allowing for this natural variability, the key is to minimize the configuration required by each individual developer, and to effectively define and declare them. In Maven, these variables relate to the user and installation settings files, and to user-specific profiles.
In Chapter 2, you learned how to create your own settings.xml file. This file can be stored in the conf directory of your Maven installation, or in the .m2 subdirectory of your home directory (settings in this location take precedence over those in the Maven installation directory). The settings.xml file contains a number of settings that are user-specific, but also several that are typically common across users in a shared environment, such as proxy settings.
In a shared development environment, it’s a good idea to leverage Maven’s two different settings files to separately manage shared and user-specific settings. Common configuration settings are included in the installation directory, while an individual developer’s settings are stored in their home directory.
The following is an example configuration file that you might use in the installation directory, <maven_home>/conf/settings.xml:
<settings>
<proxies>
<proxy>
<active>true</active>
<protocol>http</protocol>
<host>proxy</host>
<port>8080</port>
</proxy>
</proxies>
<servers>
<server>
<id>website</id>
<username>${website.username}</username>
<filePermissions>664</filePermissions>
<directoryPermissions>775</directoryPermissions>
</server>
</servers>
<profiles>
<profile>
<id>default-repositories</id>
<repositories>
<repository>
<id>internal</id>
<name>Internal Repository</name>
<url>http://repo.mycompany.com/internal/</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>internal</id>
<name>Internal Plugin Repository</name>
<url>http://repo.mycompany.com/internal/</url>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>property-overrides</activeProfile>
<activeProfile>default-repositories</activeProfile>
</activeProfiles>
<pluginGroups>
<pluginGroup>com.mycompany.plugins</pluginGroup>
</pluginGroups>
</settings>
There are a number of reasons to include these settings in a shared configuration:
- If a proxy server is allowed, it would usually be set consistently across the organization or department.
- The server settings will typically be common among a set of developers, with only specific properties such as the user name defined in the user’s settings. By placing the common configuration in the shared settings, issues with inconsistently-defined identifiers and permissions are avoided.
- The mirror element can be used to specify a mirror of a repository that is closer to you, which is typically one that has been set up within your own organization or department. See section 7.3 of this chapter for more information on creating a mirror of the central repository within your own organization.
- The profile defines those common, internal repositories that contain a given organization’s or department’s released artifacts. These repositories are independent of the central repository in this configuration. See section 7.3 for more information on setting up an internal repository.
- The active profiles listed enable the profile defined previously in every environment. Another profile, property-overrides is also enabled by default. This profile will be defined in the user’s settings file to set the properties used in the shared file, such as
${website.username}. - The plugin groups are necessary only if an organization has plugins, which are run from the command line and not defined in the POM.
You’ll notice that the local repository is omitted in the prior example. While you may define a standard location that differs from Maven’s default (for example, ${user.home}/maven-repo), it is important that you do not configure this setting in a way that shares a local repository, at a single physical location, across users. In Maven, the local repository is defined as the repository of a single user.
The previous example forms a basic template that is a good starting point for the settings file in the Maven installation. Using the basic template, you can easily add and consistently roll out any new server and repository settings, without having to worry about integrating local changes made by individual developers. The user-specific configuration is also much simpler as shown below:
<settings>
<profiles>
<profile>
<id>property-overrides</id>
<properties>
<website.username>myuser</website.username>
</properties>
</profile>
</profiles>
</settings>
To confirm that the settings are installed correctly, you can view the merged result by using the following help plugin command:
C:mvnbook> mvn help:effective-settings
Separating the shared settings from the user-specific settings is helpful, but it is also important to ensure that the shared settings are easily and reliably installed with Maven, and when possible, easily updated. The following are a few methods to achieve this:
- Rebuild the Maven release distribution to include the shared configuration file and distribute it internally. A new release will be required each time the configuration is changed.
- Place the Maven installation on a read-only shared or network drive from which each developer runs the application. If this infrastructure is available, each execution will immediately be up-to-date. However, doing so will prevent Maven from being available off-line, or if there are network problems.
- Check the Maven installation into CVS, Subversion, or other source control management (SCM) system. Each developer can check out the installation into their own machines and run it from there. Retrieving an update from an SCM will easily update the configuration and/or installation, but requires a manual procedure.
- Use an existing desktop management solution, or other custom solution.
If necessary, it is possible to maintain multiple Maven installations, by one of the following methods:
- Using the
M2_HOMEenvironment variable to force the use of a particular installation. - Adjusting the path or creating symbolic links (or shortcuts) to the desired Maven executable, if
M2_HOMEis not set.
Configuring the settings.xml file covers the majority of use cases for individual developer customization, however it applies to all projects that are built in the developer’s environment. In some circumstances however, an individual will need to customize the build of an individual project. To do this, developers must use profiles in the profiles.xml file, located in the project directory. For more information on profiles, see Chapter 3.
Now that each individual developer on the team has a consistent set up that can be customized as needed, the next step is to establish a repository to and from which artifacts can be published and dependencies downloaded, so that multiple developers and teams can collaborate effectively.