Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 15 Next »

Overview

In a corporate environment it makes sense to have some control over the setup of Maven.
For example:

  • restricting dependencies to approved versions of artifacts
  • reducing network bandwidth by having a maven repository proxied
  • sharing corporate assets by deploying them centrally

These scenarios can be realized by using internal Maven repositoriesand a Maven proxy. Be very careful not to confuse these two concepts as both services are often located on the same physical machine and it is easy to get them mixed up.

This guide will recommend installing both the Maven internal repositories and the Maven proxy on a single machine and to make this guide a bit more readable this machine will be called NUCLEUS.

To get an overview of repositories please read http://maven.apache.org/guides/introduction/introduction-to-repositories.html

For another example of repository setup with diagrams showing this configuration see http://cvs.peopleware.be/training/maven/maven2/repositories.html

Definitions of Repositories

A repository holds Maven artifacts in a well defined directory structure.

The purpose of the repository influences the types of resources that are stored in that repository.

The following list attempts to define the different terms used when discussing different repository types.

local repository

The directory structure on your local machine which stores all the artifacts required by all the projects on your system.

It is a cache of artifacts from remote repositories for any mvn command you have run.

remote repository

A remote repository is where the user may get artifacts from. A remote repository can be located anywhere and accessed by any protocol supported by Wagon (ftp/scp/http/file/...)

intranet repository

A remote repository inside your firewall, i.e. a repository not on your machine but in the confines of your organization.

You might have internal release/snapshot repositories as well.

private repository

Same as #internal repository.

central repository

A special remote repository which is situated at http://www.ibiblio.org/maven2/.

This remote repository is where most open source software artifacts are located.

release repository

A release repository is a remote repository specifically for housing released code.

No snapshots should be stored in this repository.

snapshot repository

A snapshot repository is a remote repository specifically for housing non-release code as snapshots should not be stored with released artifacts.

Using Maven in a corporate environment

Prerequisites

A web server already running and configured on NUCLEUS.

A web server is needed so that the internal repositories can be accessed from the local desktops.

scp access to NUCLEUS

It is out of scope for this guide to walk through setting scp up on the server.

The local desktop will need a SSH client which are available for Unix at http://www.openssh.com/ and Windows at http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html

Shell access to NUCLEUS

Shell access is needed to exectute commands and to configure the initial repository layout. This may be done in conjunction with a sysadmin if you do not have the required privileges.

Write access to a web server visible directory.

In this guide the Maven repositories will be installed into a location that has been configured for access by your web server.

This guide will use the location WEB_ROOT/maven2_repositories.

Create the repositories

