Git Product home page Git Product logo

facebook-oss-pom's Introduction

Facebook OSS POM

Rationale

A base pom codifies policy for projects. It allows a new Maven project to quickly get off the ground and focus on the project itself and not how to build it. The Facebook OSS POM focuses on building libraries and components that are distributed as jar files through the Maven central repository.

It is possible to use the base pom in a new project without any additional changes and modifications.

Preliminaries

The Facebook OSS POM enforces a minimum version of Maven due to various bugs found in earlier versions.

By default, the Facebook OSS POM enforces JDK 1.7. To use another version, add

<properties>
  <project.build.targetJdk>1.6</project.build.targetJdk>
  ...
</properties>

Local setup required!

To fully leverage the deployment options from the Facebook OSS POM, a number of servers need to be configured in the local ~/.m2/settings.xml file. If these servers are missing, either artifact or site deployment will fail.

As described on https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide, the sonatype-nexus-staging and sonatype-nexus-snapshots repositories should be configured:

<servers>
  ...
  <server>
    <id>sonatype-nexus-snapshots</id>
    <username>user</username>
    <password>password</password>
  </server>
  <server>
    <id>sonatype-nexus-staging</id>
    <username>user</username>
    <password>password</password>
  </server>
  ...
</servers>

To support releasing and tagging repositories that are hosted on Github and to allow site deployment to Github, entries for Github and the project site must exist:

<servers>
  ...
  <server>
    <id>github</id>
    <username>github-id</username>
    <password>github-password</password>
  </server>
  <server>
    <id>github-project-site</id>
    <username>git</username>
  </server>
  ...
</servers>

The hard-coded username git and no password for the github-project-site are a limitation of the deployment tool used for the github site. They must exist in the local settings file.

Usage

Add the Facebook OSS POM as the parent to a project:

<parent>
  <groupId>com.facebook</groupId>
  <artifactId>facebook-oss-pom</artifactId>
  <version> ... current pom release version ...</version>
</parent>

Project pom structure

The following elements should be present in a pom using the Facebook OSS POM as parent:

  • groupId, artifactId, version, packaging, name, description and inceptionYear

    Define the new project. These elements should always be present. If any of those fields are missing from the project, the values from the Facebook OSS POM are picked up instead.

  • scm

    Defines the SCM location and URL for the project. This is required to use the release:prepare and release:perform targets to deploy artifacts to Maven Central.

  • organization, developers, distributionManagement

    Empty elements override the values inherited from the Facebook OSS.

This is a sample skeleton pom using the Facebook OSS POM:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>com.facebook</groupId>
    <artifactId>facebook-oss-pom</artifactId>
    <version> ... current version ...</version>
  </parent>

  <groupId> ... group id of the new project ... </groupId>
  <artifactId> ... artifact id of the new project ... </artifactId>
  <version> ... version of the new project ... </version>
  <packaging> ... jar|pom ... </packaging>
  <description> ... description of the new project ...  </description>
  <name>${project.artifactId}</name>
  <inceptionYear>2013</inceptionYear>
  
  <scm>
    <connection> ... scm read only connection ... </connection>
    <developerConnection>... scm read write connection ... </developerConnection>
    <url> ... project url ... </url>
  </scm>

  <distributionManagement/>
  <developers/>
  <organization/>
  ...
</project>

Project POM conventions

In large maven projects, especially with multi-module builds, the pom files can become quite large. In many places, properties defined in the <properties> section of the pom are used.

To avoid confusion with properties, the following conventions are used in the Facebook OSS POM:

  • Properties defined in the POM that influence the build configuration are prefixed with fb.
  • Properties that factor out plugin versions (because the plugin is used in multiple places in the POM and the versions should be uniform) start with dep.plugin and end with version.
  • Properties that factor out dependency versions (to enforce uniform dependency versions across multiple, related dependencies) start with dep and end with version.

Examples:

<properties>
  <!-- Sets the minimum maven version to build (influences build) -->
  <fb.maven.version>3.0.4</fb.maven.version>

  <!-- The surefire plugin version -->
  <dep.plugin.surefire.version>2.13</dep.plugin.surefire.version>

  <!-- The version for all guice related dependencies -->
  <dep.guice.version>3.0</dep.guice.version>
<properties>

Deploy to Maven Central (oss.sonatype.org)

The Facebook OSS POM is intended for open source projects that should be deployed to Maven Central.

It inherits from the oss-parent POM and supports the OSS deployment process as outlined at https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide.

Project Build and Checkers

The Facebook OSS POM hooks various checkers into the build lifecycle and executes them on each build.

