среда, 1 августа 2012 г.

module: maven


Архитектура и компоненты Maven

    x. Плагины
    x. Репозитории
    x. POM
        x. Parent POM   
        x. subprojects  
Build lifecycle

Типичные задачи
    1. Компиляция
    2. Сборка jar
    3. Тестирование
    4. multi-project builds
mvn package
Работа с зависимостями
    1. Закачка зависимостей
    2. Разрешение зависимостей

    Структура проекта (Convention over Configuration)
    По умолчанию Maven ожидает определенную структуры проекта. Если проект соответствует этой структуре, то Maven непосредственно "из коробки" предлагает множество сервисов (???).

    Ожидаемая структура:

|-- pom.xml
`-- src
    |-- main
    |   |-- resources
    |   |    |--log4j.properties
    |   |    `--applicationContext.xml
    |   |
|  `-- java
    |       `-- com
    |          `-- mycompany
    |               `-- app
    |                   `-- App.java
    `-- test
        `-- java
            `-- com
                `-- mycompany
                    `-- app
                        `-- AppTest.java

    Как изменить структуру по умолчанию?

    Project Object Model

    A Project Object Model (POM) provides all the configuration for a single project. General configuration covers the project's name, its owner and its dependencies on other projects. One can also configure individual phases of the build process, which are implemented as plugins. For example, one can configure the compiler-plugin to use Java version 1.5 for compilation, or specify packaging the project even if some unit test fails.

    Larger projects should be divided into several modules, or sub-projects, each with its own POM. One can then write a root POM through which one can compile all the modules with a single command. POMs can also inherit configuration from other POMs. All POMs inherit from the Super POM by default. The Super POM provides default configuration, such as default source directories, default plugins, and so on.


    Most of Maven's functionality is in plugins. A plugin provides a set of goals that can be executed using the following syntax:

        mvn [plugin-name]:[goal-name]
    For example, a Java project can be compiled with the compiler-plugin's compile-goal by running mvn compiler:compile.
    There are Maven plugins for building, testing, source control management, running a web server, generating Eclipse project files, and much more. Plugins are introduced and configured in a <plugins>-section of a pom.xml file. Some basic plugins are included in every project by default, and they have sensible default settings.
    However, it would be cumbersome if one would have to run several goals manually in order to build, test and package a project:
        mvn compiler:compile
        mvn surefire:test
        mvn jar:jar
    Maven's lifecycle-concept handles this issue.
    Plug-ins are the primary way to extend Maven. Developing a Maven plug-in can be done by extending the org.apache.maven.plugin.AbstractMojo class. A simple example is given at the Plugin Developers Centre page on the Maven site and more detailed examples are given in the Apache Maven 3 Cookbook. Example code and explanation for a Maven plug-in to create a cloud-based virtual machine running an application server is given in the article Automate development and management of cloud virtual machines.

Build lifecycles(+phases)

    Build lifecycle is a list of named phases that can be used to give order to goal execution. One of Maven's standard lifecycles is the default lifecycle, which includes the following phases, in this order:

        1. process-resources

        2. compile

        3. process-test-resources

        4. test-compile

        5. test

        6. package
        7. install
        8. deploy
    Goals provided by plugins can be associated with different phases of the lifecycle. For example, by default, the goal "compiler:compile" is associated with the compile-phase, while the goal "surefire:test" is associated with the test-phase. When the command
        mvn test
is executed, Maven will run all the goals associated with each of the phases up to the test-phase. So it will run the "resources:resources"-goal associated with the process-resources-phase, then "compiler:compile", and so on until it finally runs the "surefire:test"-goal.
    Maven also has standard lifecycles for cleaning the project and for generating a project site. If cleaning were part of the default lifecycle, the project would be cleaned every time it was built. This is clearly undesirable, so cleaning has been given its own lifecycle.
    Thanks to standard lifecycles, one should be able to build, test and install every Maven-project using the mvn install-command.

    The example section hinted at Maven's dependency-handling mechanism. A project that needs the Hibernate-library simply has to declare Hibernate's project coordinates in its POM. Maven will automatically download the dependency and the dependencies that Hibernate itself needs (called transitive dependencies) and store them in the user's local repository. Maven 2 Central Repository is used by default to search for libraries, but one can configure the repositories used (e.g. company-private repositories) in POM.
    There are search engines such as Maven Central which can be used to find out coordinates for different open-source libraries and frameworks.
    Projects developed on a single machine can depend on each other through the local repository. The local repository is a simple folder structure which acts both as a cache for downloaded dependencies and as a centralized storage place for locally built artifacts. The Maven command 
        mvn install 
builds a project and places its binaries in the local repository. Then other projects can utilize this project by specifying its coordinates in their POMs.


    mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false


1. Base Example= Main(Log4J)+Test(JUnit(Hamcrest))

- mvn command
- pom.xml
- test
- package to jar
- different resources (log4j.properties)
- transitive dependencies (JUnit -> Hamcrest)
- different dependencies scopes (?/test)
- global repositorie
- local repositorie (caching)
- plugin.goal (mvn assemly:single)

2. Multi-module build = Main(Log4J, Dao(Log4J), FrontEnd(Log4J)) + Test(JUnit(Hamcrest))
- parent POM / POM inheritance
- multi-project builds
- install components to local repositorie
1) entity-module (com.company.project.entity.*)
2) service-module (com.company.project.service.*)
3) dao-module (com.company.project.dao.*)
4) view-module (com.company.project.view.*)
5) app-module (com.company.project.*)
service (entity)
app (entity, dao, service)

3. ???

- use archetype
- custom phases
custom goals
custom plugins
- custom build lifecycle

Сравнение с конкурентами (Ant, Gradle, Ivy)

    История кратко (http://stackoverflow.com/questions/1163173/why-use-gradle-instead-of-ant-or-maven):

    Ant (tool for automating software build processes) (очень императивный стиль, проблемы с повторным использованием, проблемы с портированием)
    Ant + ant-contrib is essentially a turing complete programming language that no one really wants to program in.

    Maven (complete build tool, build automation tool) (ожидает, что полностью интегрируемся с его buil lifecycle, конфигурации многословны, You have to adapt your structure or architecture to your build tool to Maven)
    customizing your build process becomes a hack
    Maven promotes every project publishing an artifact. Sometimes you have a project split up into subprojects but you want all of the subprojects to be built and versioned together. Not really something Maven is designed for.
    Maven tries to take the opposite approach of trying to be completely declarative and forcing you to write and compile a plugin if you need logic. It also imposes a project model that is completely inflexible.
    Using Maven, the user provides only configuration for the project, while the configurable plug-ins do the actual work of compiling the project, cleaning target directories, running unit tests, generating API documentation and so on. In general, users should not have to write plugins themselves. Contrast this with Ant and make, in which one writes imperative procedures for doing the aforementioned tasks.

    Gradle (it's specifically focused on multi-project builds). 
    Gradle has two distinct phases: evaluation and execution. Basically, during evaluation Gradle will look for and evaluate build scripts in the directories it is supposed to look. During execution Gradle will execute tasks which have been loaded during evaluation taking into account task inter-dependencies.
    Gradle nicely combines both Ant and Maven, taking the best from both frameworks. Flexibility from Ant and convention over configuration, dependency management and plugins from Maven.
    it uses groovy syntax which gives much more expression power then ant/maven's xml.
    It is a superset of Ant - you can use all Ant tasks in gradle with nicer, groovy-like syntax 
    Gradle you can have the flexibility of Ant and build by convention of Maven
     Groovy is much nicer to code than XML. 
    In Gradle, you can define dependencies between projects on the local file system without the need to publish artifacts for each to a repository
    Gradle uses Ivy, so it has excellent dependency management
  • It follows convention-over-configuration (ala Maven) but only to the extent you want it
  • It lets you write flexible custom tasks like in Ant
  • It provides multi-module project support that is superior to both Ant and Maven
  • It has a DSL that makes the 80% things easy and the 20% things possible (unlike other build tools that make the 80% easy, 10% possible and 10% effectively impossible).
    Ivy (transitive relation dependency manager, Dependency Manager)
    Ivy gives better dependency management than Maven
    There isn't great support for multi-project builds
  • Managing project dependencies
  • XML-driven declaration of project dependencies and jar repositories
  • Automatic retrieval of transitive dependency definitions and resources
  • Automatic integration to publicly-available artifact repositories
  • Resolution of dependency closures
  • Configurable project state definitions, which allow for multiple dependency-set definitions
  • Publishing of artifacts into a local enterprise repository
modules and components, the build order, directories, and required plug-ins. It comes with pre-defined targets for performing certain well-defined tasks

    Maven dynamically downloads Java libraries and Maven plug-ins from one or more repositories such as the Maven 2 Central Repository.[3] This local cache of downloaded artifacts can also be updated with artifacts created by local projects. Public repositories can also be updated.

    1) Введение в Apache Maven 2
    2) Наводим порядок в разработке ПО вместе с maven. Часть 1 (частей много)
    3) для углубленного понимания "Использование Apache Maven – обратная сторона медали"
    4) http://en.wikipedia.org/wiki/Apache_Maven

    1) Maven by Example
    2) Maven: The Complete Reference

    Термин - Convention over Configuration, that is, Maven provides default values for the project's configuration.