Maven - why?

    On open spaces of a network in general and a habr in particular I managed to see not one topic devoted to Maven. And wherever there was a discussion , questions arose of the form:
    • What gives its use in a project of type X?
    • Why is it better than Ant / Make / sh?
    • And what if I want to use antlr / JAX-WS / XDoclet in the project?

    I believe that all these questions come from ignorance that there is Google in the world with insufficient understanding of what Maven is and what kind of approach to solving build management problems it offers. Which in turn grows out of the insufficient attention that article authors devote to the ideas behind xml-files and mesmerizing console commands.


    To me, it’s very viable to understand that when they say Maven they mean 3 rather loosely coupled things:
    • POM. Project object model. Project model - it describes what the project consists of and how its life cycle is structured.
    • Artifact repositories. Storage locations for software module assembly products along with metadata.
    • The mvn utility and plugins for it. Actually a tool for assembling module life cycle management projects .

    Let's look at each one individually to understand how they can be used together.

    POM


    This is a common project model. It describes such general characteristics as the name, version, authors and their contact information, the VCS of the project and the network resources generally associated with it, the type of project (for example, a library or web module, in the original terminology is called packaging, although it affects not only the type of received artifact), links to other projects used in the assembly of plugins and descriptions of how to use them. Two components of this model seem especially important to me.

    Links to other modules

    POM allows three types of relationships with other modules: dependency, inclusion, and inheritance.

    Dependence , this connection says that for some phases of the life cycle of our module, some artifacts of module-dependencies are required (it turned out abstractly - it’s scary to myself). What exactly and at what phase of the life cycle is required is determined by the so-called scope of dependence. Maven understands several predefined scopes and allows you to add your own. As an example, I will limit myself to one scope: compile - it says that binary dependency assemblies are required at the stage of compilation, test execution, and runtime.

    Turning on- Says that the linked module is an integral part of our module. For our module to go through a certain phase of the life cycle, its member must also go through this phase. A classic example of an enterprise module, which includes a web module, an EJB package, and a shared library. Obviously, its assembly requires the assembly of each of the included modules.

    Inheritance. Such a relationship implies transferring to the heir part of the ancestor model. The transfer rules are somewhat confusing, but basically the principle applies - the value of the ancestor model parameter becomes the default for the descendant model. An example from my practice: a module was created that installed the JDK version for compiling projects, internal repositories for results, a set of rules for verifying that the sources corresponded to the coding standard, it should have been used (and in some places really used;)) as a parent for all developed under the project modules.

    Description of plugins used during assembly

    The description consists of the name of the plug-in involved, some of its settings (they are determined individually by the plug-ins), and the goals that it actually fulfills at each phase of the life cycle (for a detailed description of the ideas behind these terms, see below).

    This element is somewhat alien to the general idea of ​​POM - it does not carry a declarative description of the module, but instructions for assembling it with a specific tool.

    Summary
    1. POM is a common, unified model for describing software modules.
    2. It supports the storage of not only attributes of individual modules but also high-level relationships between them.
    3. It also carries information on the tools necessary to support the module's life cycle.

    Artifact repositories


    Artifact repositories are dedicated repositories of build results, designed to simplify the search for the desired artifact (by name, version, type of artifact). They allow a group of developers to use the results of each other's work without having to have copies of the source codes of their modules and build the dependency tree with 0. Maven-compatible repositories have become the standard for de facto publishing the results of various open source projects.

    It should be noted that pom-files containing the project model are also artifacts and can be stored in the repositories with everyone (in fact, at least truncated versions of them, containing only module identification and dependencies, are always stored). Thus, the repository is also a source of information (as a minimum sufficient for distribution) about the modules stored in it.

    So, what bonuses do they give us:
    1. Structured storage of artifacts, their cataloging.
    2. Reuse of artifacts.

    Lifecycle management utility


    The name turned out to be quite pathos, however, it fully corresponds to the high mission and complexity of the subject.

    Before diving into its functions, you need to get a little acquainted with the theory of organizing the module life cycle in Maven. The life cycle is the entire set of operations on the module from assembly initialization to deployment. In the process of passing the life cycle, certain operations are performed on the module, some artifacts are formed. The life cycle is divided into phases. Each phase involves the transfer of the module to a new state as a result of its passage and the appearance of new artifacts. Each previous phase prepares the basis for the next. The phase list is essentially part of the POM, but global, common to all modules. It’s pointless to give a clear list, but for an example I’ll give you several phases (quite intuitively named, in my opinion :)) in the order they follow: compile, ... test, ... deploy.

    Within each phase, a certain set of goals is performed depending on the model of a particular module. A target is a specific operation on source codes and / or artifacts.

    Now to the utility itself. She is responsible for implementing the life cycle based on the project model. Consists of two main components:
    1. Firstly, from a very small kernel that describes (the hardcodes, as the common people say) basic principles of project design, default goals for phases of standard types of projects, a working environment for plugins (access interfaces to models, repositories, FS, settings, etc. .P.).
    2. Secondly from the plugins. They actually contain code that fulfills the goals. Almost all of the external mvn functionality is implemented by them. They generate, compile, test, package, etc. etc.

    Communication with this utility is built extremely simple: you say what phase condition you need to bring the client module to and it does it. All the complexity of formulating and completing tasks to achieve the goal remains on the conscience of the plugin developers (well, a little remains on the model developer). For example, we say compile and we are compiled, and not only what got out of the VCS, but they also generate what is needed, for example by wsimport, and the results are also compiled.

    You can also be asked to perform a separate task for a particular plugin. For example, there is a plug-in for generating Eclipse-projects, the task of "generating a project" which by default is not tied to any phase, but is called manually by interested parties.

    Another extremely interesting function of mvn is to create a draft project based on an archetype. The archetype is a generalized project template that traditionally focuses on its structure and plugins used. For example, there are standard archetypes of the java-library, web-module, and non-standard, for example, grails application. It is important to understand the difference between an archetype and a project type. Archetype - only a template of the initial structure and individual parts of the project, after creating the project, no information about its archetype remains. Type of project - on the contrary, part of the model that is used throughout the entire life cycle.

    What is the total


    So, we have identified three pillars of Maven. What do they give us together?

    • Concentrating module information in one place and in one format. Not everything is smooth here, but many IDEs can import projects from POM, most autocompilation servers (continuous integration, as XP adherents say) can also use them to add a project.
    • Unified module identification system. Very simple and very important. We now have no designations like bugfix-branch of our-super-project, collected at 23 o'clock last Saturday.
    • One tool. Although this, frankly, is not a unique feature of Maven. I can not resist and repeat the common truth: the project should be collected by standard and portable means. Assembling the favorite IDE of the First Project Developer is the way to hell.
    • Automatic dependency management. Linking project source code to binary assemblies of something is a very sad practice. Of particular note are the difficulties with maintaining source code repositories (how many magnetic tapes does your svn backup take?))). Inventions of a bicycle in the form of its repositories or scripts of dependencies dragging the source code are also not the best solution in an era when spaceships plow the expanses of the universe .
    • Reuse of solutions related to the device and the procedure for assembling projects. Thanks to the inheritance and inclusion of projects, we can reuse once developed project models, settings related to the infrastructure and tools adopted in our company. Using archetypes allows you to automate the stage of creating new projects, save time on the preparation of the project structure and minimize errors in the use of external models.
    • A ready-made tool for managing the results of work and the simplicity of their subsequent use. We configure the infrastructure appropriately and each build settles in the right place and is available for future use. Need to check the performance of different layouts / module branches of a large project? Just edit dependencies in POM.

    Conclusion


    Something I deviated from the central question in some places and came to grips with the question “how”, but oh well ...

    From all the information given above, we can draw a simple, but for some reason very rare conclusion. Maven is not a utility for building Java applications. Maven is a framework for automating a wide range of tasks with project support. It has nothing to do with language and platform, moreover, it is absolutely not obliged to collect anything. Using the description of models or writing plugins, you turn it into a tool. Yes, the default model adopted in it is the assembly of Java modules, but these are only defaults ...

    I hope that after reading the topic everyone can confidently answer the questions given at the beginning;)

    PS I will also learn with interest about your experience with custom applications of Maven. There is an idea in the future to create a post with examples of interesting and unusual use cases for it.

    Also popular now: