2. Arnaud Héritier
• eXo - Software Factory Manager
» In charge of tools and methods
• Apache Maven :
» Committer since 2004 and member of the
Project Management Committee
• Coauthor of « Apache Maven »
» published by Pearson (in French)
• Contact me :
» http://aheritier.net
» Twitter : @aheritier
» Skype : aheritier
2
4. Definition
• Apache Maven is a software project
management and comprehension tool.
• Based on the concept of a project object
model (POM)
» Maven can manage a project's build, binaries,
reporting and documentation from a central piece
of information.
• Apache Maven is standards/conventions
driven
» How many of you are doing JEE and related
developments ?
4
5. History
• Initiated in 2001 by Jason Van Zyl in Alexandria,
an Apache Jakarta project,
• Moved to Turbine few months after,
• Became a Top Level Project in 2003.
• Maven 2.0 released in September 2005
• Maven 3.0 released in October 2010
» 3.0.4 – January 2012
5
6. Choose your way of thinking
Conventions approach Scripting approach
6
7. Competitors
• Ant + Ivy, Easy Ant, Gant, Gradle, Buildr…
• Script oriented
» You can do what you want !
• Reuse many of Maven conventions (directories layout,
…) and services (repositories) but without enforcing
them
• The risk for them : Not being able to evolve due to the
too high level of customization proposed to the user.
» We tried on Maven 1 and it died because of that. It was
impossible to create a set of tests to cover all usages.
» It’s like providing a framework without a well tested set of
public API L
7
8. With scripts oriented builds
You can have But often you have
(if you have good skills) (moreover after years …)
8
9. With Maven
We dream to deliver But yesterday we too often had
(Maven 3.x) (Maven 2.x)
9
15. Reactor
• Split your project in
sub-modules <project>!
• Maven computes the ...!
build order from <modules>!
<module>moduleA</module>
!
dependencies <module>moduleB</module>
!
between sub- <module>moduleC</module>
!
modules. <module>moduleD</module>
!
<module>moduleE</module>
!
• Modules have to be <module>moduleF</module>
!
defined in the POM </modules>!
» No auto-discovery for ...!
performance reasons </project>!
15
16. Inheritance
• Share settings between
projects/modules
• By default the parent
project is supposed to
be in the parent
directory (../)
<parent>!
<groupId>net.aheritier.sample</groupId>!
<artifactId>my-parent</artifactId>!
<version>1.0.0-SNAPSHOT<version>!
</parent>!
16
17. Inheritance
Use a technical inheritance to organize sub-
modules
Use assembly to package batchs
Insert README in all artifacts
Use clirr to validate backward
compatibility
17
18. Artifact Repository
• By default :
» A central repository
• http://repo1.maven.org/
maven2
• Several dozen of Gb of OSS
libraries
» A local repository
• ${user.home}/.m2/repository
• All artifacts
• Used by maven and its
plugins
• Used by your projects
(dependencies)
• Produced by your projects
18
19. Artifact Repository
• By default Maven
downloads artifacts
required by the project
or itself from central
• Downloaded artifacts
are stored in the local
repository
• Used to store :
» Project’s binaries
» Project’s dependencies
» Maven and plug-ins
binaries
19
21. Dependencies
• Declaratives
» groupId + artifactId + version (+ classifier)
» Type (packaging) : jar, war, pom, ear, …
• Transitives
» Lib A needs Lib B
» Lib B needs Lib C
» Thus Lib A needs Lib C
21
22. Dependencies
• Scope
» Compile (by default) : Required to build and run the application
» Runtime : not required to build the application but needed at
runtime
• Ex : taglibs
» Provided : required to build the application but not needed at
runtime (provided by the container)
• Ex : Servlet API, Driver SGBD, …
» Test : required to build and launch tests but not needed by the
application itself to build and run
• Ex : Junit, TestNG, DbUnit, …
» System : local library with absolute path
• Ex : software products
22
23. Dependencies
• Define all dependencies you are using
» and no more !
• If you have optional dependencies
» Perhaps you should have optional modules
instead
• Cleanup your dependencies with
» mvn dependency:analyze!
• Study your dependencies with
» mvn dependency:tree!
» mvn dependency:list!
23
24. Versions
• Project and dependency versions
• Two different version variants
» SNAPSHOT version
• The version number ends with –SNAPSHOT
• The project is in development
• Deliveries are changing over the time and are overridden
after each build
• Artifacts are deployed with a timestamp on remote
repositories
» RELEASE version
• The version number doesn’t end with –SNAPSHOT
• Binaries won’t change
24
26. Versions
• About SNAPSHOT dependencies
» Maven allows the configuration of an update policy.
The update policy defines the recurrence of checks if
there is a new SNAPSHOT version available on the
remote repository :
• always
• daily (by default)
• interval:X (a given period in minutes)
• never
» Must not be used in a released project
• They can change thus the release also L
• The release plugin will enforce it J
26
27. Versions
• Range
» From … to …
» Maven automatically searches for the
corresponding version (using the update policy
for released artifacts)
» To use with caution
• Risk of non reproducibility of the build
• Risk of side effects on projects depending on yours.
27
28. Versions
• Use the versions plugin to update all versions
of your project and its modules
mvn versions:set –DnewVersion=A.B.C-SNAPSHOT!
28
29. Profiles
• Allow to modify the default behavior of Maven
by overriding/adding some settings
• Use mvn help:active-profiles to debug
• Explicit activation or deactivation
mvn <phases or goals> !
-PprofileId1,-profileId2 !
-P!profileId3!
29
30. Profiles
● activeByDefault = If no other profile is
activated
● Activation through Maven settings
<settings>!
...!
<activeProfiles>!
<activeProfile>profile-1</activeProfile>!
</activeProfiles>!
...!
</settings>!
30
36. Build Lifecycle And Plugins
• Many plugins
» Packaging
» Reporting
» IDE integration
» Miscellaneous tools integration
• Many locations
» maven.apache.org
» mojo.codehaus.org
» code.google.com
» …
Take care while selecting them !!!
36
39. Backward compatibility - Criticisms
• Migration from Maven 1 to Maven 2 was
impossible. Everything had to be re-done.
• Updates between 2.x versions and also
between 2.0.x weren’t often without side
effects.
39
40. Backward compatibility
• Near to 700 integration tests
• Tested for several months on a large set of
OSS projects
• 7 alphas + 3 betas versions
• A bug fix release every 6 weeks
• It’s a revolution under the hood but an
evolution for end users
40
43. Performances - Criticisms
• Maven is slow
• It spends its time to download the world
• Whereas everybody has multicore CPUs, it
doesn’t allow to process modules builds in
parallel
43
44. Performances
• A set of benchmark tools was developed to
measure Maven performances (IO, CPU,
Memory, Network …)
• Startup and execution times are reduced
» Java 5 optimizations
» Code cleanup and improvements
• Reduced Memory footprint
• Artifacts Resolution Caching
» .lastUpdated files in your local repo
» Enforce checks with –U option
44
45. Performances – Parallel builds
• Parallel builds
» An execution plan is predefined at startup to
define which modules could be built in //
» Requires to have up to date plugins to avoid dead
locks and some others issues
» Launch a build with 2 threads
• mvn –T 2 install
» Launch a build with 2 threads per CPU core
• mvn –T 2C install
45
46. Performances – mvnsh
• Performances optimizations
» Intelligent cache system (artifacts resolution,
project descriptors …)
» No need to restart a JVM for each build
• Cross platform « unix like » shell
» Alias, environment settings …
» Color highlighting
46
47. Performances – mvnsh
• All in one
» Includes Maven 3.x
» Allows to have color highlighting with “standard”
Maven 3.x
• Developed and freely distributed by Sonatype
47
50. Extensibility - Criticisms
• It is difficult and time consuming to extend
maven (write plugins)
» Many unknown technologies like Plexus for IOC
• It is difficult/impossible to reuse maven
plugins
» Its impossible to extend plugins/mojo and
lifecycles
50
51. Extensibility
• New APIs to improve abstraction of
underneath implementation
» Aether : to manage artifacts and repositories
• Plugin classloader partitioning
• Embeddable
• IOC replaced by Guice
» For now (3.0) a wrapper is hiding the change
» You don’t yet use Guice directly (from plugins for
example)
51
54. Robustness - Validations
• Many more validations in POMs (warnings or
errors)
» Missing plugins versions
» Duplicated dependencies in a POM
» Incoherent inheritance (wrong relative path or
parent not in the upper directory)
• Improved error messages with links to wiki
pages for more detailed information
54
55. Robustness – Artifacts management
• Parent POMs prefer to resolve from
repositories
» Version less parent will be available in a future
maven 3.x release by using the relativePath
element
• Profiles usage consolidation
» No more profiles.xml (incompatible with future
polyglot feature)
55
56. Robustness – Artifacts management
• No more support for legacy repository layout
for Maven 1.0
• SNAPSHOTs are always deployed with
timestamps
56
57. Robustness – Plugins management
• Plugin version is by default RELEASE and no
more SNAPSHOT
» Affects command-line invocation
• Plugins cannot use versions LATEST or
RELEASE
» Affects command-line invocation and POM
• Plugins are resolved only from
<pluginRepository> entries
57
58. Robustness – Site plugin
• Site plugin is now completely extracted from
Maven core
» It has its own lifecycle
» reporting section in POM becomes useless
(moved in plugin configuration)
58
60. Criticisms
• XML, we don’t like it
• POM is too verbose
• POM v4 didn’t evolve last 5 years
» When will you add new common attributes to
ease plugins configuration (encoding …)
» New feature like global exclusions
60
61. POM
• No change in POM syntax for Maven 3.0
• Changes will occur in 3.x versions
» New model with a new version
» Only new things
» Generation / deployment of 4.0.0 current POM to
keep backward compatibility with old maven
versions
• Mixins to allow to import POM fragments
61
62. POM - Polyglot
• Developed and freely distributed by Sonatype
• Extended version of Maven 3.0 using its new
embedding and extensibility capabilities
• Allow translation (read/write) from/to various
syntaxes
» Yaml
» Scala
» Groovy
• Allow macros and freeform scripting
62
65. K.I.S.S.
• Keep It Simple, Stupid
• Start from scratch
» Do not copy/paste what you find without
understanding
• Use only what you need
» It’s not because maven offers many features that you
need to use them
• Filtering
• Modules
• Profiles
• …
65
67. Project bad practices
• Ignore Maven conventions
» Except if your are migrating from something else
and the target has to be to follow them.
» Except if they are not compatible with your IDE
• Different versions in sub-modules
» In that case they are standalone projects.
• Too many inheritance levels
» It makes the POMs maintenance more complex
• Where should I set this plugin parameter ? In which parent ?
67
68. Project bad practices
• Have too many modules
» Is there a good reason ?
• Technical constraint ?
• Team organization ?
» It increases the build time
• Many more artifacts to generate
• Dependencies resolution more complex
» It involves more complex developments
• More modules to import in your IDE
• More modules to update …
68
69. Project good practices
• Use the default
inheritance :
» The reactor project is
also the parent of its
modules.
» Configuration is
easier :
• No need to redefine SCM
settings, site distribution
settings …
69
71. POM bad practices
• Dependencies :
» DON’T confuse dependencies and
dependencyManagement
• Plugins :
» DON’T confuse plugins and pluginManagement
» DON’T use AntRun plugin everywhere
» DON’T let Maven choose plugins versions for you
71
72. POM bad practices
• Profiles :
» DON’T create environment dependant builds
» DON’T rely on dependencies coming from profiles
(there is no transitive activation of profiles)
• Reporting and quality
» DON’T activate on an existing project all reports
with default configuration
» DON’T control formatting rules without giving
settings for IDEs.
• DON’T put everything you find in your POM.
72
73. POM good practices
• Set versions of dependencies in project
parent’s dependencyManagement
• Set dependencies (groupId, artifactId, scope)
in each module they are used
• Use the dependency plugin (from apache) and
versions plugin (from mojo) to analyze,
cleanup and update your dependencies.
73
75. Development bad practices
• DON’T spend your time in the terminal,
• DON’T exchange libraries through emails,
• DON’T always use "-Dmaven.test.skip=true”
• DON’T manually do releases
75
76. Development good practices
• Keep up-to-date your version of Maven
» For example in 2.1 the time of dependencies/modules
resolution decreased a lot (Initialization of a project of
150 modules passed from 8 minutes to less than 1)
• Use the reactor plugin (Maven < 2.1) or native
reactor command line options (Maven >= 2.1) to
rebuild only a subpart of your project :
» All modules depending on module XXX
» All modules used to build XXX
• Try to not use Maven features not supported by
your IDE (resources filtering with the plugin
eclipse:eclipse)
76
79. Secure your credentials
l Generate a private key
-
arnaud@leopard:~$ mvn --encrypt-master-password toto
{dZPuZ74YTJ0HnWHGm4zgfDlruYQNda1xib9vAVf2vvY=}
!
● We save the private key in ~/.m2/settings-security.xml
<settingssecurity>!
<master>{dZPuZ74YTJ0HnWHGm4zgfDlruYQNda1xib9vAVf2vvY=}</
master>!
</settingssecurity>!
79
80. Secure your credentials
● You can move this key to another drive ~/.m2/
settings.xml
- <settingsSecurity>
<relocation>/Volumes/ArnaudUsbKey/secure/settings-security.xml</relocation>
</settingsSecurity>!
● You create an encrypted version of your server
password
- arnaud@mbp-arnaud:~$ mvn --encrypt-password
titi{SbC9Fl2jA4oHZtz5Fcefp2q1tMXEtBkz9QiKljPiHss=}!
● You register it in your settings
- <settings>
...
<servers>
...
<server>
<id>mon.server</id>
<username>arnaud</username>
<password>{SbC9Fl2jA4oHZtz5Fcefp2q1tMXEtBkz9QiKljPiHss=}</password>
</server>
...
</servers>
...
</settings>!
80
82. Using Reactor Options
• Options added in maven 2.1
• Available in 2.0.x with the maven-reactor-
plugin
» But syntax is longer
• Allow to control what you want to build in your
project
82
84. Using Reactor Options
-
- arnaud@mbp-arnaud:~$ mvn install –pl
moduleE,moduleB
moduleE,moduleB
-------------------------------------------
[INFO] -------------------------------------------
Summary:
[INFO] Reactor Summary:
[INFO]
[INFO]
[2.774s]
[INFO] ModuleB .................. SUCCESS [2.774s]
[1.008s]
[INFO] ModuleE .................. SUCCESS [1.008s]
!
l
l Builds only modules B and E
l
l Following dependencies order
l
l -pl --project-list: Build the
specified reactor projects instead
of all projects
84
85. Using Reactor Options
-
- arnaud@mbp-arnaud:~$ mvn install –pl moduleD -am
------------------------------------------
[INFO] ------------------------------------------
Summary:
[INFO] Reactor Summary:
[INFO]
[INFO]
[4.075s]
[INFO] ModuleA ................. SUCCESS [4.075s]
[0.468s]
[INFO] ModuleB ................. SUCCESS [0.468s]
[0.354s]
[INFO] ModuleC ................. SUCCESS [0.354s]
[0.384s]
[INFO] ModuleD ................. SUCCESS [0.384s]
!
l
l Builds module D (-pl) and all
modules it uses as
dependencies
l
l -am --also-make: If a project list
is specified, also make projects
that the list depends on
l
l Usecase : Build all modules
required for a war, ear, …
85
86. Using Reactor Options
-
- arnaud@mbp-arnaud:~$ mvn install –pl moduleD -amd
------------------------------------------
[INFO] ------------------------------------------
Summary:
[INFO] Reactor Summary:
[INFO]
[INFO]
[4.881s]
[INFO] ModuleD ................. SUCCESS [4.881s]
[0.478s]
[INFO] ModuleE ................. SUCCESS [0.478s]
[0.427s]
[INFO] ModuleF ................. SUCCESS [0.427s]
!
l
l Builds module D (-pl) and all
modules which depend on it
l
l -amd --also-make-dependents:
If a project list is specified, also
make projects that depend on
projects on the list
l
l Usecase : Check that a change
in a module didn’t break others
which are using it
86
87. Using Reactor Options
-
- arnaud@mbp-arnaud:~$ mvn install –rf moduleD
------------------------------------------
[INFO] ------------------------------------------
Summary:
[INFO] Reactor Summary:
[INFO]
[INFO]
[9.707s]
[INFO] ModuleD ................. SUCCESS [9.707s]
[0.625s]
[INFO] ModuleE ................. SUCCESS [0.625s]
[INFO] ModuleF ................. SUCCESS [0.679s]
[2.467s]
[INFO] Project ................. SUCCESS [2.467s]
!
l
l Restarts all the build from
module D (-rf)
l
l -rf,--resume-from <arg> :
Resume reactor from specified
project
l
l Usecase : The build failed a 1st
time in module D, you fixed it,
and restart the build were it was
to end it.
87
89. Release of a webapp in 2002
• Limited usage of eclipse
» No WTP (Only some features in WSAD),
» No ability to produce WARs
89
90. Release of a webapp in 2002
• Many manual tasks
» Modify settings files
» Package JARs
» Copy libraries (external and internal) in a « lib »
directory
» Package WAR (often with a zip command)
» Tag the code (CVS)
» Send the package on the integration server using
FTP
» Deploy the package with AS console
90
91. Release of a webapp in 2002
• One problem : The are • How long did it take ?
always problems » When everything is
» Error in config files ok : 15 minutes
» Missing dependencies » When there’s a
» Missing file problem : ½ day or
» Last minute fix which created a more
bug
» And many other possibilies ..
91
92. Maven Release Plugin
• Automates the release process from tagging
sources to binaries delivery
• Release plugin main goals:
» Prepare : To update maven versions and
information in POMs and tag the code
» Perform : To deploy binaries in a maven
repository
• After that you can just automate the
deployment on the AS using cargo for
example.
92
94. Configuration and Prerequisites
• Project version (must be a SNAPSHOT
version)
• Dependencies and plugins versions mustn’t be
SNAPSHOTs
94
95. Troubleshooting Releases
• Common errors during release:
» Build with release profile was tested before and
fails
» Local modifications
» Current version is not a SNAPSHOT
» SNAPSHOTs in dependencies and/or plugins
» Missing some configuration (scm, distribMgt, …)
» Tag already exists
» Unable to deploy project to the Repository
» Connection problems
95
96. SCM configuration
SCM binaries have to be in the PATH
SCM credentials have to already be stored or
you have to pass them in command line with :
–Dusername=XXX –Dpassword=XXX
<scm>!
<connection>scm:svn:http://svn.acme.com/myproject/trunk</connection>!
<developerConnection>scm:svn:https://svn.acme.com/myproject/trunk</developerConnection>!
<url>http://fisheye.acme.com/browse/myproject/trunk</url>!
</scm>!
96
97. Distribution Management
• Where you want to upload released binaries
» The url of a repository dedicated for your project/
corporate maven deliveries in your repository
manager
<project>!
<distributionManagement>!
<repository>!
<id>repository.acme.com</id>!
<url>${acme.releases.repo.url}</url>!
This id will be used in
</repository>! user’s maven settings
. . .! (~/.m2/settings.xml)
</distributionManagement>!
. . . !
<properties>!
<acme.releases.repo.url>http://repo.acme.com/acme-releases</acme.releases.repo.url>!
. . .!
</properties>!
</project>! Often useful to have a
property to test the release
process on a fake
repository, to validate a
repo manager ...
97
98. Repository credentials
• One server entry is required per different repository id
in distribution management of projects
• In a corporate environment, use a unique id for all
repositories hosted on repository managers using
same credentials (corporate LDAP …)
<settings>!
...!
<servers>!
<server>!
<id>repository.acme.com</id>!
<username>aheritier</username>! This id is the one defined in
<password>{ABCDEFGHIJKLMNOPQRSTUVWYZ}</password>
<password>{ABCDEFGHIJKLMNOPQRSTUVWYZ}</password>! distributionManagement
</server>!
...!
entry of the project to
</servers>! release
...!
</settings>!
98
99. Default Release Profile in Super POM
• This profile is used when you generate binaries of
the release with “mvn release:perform”
• By default, generates sources and javadocs jars
for each module.
<profile>!
<id>release-profile</id>!
<activation>!
<property>!
<name>performRelease</name>!
<value>true</value>! This activation could be
</property>!
</activation>!
used in profiles you want to
<build>! activate in the release
<plugins>! process
...!
</plugins>!
</build>!
Configuration to generate
</profile>! sources and javadoc jars
with basic setting
99
100. Custom release profile
<project>!
...!
<build>!
<pluginManagement>!
<plugins>!
<plugin>!
<groupId>org.apache.maven.plugins</groupId>!
<artifactId>maven-release-plugin</artifactId>!
<version>2.0</version>!
<configuration>!
<useReleaseProfile>false</useReleaseProfile>!
<releaseProfiles>myreleaseprofile</
releaseProfiles>! Don’t use the default
</configuration>!
profile
</plugin>! Use our customized
</plugins>!
</pluginManagement>! profile
</build>!
...!
<profiles>!
<profile>!
<id>myreleaseprofile</id>!
<build>!
...! Our customized profile
</build>!
</profile>! Customize the behavior
</profiles>!
...!
of the build for a release
</project>! Take care to test is
before the release !!
100
102. Why should we setup a global mirror ?
• To simplify users and projects settings
• To control where binaries are coming from
» To not rely on project’s repositories
» To use only the corporate repository manager
• To improve build performances
» By reducing the number of requests to find a
missing artefact
102
103. How should we setup a global mirror ?
<setting>
<mirrors>
<mirror>
<id>global-mirror</id>
<mirrorOf>external:*</mirrorOf>
<url>http://repo.acme.com/public</url>
<url>http://repo.acme.com/public</url> Send all requests to this url
</mirror>
</mirrors>
<profiles>
<profile>
<id>mirror</id>
<repositories>
<repository>
<id>central</id>
<url>http://central</url>
<releases><enabled>true</enabled></releases>
<releases><enabled>true</enabled></releases>
Use « central » id to
<snapshots><enabled>true</enabled></snapshots>
<snapshots><enabled>true</enabled></snapshots> override default maven
</repository>
configuration
</repositories>
<pluginRepositories>
Enable snapshots
<pluginRepository>
<id>central</id>
<url>http://central</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>mirror</activeProfile>
</activeProfiles>
</settings> !
make the profile active all
the time
103
106. Eclipse
• Integration from maven (eclipse:eclipse)
» Allow many customizations
» Support many versions/variants of eclipse
» Support many usages (ear …)
» Doesn’t support projects with “pom” packaging
» Few support from dev team
» Many bugs in classpath management
» Asynchronous
• You have to regenerate and reload project each time you
change a POM)
106
107. Eclipse
• Integration from eclipse (m2eclipse)
» Synchronous
» Nice UI and services to edit POMs
» Support projects with “pom” packaging
» Doesn’t support all usages like EAR with WTP
» Doesn’t support very well a large number of
modules
» Slow down eclipse on large projects because of a
lack of support of incremental build in Maven 2.x
and its plugins
107
114. Users Mailing List
• users@maven.apache.or • Blue :
g » Number of subscribers
» Traffic statistics cover a
total of 2025 days. • Red :
» Current subscribers: 1936 » Number of messages
» Current digest per day
subscribers: 48
» Total posts (2025 days):
89687
» Mean posts per day:
44.29
• http://pulse.apache.org/
114
117. The team
• 60 committers,
• More than 30 active in 2009,
• Several organizations like Sonatype, deliver
resources and professional support,
• A community less isolated : more interactions
with Eclipse, Jetty,
117
120. Some links
• The main web site :
» http://maven.apache.org
• Project’s team wiki :
» http://docs.codehaus.org/display/MAVEN
• Project’s users wiki :
» http://docs.codehaus.org/display/MAVENUSER
120
121. Books
• Nicolas De loof
Arnaud Héritier
» Published by Pearson
» Collection Référence
» Based on our own
experiences with
Maven.
» From beginners to
experts.
» In French only
121
122. Books
• Sonatype / O’Reilly :
» The Definitive Guide
» http://
www.sonatype.com/
books
» Free download
» Available in several
languages
122
126. Support
• Mailing lists
» http://maven.apache.org/mail-lists.html
• IRC
» irc.codehaus.org - #maven
• Forums
» http://www.developpez.net/ forum maven
» In French
• Dedicated support
» Sonatype and many others companies
126
128. Licence et copyrights
• Photos and logos belong to their respective
authors/owners
• Various ideas are coming from the excellent
presentation done by Matthew McCullough :
» http://www.slideshare.net/matthewmccullough/
maven-30-at-oredev
128
129. Licence et copyrights
• Content under Creative Commons 3.0
» Attribution — You must attribute the work in the manner
specified by the author or licensor (but not in any way that suggests
that they endorse you or your use of the work).
» Noncommercial — You may not use this work for commercial
purposes.
» Share Alike — If you alter, transform, or build upon this work,
you may distribute the resulting work only under the same or similar
license to this one.
• http://creativecommons.org/licenses/by-nc-sa/3.0/us/
129