Generally speaking, running a set of checks at each build is a good way to catch problems early and any problem reported by a checker should be treated as something that needs to be fixed before releasing.

Checkers are organized in two groups, basic and extended.

Basic checkers

Extended checkers

All checkers are enabled by default and all checkers will fail the build if a problem is encountered.

Each checker has a switch to turn it on or off and also whether a problem will be a warning or fatal to the build.

...
<properties>
  <!-- Do not run the duplicate finder --->
  <fb.check.skip-duplicate-finder>true</fb.check.skip-duplicate-finder>
</properties>
...

The following switches exist:

Group Check Skip check (Setting to true skips the check) Fail build (Setting to false only reports a warning)
Basic Maven Enforcer fb.check.skip-enforcer fb.check.fail-enforcer
Basic Maven Dependencies fb.check.skip-dependency fb.check.fail-dependency
Basic Maven Dependency version check fb.check.skip-dependency-version-check fb.check.fail-dependency-version-check
Basic Maven Duplicate finder fb.check.skip-duplicate-finder fb.check.fail-duplicate-finder
Extended Findbugs fb.check.skip-findbugs fb.check.fail-findbugs
Extended PMD fb.check.skip-pmd fb.check.fail-pmd
Extended License check fb.check.skip-license fb.check.fail-license
Extended Code coverage fb.check.skip-jacoco fb.check.fail-jacoco

Checks can be turned on and off in groups:

Group Skip checks Fail build
All Checks fb.check.skip-all fb.check.fail-all
All Basic checks fb.check.skip-basic fb.check.fail-basic
All Extended Checks fb.check.skip-extended fb.check.fail-extended

A more specific setting (checker specific, then group, then all) overrides a more general setting:

...
<properties>
  <fb.check.skip-all>true</fb.check.skip-all>
  <fb.check.skip-duplicate-finder>false</fb.check.skip-duplicate-finder>
</properties>
...

will skip all checks except the duplicate finder.

Checker notes

License checker

To ensure that a project has an uniform license header in all source files, the Maven license plugin can be used to check and format license headers.

The plugin expects the license header file as src/license/LICENSE-HEADER.txt in the root folder of a project.

For a multi-module project, this file should exist only once, in the root pom of the project. In all other sub-modules, add

<properties>
  <fb.main.basedir>${project.parent.basedir}</fb.main.basedir>
</properties>

to each pom. This is a limitation of the Maven multi-module build process (see http://stackoverflow.com/questions/1012402/maven2-property-that-indicates-the-parent-directory for details).

Enforcer checker

The Enforcer plugin outlaws a number of dependencies that project might use for various reasons:

Outlawed dependency Rationale What to use
commons-logging:commons-logging-api Ill-fated attempt to split commons-logging implementation and commons-logging API. commons-logging:commons-logging
cglib:cglib Has all its dependencies packed inside, therefore leads to duplicate classes. cglib:cglib-nodep
junit:junit Has all its dependencies packed inside, therefore leads to duplicate classes. junit:junit-dep
com.google.collections:google-collections Superseded by Guava, duplicate classes with Guava. com.google.guava:guava
com.google.code.findbugs:jsr305 Subset of the full findbugs annotations, contains only the JSR-305 annotations com.google.code.findbugs:annotations

Well known dependencies

The Facebook OSS POM provides a number of dependencies to projects. These dependencies are considered "well known and stable". When a project wants to use any of these dependencies, it can declare them in the project <dependencies> section without a version and automatically pick up a version from the Facebook OSS POM.

The following dependencies are defined:

Dependency nameGroup/Artifact Idsproperty
Google Guice com.google.inject:guice

com.google.inject.extensions:guice-servlet

com.google.inject.extensions:guice-assistedinject

com.google.inject.extensions:guice-multibindings

com.google.inject.extensions:guice-throwingproviders

dep.guice.version
Google Guava com.google.guava:guava dep.guava.version
Joda Time joda-time:joda-time dep.joda.version
Apache Commons Lang 3 org.apache.commons:commons-lang3 dep.commons-lang3.version
Apache Commons Lang commons-lang:commons-lang dep.commons-lang.version
Apache Commons Configuratio commons-configuration:commons-configuration dep.commons-configuration.version
Apache Commons Codec commons-codec:commons-codec dep.commons-codec.version
Apache Commons Collections commons-collections:commons-collections dep.commons-collections.version
Apache Commons IO commons-io:commons-io dep.commons-io.version
Apache Commons Beanutils commons-beanutils:commons-beanutils dep.commons-beanutils.version
Java Inject API javax.inject:javax.inject dep.javax-inject.version
Java Servlet API javax.servlet:javax.servlet-api dep.javax-servlet.version
slf4j (Simple Logging Facade for Java) org.slf4j:slf4j-api

org.slf4j:slf4j-jcl

org.slf4j:slf4j-jdk14

org.slf4j:slf4j-log4j12

org.slf4j:slf4j-nop

org.slf4j:slf4j-simple

org.slf4j:slf4j-ext

org.slf4j:jcl-over-slf4j

org.slf4j:jul-to-slf4j

org.slf4j:log4j-over-slf4j

dep.slf4j.version
Logback ch.qos.logback:logback-core

ch.qos.logback:logback-classic

dep.logback.version
log4j log4j:log4j dep.log4j.version
Findbugs Annotations com.google.code.findbugs:annotations dep.findbugs-annotations.version
JUnit testing junit:junit-dep dep.junit.version
TestNG testing org.testng:testng dep.testng.version
Easymock Mocking framework org.easymock:easymock dep.easymock.version
Hamcrest matchers org.hamcrest:hamcrest-core

org.hamcrest:hamcrest-library

dep.hamcrest.version
Objenesis org.objenesis:objenesis dep.objenesis.version

Lock down a well known dependency

It is possible to "lock down" the version of a dependency so that any Facebook OSS POM updates will not affect the version used by the project. Locking a version is done by adding a property to the <properties> section of the project POM:

  <properties>
    <!-- change guice version in the Facebook OSS POM. -->
    <dep.guice.version>2.0</dep.guice.version>
    ...
  </properties>
  ...
  <dependencies>
    <dependency>
      <!-- Use the version from the Facebook OSS POM -->
      <groupId>com.google.inject</groupId>
      <artifactId>guice</artifactId>
    </dependency>
    <dependency>
      <!-- Use the version from the Facebook OSS POM -->
      <groupId>com.google.inject.extensions</groupId>
      <artifactId>guice-multibinder</artifactId>
    </dependency>
    ...
  </dependency>

to the project POM. This will lock the version of a dependency to the version desired. This can also be used to force a version update to a dependency.

  <properties>
    <!-- change log4j version in the Facebook OSS POM. -->
    <dep.log4j.version>1.2.18-SNAPSHOT</dep.log4j.version>
    ...
  </properties>
  ...
  <dependencies>
    <dependency>
      <!-- Use the version from the Facebook OSS POM -->
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
    </dependency>
    ...
  </dependency>

Site deployment to Github

The Facebook OSS POM supports deployment of the maven generated site to Github. See http://khuxtable.github.com/wagon-gitsite/ for more information.

For a first time deployment, it is necessary to generate the gh-pages branch as described on Github at https://help.github.com/articles/creating-project-pages-manually.

For site deployment, the github user and github project site must be configured in the local ~/.m2/settings.xml file!

<servers>
  ...
  <server>
    <id>github</id>
    <username>github-id</username>
    <password>github-password</password>
  </server>
  <server>
    <id>github-project-site</id>
    <username>git</username>
  </server>
  ...
</servers>

The hard-coded username git and no password for the github-project-site are a limitation of the deployment tool used for the github site.

Other properties

These are default properties that affect some aspects of the build. All of them can be overriden in the <properties> section of the project pom.

fb.build.jvmsize

Sets the default heap size for the compiler, javadoc generation and other plugins. Default is 1024M.

fb.release.push-changes

When a project creates a release using the maven-release-plugin and mvn release:prepare, this switch controls whether the generated tags, modified POM files etc. are pushed automatically to the upstream repository or not. Default is false (do not push the changes).

fb.maven.version

The minimum version of Maven to build a project.

fb.main.basedir

The 'root' directory of a project. For a simple project, this is identical to project.basedir. In a multi-module build, it should point at the root project.

For a multi-module project, all other sub-modules must have this explicitly set to the root directory and therefore the following code

<properties>
  <fb.main.basedir>${project.parent.basedir}</fb.main.basedir>
</properties>

must be added to each pom. This is a limitation of the Maven multi-module build process (see http://stackoverflow.com/questions/1012402/maven2-property-that-indicates-the-parent-directory for details).

fb.test.fork-mode

Defines the fork mode for running tests. Default is 'once' which is forking one JVM for all tests. Valid values are the same as for the maven-surefire-plugin (once, always, never).

facebook-oss-pom's People

Contributors

hgschmie avatar andrewcox avatar electrum avatar programmax avatar ryandm avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.