The following artifacts are ones stored in a corporate environment:

  • inhouse released
  • inhouse snapshot
  • external non free - Oracle JDBC, J2EE stuff
  • external free - free but with annoying license restrictions so they can not be housed on ibiblio. Or any other projects not yet on ibiblio (in which case file a request to get it loaded into ibiblio see http://maven.apache.org/guides/mini/guide-ibiblio-upload.html)

Note: these categories are paraphrased from the Proximity web site https://is-micro.myip.hu/projects/ismicro-commons/proximity/configuration.html

The corporate environment should only contain artifacts as categorised above, any other artifacts should be obtained from the proper repository and not be duplicated in the corporate repository.
However these remote non-corporate environment repositories may be proxied. See #Creating a Maven proxy. Remember a proxy and a repository are different concepts.

In this guide the logically different artifacts are stored in physicall separate repositories. There is no physical reason why you could not store them within the one repository but to make it obvious were artifacts have come from they are separated.

In the WEB_ROOT/maven2_repositories directory (which your sysadmin has already created) create these directories:

  • inhouse
  • inhouse_snapshot
  • external_free
  • external_non_free

If you are on a Unix machine ensure that the WEB_ROOT/maven2_repositories directory has g+ws permission (the s bit ensures that files and directories created will have the same group access control).

Configure settings.xml

Now that the repositories have been created, each deployer's settings.xml file will need to specify these repositories in the server section:

Note: There appears to be some bugs with permissions not being set. You may need to manually set the permissions after running deployment commands.
TODO: Link to JIRA bug if there is one, and/or create it.

<servers>
    ...
        <server>
            <id>inhouse</id>
            <username>DEVELOPERS_USERNAME</username>
            <privateKey>PATH/TO/SSH.key</privateKey>
            <filePermissions>664</filePermissions>
            <directoryPermissions>775</directoryPermissions>
        </server>

        <server>
            <id>inhouse_snapshot</id>
            <username>DEVELOPERS_USERNAME</username>
            <privateKey>PATH/TO/SSH.key</privateKey>
            <filePermissions>664</filePermissions>
            <directoryPermissions>775</directoryPermissions>
        </server>

        <server>
            <id>external_free</id>
            <username>DEVELOPERS_USERNAME</username>
            <privateKey>PATH/TO/SSH.key</privateKey>
            <filePermissions>664</filePermissions>
            <directoryPermissions>775</directoryPermissions>
        </server>

        <server>
            <id>external_non_free</id>
            <username>DEVELOPERS_USERNAME</username>
            <privateKey>PATH/TO/SSH.key</privateKey>
            <filePermissions>664</filePermissions>
            <directoryPermissions>775</directoryPermissions>
        </server>
    ....
    </servers>

 

Deploy artifacts into a repository

Deploying inhouse artifacts

Inhouse artifacts should have the correct sections of the pom completed so that the deploy goal will work without having to specify any extra arguments.

...
    <distributionManagement>
        <repository>
            <id>inhouse</id>
            <name>Inhouse Internal Release Repository</name>
            <url>
                scp://NUCLEUS/PATH/TO/WEB_ROOT/maven2_repositories/inhouse</url>
        </repository>
        <snapshotRepository>
            <id>inhouse_snapshot</id>
            <name>Inhouse Internal Snapshot Repository</name>
            <url>
                scp://NUCLEUS/PATH/TO/WEB_ROOT/maven2_repositories/inhouse_snapshot</url>
            <uniqueVersion>true</uniqueVersion>
        </snapshotRepository>
    </distributionManagement>
...

 

The "uniqueVersion" setting defaults to true and will mean that the uploaded snapshot will look like:

<artifactId>-<version>-<yyyyMMdd.HHmmss>-<buildNumber>

 

instead of just

<artifactId>-<version>

 

To deploy the artifact run: (Note: use -N if you don't want maven to run in recursive mode)

mvn deploy

 

Deploying external free or external non free artifacts

External free (ones not available from ibiblio because of annoying license restrictions) and external non free artifacts can be deployed to their respective repository.

Since these are normally well versioned jar files there is no need for any snapshots in these repositories.

Additional documentation on the deploy goal is available at http://maven.apache.org/plugins/maven-deploy-plugin/deploy-file-mojo.html.

Consider the example of deploying the WebLogic jars. The WebLogic jar is an external non free jar and therefore needs to be deployed into the external_non_free repository.
Assume that the version of WebLogic is 8.1sp5 and the weblogic.jar is in the current directory then use the following command:

Note: The trailing slashes are used to represent the command continues onto the next line. This works fine on Unix but not on Windows. You will need to ensure that this command is all on one line with the trailing slashes removed.

mvn deploy:deploy-file -DgroupId=weblogic -DartifactId=weblogic -Dversion=8.1.5 \
  -DgeneratePom=true \
  -Dpackaging=jar \
  -Dfile=weblogic.jar \
  -DrepositoryId=external_non_free \
  -Durl=scp://NUCLEUS/PATH/TO/WEB_ROOT/maven2_repositories/external_non_free

 

Defining repositories in settings.xml

By defining these repositories in the settings.xml they will automatically get checked for artifacts. An alternative is to define these directly in your project's pom.xml file.
Since each developer needs to modify their settings.xml using the pom.xml might be a better choice.

Note that these repositories do not contain any Maven plugins and if plugins are needed then the pluginRepositories section will need to be completed with appropriate details.
Inhouse Corporate plugins are likely to be the only ones needing a repository definition.

The profile "repositoryDefinitions" is made active, but "inhouseSnapshot" is de-active by default.
If you want your project to be built against snapshot versions then activate the profile on the mvn command line via "-PinhouseSnapshot".

...
    <profiles>
        <profile>
            <id>repositoryDefinitions</id>
            <repositories>
                <repository>
                    <id>inhouse</id>
                    <name>Inhouse Repository</name>
                    <url>http://NUCLEUS/maven2_repositories/inhouse</url>
                    <releases>
                        <enabled>true</enabled>
                    </releases>
                    <snapshots>
                        <enabled>false</enabled>
                    </snapshots>
                </repository>
                <repository>
                    <id>external_free</id>
                    <name>External Free Repository</name>
                    <url>http://NUCLEUS/maven2_repositories/external_free</url>
                    <releases>
                        <enabled>true</enabled>
                    </releases>
                    <snapshots>
                        <enabled>false</enabled>
                    </snapshots>
                </repository>
                <repository>
                    <id>external_nonfree</id>
                    <name>External Non-Free Repository</name>
                    <url>http://NUCLEUS/maven2_repositories/external_non_free</url>
                    <releases>
                        <enabled>true</enabled>
                    </releases>
                    <snapshots>
                        <enabled>false</enabled>
                    </snapshots>
                </repository>
            </repositories>
        </profile>
        <profile>
            <id>inhouseSnapshot</id>
            <repositories>
                <repository>
                    <id>inhouse_snaphot</id>
                    <name>Inhouse Snapshot Repository</name>
                    <url>http://NUCLEUS/maven2_repositories/inhouse_snapshot</url>
                    <releases>
                        <enabled>false</enabled>
                    </releases>
                    <snapshots>
                        <enabled>true</enabled>
                        <updatePolicy>always</updatePolicy>
                    </snapshots>
                </repository>
            </repositories>
        </profile>
        ...
    </profiles>
  ...
  <activeProfiles>
    <activeProfile>repositoryDefinitions</activeProfile>
  </activeProfiles>

 

Conclusion

After following this guide you should have four internal repositories configured for your corporate environment:

  • inhouse
  • inhouse_snapshot
  • external_free
  • external_non_free

You can deploy your snapshot artifacts to the inhouse_snapshot repository, your released artifacts to the inhouse repository and populate the external_free and external_non_free repositories with jar files as needed.

The settings.xml file has a lot of verbose information in it now. It would be nice if this could be cleaned up somehow.
The server section can't be changed as this will be needed whenever you deploy to one of the defined servers. However the repositoryDefinitions profile section can be made simpler by using a proxy infront of the internal repositories.

Creating a Maven proxy

A Maven proxy can be thought of as a Maven mirror that aggregates one or more Maven repositories.

This document will walk through the setup of maven-proxy http://maven-proxy.codehaus.org/. At least one other alternative exists called Proximity https://is-micro.myip.hu/projects/ismicro-commons/proximity/projects-overview.html however I found the documentation to be sparse or non existant as of 2006-01-13.

Additional installation instructions can be found at http://docs.codehaus.org/display/MAVEN/MAVEN-PROXY

Prerequisites

Shell access to NUCLEUS

Shell access is needed to exectute commands and to configure the maven proxy. This may be done in conjunction with a sysadmin if you do not have the required privileges.

Build 0.2 of maven-proxy

See http://maven-proxy.codehaus.org/Downloads for access to http://dist.codehaus.org/maven-proxy/distributions/maven-proxy-standalone-0.2.zip

maven-proxy.properties configuration file.

Up to date configuration properties file can be found at http://maven-proxy.codehaus.org/Configuration.

An already configured instance of the maven-proxy.properties for maven-proxy 0.2 configuration file is as below.
The only changes needed are:

  • replace WEB_ROOT with the correct path details
  • decide whether to allow non-local access to web configuration pages. If yes, then change serverName to the host details of the machine instead of localhost.
################
# This file IS NOT DOCUMENTED, it is taken from
# maven-proxy/core/src/test/resources/org/apache/maven/proxy/config/PropertyLoaderTest1.properties
# and configured to match http://docs.codehaus.org/display/MAVENUSER/Using+Maven+in+a+corporate+environment
#
# You will need to globally replace WEB_ROOT to be the full path to where
# the maven2 repositories are located.  As per the above document these directories
# live under the web server root directory.
#
# If you want remote browsing of the maven-proxy repository then you must
# configure serverName to be something other than localhost.
################

################ GLOBAL SETTINGS
# This is where maven-proxy stores files it has downloaded
repo.local.store=WEB_ROOT/maven2_repositories/maven_proxy

#The port to listen on - not used if loaded as a webapp
port=9999

#This is the base area that all files are loaded from. While it is possible to leave this blank, this behaviour
#is deprecated and will be disabled in version 2.0.  There are too many namespace conflicts caused by not using
#a prefix.
#The repository will be shown at http://localhost:9999/repository/
#for the .war loaded into a webapp server, the default prefix is "repository" (edit the web.xml to change)
# As maven doesn't like a trailing slash, this address shouldn't have one either.
prefix=repository

#This is the simple date format used to display the last modified date while browsing the repository.
lastModifiedDateFormat=yyyy/MM/dd HH:mm:ss

################ SNAPSHOT HANDLING
#If you want the proxy to look for newer snapshots, set to true
snapshot.update=true

################ M2 METADATA HANDLING
#If you want the proxy to prevent looking for newer metadata, set to false (default is true)
#metadata.update=false

################ M2 POM HANDLING
#If you want the proxy to look for newer POMs, set to true (default is false)
pom.update=true

################ PROMOTION HANDLING
# ***** NOT CURRENTLY IMPLEMENTED *****
#Promotion describes the process by which new artifacts are loaded to global maven-proxy repository.  It
# is designed to be used by "higher security installations" that do not want to acquire artifacts from
# remote repositories without approval.
#
#If promotion handling is enabled, then the proxy will not download remote artifacts without permission
# (local repositories with copy=false are considered to be local)
#
#Permission to download is granted via the Promotion menu which will be enabled
#  when promotion handling is enabled.
#
#If promotion is false, artifacts are sourced from any repository as per normal.
#
#Promotion and snapshots:  If promotion is enabled, snapshots are not downloadable.  The concept of using
# a snapshot in a production build (which is primarily what promotion is for) is counterintuitive.
##
promotion=false

################ WEB INTERFACE
# This defines the absolute URL the server should use to identify itself.
# This can often be determined automatically, but we recommend you specify
# it explicitly to prevent problems during startup.
# The prefix will be added to this for the actual repository
# i.e. proxy available at http://localhost:9999/, repository at http://localhost:9999/repository
serverName=http://localhost:9999

#If true, the repository can be browsed
browsable=true

#If true, the repository can be searched
searchable=true

#Not currently implemented. Will allow webdav access to the repository at some point.
webdav=true

#Stylesheet - if configured, will override the default stylesheet shipped with maven-proxy - absolute URLs only
#eg.  /maven-proxy/style.css, http://www.example.com/style.css
stylesheet=/maven-proxy/style.css

#bgColor / bgColorHighlight are replaced in the built in stylesheet to produce a simple color scheme.
#If a stylesheet is set, these are not used.
bgColor=#14B
bgColorHighlight=#94B

#rowColor / rowColorHighlight are replaced in the built in stylesheet to produce a simple color scheme.
#If a stylesheet is set, these are not used.
rowColor=#CCF
rowColorHighlight=#DDF


################ PROXIES
#Note: Proxies are only needed for external repositories.
#If you need to use a proxy to get Internet access to an external repository
#then in the repository definition section you must also specify which proxy that repository should use.
#e.g. repo.www-ibiblio-org.proxy=one

#This is just a hack, it should auto discover them (but it currently doesn't)
#proxy.list=one,two,three

#Unauthenticated proxy
#proxy.one.host=proxy1.example.com
#proxy.one.port=3128

#Authenticated proxy
#proxy.two.host=proxy2.example.org
#proxy.two.port=80
#proxy.two.username=username2
#proxy.two.password=password2

#Authenticated proxy
#proxy.three.host=proxy3.example.net
#proxy.three.port=3129
#proxy.three.username=username3
#proxy.three.password=password3


################# REPOSITORIES
#This is not just a hack, it specifies the order repositories should be checked
#Note that the proxy adds a "/" which is why the urls aren't suffixed with a "/"
repo.list=inhouse,inhouse_snapshot,external_free,external_non_free,www-ibiblio-org,dist-codehaus-org

#inhouse
repo.inhouse.url=file:///WEB_ROOT/maven2_repositories/inhouse
repo.inhouse.description=inhouse released artifacts
#If copy is true, jars are copied from the store to the proxy-repo. Only configurable for file:/// repos
repo.inhouse.copy=false
#If hardfail is true, any unexpected errors from the repository will cause
#the client download to fail (typically with a 500 error)
repo.inhouse.hardfail=true
#Don't cache a file repository
repo.inhouse.cache.period=0

#inhouse_snapshot
repo.inhouse_snapshot.url=file:///WEB_ROOT/maven2_repositories/inhouse_snapshot
repo.inhouse_snapshot.description=inhouse snapshot artifacts
#If copy is true, jars are copied from the store to the proxy-repo. Only configurable for file:/// repos
repo.inhouse_snapshot.copy=false
#If hardfail is true, any unexpected errors from the repository will cause
#the client download to fail (typically with a 500 error)
repo.inhouse_snapshot.hardfail=true
#Don't cache a file repository
repo.inhouse_snapshot.cache.period=0

#external_free
repo.external_free.url=file:///WEB_ROOT/maven2_repositories/external_free
repo.external_free.description=external free artifacts, but with annoying license restrictions so they can not be housed on ibiblio.
#If copy is true, jars are copied from the store to the proxy-repo. Only configurable for file:/// repos
repo.external_free.copy=false
#If hardfail is true, any unexpected errors from the repository will cause
#the client download to fail (typically with a 500 error)
repo.external_free.hardfail=true
#Don't cache a file repository
repo.external_free.cache.period=0

#external_non_free
repo.external_non_free.url=file:///WEB_ROOT/maven2_repositories/external_non_free
repo.external_non_free.description=external non free artfiacts
#If copy is true, jars are copied from the store to the proxy-repo. Only configurable for file:/// repos
repo.external_non_free.copy=false
#If hardfail is true, any unexpected errors from the repository will cause
#the client download to fail (typically with a 500 error)
repo.external_non_free.hardfail=true
#Don't cache a file repository
repo.external_non_free.cache.period=0

#www.ibiblio.org
#Maven1 Repository
#repo.www-ibiblio-org.url=http://www.ibiblio.org/maven
#Maven2 Repository
repo.www-ibiblio-org.url=http://www.ibiblio.org/maven2
repo.www-ibiblio-org.description=www.ibiblio.org
#If hardfail is true, any unexpected errors from the repository will cause
#the client download to fail (typically with a 500 error)
repo.www-ibiblio-org.hardfail=true
#Cache this repository for 1 hour
repo.www-ibiblio-org.cache.period=3600
repo.www-ibiblio-org.cache.failures=true
#If a Proxy is needed, which one?
#repo.www-ibiblio-org.proxy=one

#dist.codehaus.org
repo.dist-codehaus-org.url=http://dist.codehaus.org
#If hardfail is true, any unexpected errors from the repository will cause
#the client download to fail (typically with a 500 error)
repo.dist-codehaus-org.hardfail=false
#Cache this repository for 1 hour
repo.dist-codehaus-org.cache.period=3600
repo.dist-codehaus-org.cache.failures=true
#If a Proxy is needed, which one?
#repo.dist-codehaus-org.proxy=one

 

Install maven-proxy on NUCLEUS

Get your systems administrator to install maven-proxy.
See http://docs.codehaus.org/display/MAVEN/MAVEN-PROXY for additional instructions on how to do this.

Run maven-proxy

Run maven proxy with your maven-proxy.properties file specified.

Update settings.xml

<mirrors>
        ...
        <mirror>
            <id>maven-proxy</id>
            <name>Maven-Proxy Mirror</name>
            <url>http://NUCLEUS:9999/repository/</url>
            <mirrorOf>central</mirrorOf>
        </mirror>
    </mirrors>

 

Run maven

Maven should now connect to your installed maven-proxy to download artificats.
Remember on the first run the proxy's cache will be empty so the first run will be slower than usual.

Why proxy internal repositories?

People who do not deploy to the internal repositories do not need those repositories defined in settings.xml. They can use maven-proxy to retrieve those artifacts for them. The repositories external_free and external_non_free are internal repositories that only a few people need to deploy to, the rest can access via maven-proxy.

An oustanding uncertainty is the <mirrorOf> section defines "central". So if a person does not have all the repositories defined in settings.xml will they still contact maven-proxy for external_free?? Need to check this.

  • No labels