Jason van Zyl on the Future of Maven: Maven 3


April 20, 2009 By Tim O'Brien

Jason recently talked about Maven 3 at the Maven Meetup on March 19, 2009. Here is his entire presentation. In it, Jason discusses plans for Maven 3: support for incremental builds, changes to Plexus, better multi-language support, a queryable lifecycle, changes to the Plugin API, extensible reporting, a refactored plugin manager, project builder, and a new subsystem for interacting with repositories. You’ll hear Jason discuss plans to make Maven 3 more pluggable and to prepare for a Maven that can integrate with various repository formats. Jason also talks about changing the report generation subsystem to be more focused on report generation and integration with tools such as Sonar and Hudson.


Jason van Zyl on Maven 3 from Sonatype on Vimeo.
Jason’s Maven 3 Presentation

Maven 3.0 Jason van Zyl SONATYPE Thursday, March 19th, 2009 Monday, April 20, 2009 /** * This is a method of a Hibernate ORM object which can be serialized via JAXB. * Also utilizes Hibernate validation, an i18n Message manager and EqualsMember, * which means this element is a member of the set of fields denoting object * equality. Somehow, I’m starting to miss XML…  * @return related details for this person   */   @ManyToOne( fetch = FetchType.EAGER, cascade =    { javax.persistence.CascadeType.PERSIST, javax.persistence.CascadeType.MERGE } )   @JoinColumn( name = ”PERSON_DETAIL”, nullable = false )   @Where( clause = ”ACTV_ID = ’T'” )   @Cascade( { CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.DELETE } )   @Cache( usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE )   @EqualsMember   @NotNull   @Valid   @Message( ”${msg.invalid.person.detail}” )   @XmlElement( name = ”person‐detail”, required = true )   public PersonDetail getPersonDetail()   {     return personDetail;   }   Monday, April 20, 2009 Why Maven 3.0 Maven 2.0 – components lacked degree encapsulation and layering Maven 3.0 – easier to add new features Maven 3.0 – better support for IDEs Maven 3.0 – Model Builder Specification Monday, April 20, 2009 Brief History Original Maven 2.1-SNAPSHOT moved to Maven 3.0 Maven 2.0.x work that involved new features became Maven 2.1 Three active branches Maven 2.0.x, 2.1 and 3.0 Monday, April 20, 2009 Integration Testing An enormous amount of time and energy has gone into improving the the integration tests for Maven. The integration tests are the gatekeeper and will let us determine that we have a Maven 3.x that is compatible for most Maven 2.x projects. Monday, April 20, 2009 Backward Compatibility We must ensure that plugins and reports written against the Maven 2.0.x APIs remain to work in 2.1. We don’t want people to have to rewrite their plugins. There are several plugins that are using the current artifact resolution code that will not be supported (please see the Mercury section below). The ones that are in our control we can port over to use Mercury, and external users will have to deal with the major version change. Most people will not be affected and Mercury will be a far better solution. We must also ensure that POMs of version 4.0.0 are supported in 2.1.x along with the behavior currently experienced. We are relying heavily on our integrations tests right now but as we move forward the work that Shane is doing on the project builder with maven-shared-model will help us to accommodate different versions of a POM, and different formats we decide to support. The maven-shared-model code has no limitation to formats of XML, or any of format like YAML, script, or anything else anyone can dream up. These implementations may find use outside of Maven. For example someone might build something with the Maven Embedder, JRuby, and Mercury to create a JRuby-based system. The same could be done for Groovy, or Intercal. We have managed to keep almost everything backward compatible and we will go so far as to provide an isolated execution environment that can contain older versions of the plugin API so that every can work. We’ll see as we progress toward 3.0 GA if this is necessary. This primarily revolves around plugins that require the old artifact resolution code which is not compatible with the new artifact resolution code at the API level. We tried to preserve behavior but there’s not much we could do about the APIs. Monday, April 20, 2009 Error & integrity reporting Don’t allow builds where versions come from non-project sources like local settings and CLI parameters Don’t allow builds where versions come from profiles that have to be activated manually Much improved error reporting Monday, April 20, 2009 Queryable lifecycle The most important change in the embedding environment.You can actually query Maven for the complete execution before it happens. Know about dependencies before executing will also be possible because the new artifact resolution code complete separates the metadata resolution from the artifact resolution. Symmetric plugin parameters will be necessary to know how the model might change during execution. Knowing before hand where a plugin will generate a source directory versus having to execute the lifecycle and examine the compile source roots. This also applies to plugins that would add resources to a project. Monday, April 20, 2009 Lifecycle extension points Clean extension points for processing at the beginning and end of a lifecycle. Aggregator mojos bound to the lifecycle have been deprecated. This practice can produce some very strange results, and isn’t really the right solution for many of the problems it attempts to solve. I’m hoping to include some better options for bracketing the normal build – both before, and after, explicitly – to make aggregator mojos obsolete, but for now they’ve been deprecated to avoid disrupting backward compatibility. Also, aggregator mojos that are bound to the lifecycle will only be allowed to execute at most once during the build, to limit redundant execution. These mojos are meant to act on all projects in the reactor at once, and binding them to one pom.xml file is dangerous in that it can produce different build results depending on whether that pom.xml i
s included. This is further complicated if two modules in a reactor configure the same aggregator mojo…in which case, it may run multiple times…or, when the aggregator is configured in the parent pom, where it will run for each descendant module. Monday, April 20, 2009 Basic Module Layout maven-project contains the original APIs for MavenProjectBuilder that core uses maven-project-builder implements maven specific services of model-builder model-builder general model API Monday, April 20, 2009 POM Elements Tags and categorization in the POM Specification dependencies Dependencies Exclude all Properties Parent versions not required Monday, April 20, 2009 Plugin API Symmetric parameters: input and output Annotations can be used and the javadocs tags will be deprecated Easier to support scripted plugins, though tools like GMaven are taking the bytecode/compiler approach. Complete separation of plugins from reports Monday, April 20, 2009 Extensible reporting Create a completely separate system for reporting. It should not be part of Maven’s core and should really live in its own world. Different reporting solutions should be supported. Not just the maven-site-plugin solution completely coupled to Doxia. Maven 3.x will not be coupled to Doxia. An entirely separate execution environment is required for reporting. A data production model for build information is more useful then a document production model. This is where we could completely mesh with Hudson so that Maven reports could be used to produce useful trending information. Monday, April 20, 2009 Latest Refactoring Moved from linear to hierarchal (tree-based) inheritance. Easier to encapsulate behavior with tree-based inheritance. Monday, April 20, 2009 Key Problem Points Solved Hold unmutated (no-interpolation or inheritance) model. Specified the rules of construction and have much better unit/IT coverage. Have ways of transforming between model types Significant cleanup of profiles (uses same build processors) Easier to extend poms, do mixins Made mercury integration easier Monday, April 20, 2009 Maven future Mercury Project builder Plugin manager Plexus/XBean Classloader architecture Embedder Monday, April 20, 2009 Maven The best is yet to come (and we’ll fix a bunch of stuff)! Mercury Refactored Project Builder Canonical model properties A specification for building a project object model (POM) Domain specific parsers — attribute-based XML, Groovy, Ruby Mixins Maven Embedder Plugin Manager Plexus/XBean (what are those?) Embedder Maven4R / Maven4G/ Maven4P Monday, April 20, 2009 Mercury New repository and transport layer Developed by Greg, Jan, and Jesse from Webtide (the Jetty people) Super fast transport — async client with connection pooling and parallelization Atomic downloads and deployments (with Nexus) Full SSL support Full PGP support WebDAV client built-in Full support for ranges using a pseudo boolean solver — SAT4J Designed, implemented and tested without POMs. Mercury can be embedded and will allow any domain specific application to retrieve, and deploy artifacts from any type of Repository: GEMs, P2, and Maven repositories are possible Monday, April 20, 2009 Project builder Versionless parent elements Better version delegation Mixins XML POM format using attributes Scripted POM formats (pom.{rb|groovy|py}) Monday, April 20, 2009 Plugin manager Generalizing and extracting the plugin manager capabilities and making it available as a library Download artifacts from artifact repositories Create isolated classloaders based on the artifacts downloaded XStream-like configuration mechanism Create isolated execution environments We will use these features to make sure we can support all previous versions of Maven plugins Expression evaluator will become part of the execution environment Monday, April 20, 2009 Plexus/XBean Plexus has a long but quiet history. Started as an offshoot of the Apache Avalon project Started at approximately the same time as Spring but didn’t yet support many features Maven needed XBean is a new DI framework used to provide all the EE injection in OpenEJB and Geronimo. Annotations are now supported in Plexus thanks to XBean. Plexus will leverage XBean to enable all forms of DI currently known Integration with OSGi Monday, April 20, 2009 Embedder The embedder is currently being used in all the major IDEs m2eclipse IDEA Netbeans Maven can now be integrated in any build or development tools Monday, April 20, 2009 Customizable Components Using a directory and specifying it in the Classworlds configuration. Tycho simply has a special set of components that load first before the standard maven components and they override the standard Maven components. Here’s the example based on what Tycho is currently doing which allows custom components to be used. The embedder has the ContainerCustomizer which allow you to inject new component descriptors. This is used in the IDE integration (m2ecipse, Netbeans) for adding custom artifact resolvers. What we ultimately need for Tycho is a way to dynamically pull in a set of components based on the packaging of a project. In our case with Tycho the packaging is maven-osgi-bundle and that should kick in the set of components that do builds for OSGi bundles. We also have another use case in Tycho where we are building OSGi bundles without a POM and actually using a manifest. In this case we need to somehow detect the manifest and then have the custom set of components kick in. In the case of Tycho we need a different project builder, and artifact resolver. Monday, April 20, 2009 Dropping in component JARs main is org.apache.maven.cli.MavenCli from plexus.core set maven.home default ${user.home}/m2 [plexus.core] load ${maven.home}/tycho/*.jar load ${maven.home}/lib/*.jar Monday, April 20, 2009 Using the Container Customizer public void customize( PlexusContainer container ) { ComponentDescriptor resolverDescriptor = container.getComponentDescriptor( ArtifactResolver.class ); resolverDescriptor.setImplementation( EclipseArtifactResolver.class ); } Monday, April 20, 2009 Maven4R class Maven def initialize goals @goals = goals end include_class include_class include_class include_class ‘java.io.File’ ‘org.apache.maven.embedder.MavenEmbedder’ ‘org.apache.maven.embedder.DefaultConfiguration’ ‘org.apache.maven.execution.DefaultMavenExecutionRequest’ def run configuration = DefaultConfiguration.new maven = MavenEmbedder.new(configuration) r = DefaultMavenExecutionRequest.new r.setGoals( @goals ) result = maven.execute( r ); end end m = Maven.new( ["doit!"] ).run Monday, April 20, 2009 Plugin Extension Points a plugin extension must have access to everything in the execution context the maven execution request, we have the project the session where to execute in the plugin, there must be many extensions points depending on what you’re doing so for the osgi example we need an explicit place to modify the manifest entries manifest entries adding license information or would this just be a resource to add maybe the licensing thing would be dynamic resources We create extension points in the component and name these extension points so that components can be created which hook into these extension points. the extension will be instantiated and executed If there are several extension points how is the order determined and do we want any mechanism for precedence Monday, April 20, 2009 Execution configuration Remove Settings from the core and make it a user facing configuration Have one configuration model for request Have one configuration model for session: session takes the request in the constructor and delegates Monday, April 20, 2009