Hi all,

In order to prevent the issues we've had in 2.0.x, I've refactored the extension mechanism in 2.1 to be much more careful about separating extensions from the core of maven. All extensions are loaded into their own ClassRealm that inherits from the maven core ClassRealm, and each project that uses an extension gets its own ClassRealm that inherits from the core realm as well. The project realm then imports all implementations of components declared in the extension artifact. The interfaces for these components are assumed to exist inside maven's core realm, to prevent adding new interfaces to the runtime that plugins see.

Plugins each get their own ClassRealm, which is associated with a particular project realm (or, if the project isn't using extensions, the core realm) just before the plugin executes. This allows plugin realms to be reusable across multiple projects (at least, that's the theory), and reduces the memory problem incurred by each project having their own copy of each plugin's realm.

The problem we've run into is that the dotnet code relies on maven- toolchains, but uses sub-interfaces of the main toolchain interfaces to do its work. This means it's not as simple as just casting the dotnet-specific toolchain components to their implementation classes and using that. Instead, the dotnet work relies on access to the sub- interfaces, which are loaded twice: once in the extension realm (isolated from the rest of the build, but accessible from the extension's imported classes), and once again in the plugin (since it can't see the sub-interface from the extension).

Simply adding all classes in an extension (and its dependencies) to the core maven realm (or a project-specific realm) is not a great option, since this can cause incompatibilities between the extension and plugins. If the project uses and extension that depends on maven- scm 1.0, and plugin Y needs maven-scm 1.1, you're out of luck. In the current 2.1 implementation, the dependency on maven-scm from the extension should be effectively hidden from the rest of maven, only accessible from the extension component itself. Obviously this hiding mechanism is a little too restrictive, since it also hides other public non-core interfaces that need to be present to be used from plugins.

I'd propose to resolve this using a mechanism borrowed from OSGi: we should create some sort of manifest of classes to be exported from the extension for use by the rest of Maven. This file could be optional, and the existing behavior would result. But if the file were present, it would name all the classes (and class patterns?) in the extension artifact (and possibly its dependencies) to "export" into the main maven ClassRealm(s) for use by plugins. This is a relatively small change to Maven's extension mechanism for 2.1, and would restore many of the best features of the old extension functionality without incurring the blind incompatibilities of the old system.

Anyone have any thoughts on this?

-john


---
John Casey
Committer and PMC Member, Apache Maven
mail: jdcasey at commonjava dot org
blog: http://www.ejlife.net/blogs/john
rss: http://feeds.feedburner.com/ejlife/john


Reply via email to