Nice overview and could be really useful for an entry on the maven site in the
section for plugin
developers.
Mvgr,
Martin
Benjamin Bentmann wrote:
> Dear developers,
>
> After some months of reporting issues for Maven, I have noticed common
> bugs in various plugins. For me it seems that many developers are either
> completely unaware of the problems (i.e. do not handle them at all) or
> are misunderstanding them (i.e. handle them insufficiently). Therefore,
> I would like to illustrate the source of those problems in more detail
> such that developers can start to prevent bugs right from the beginning
> rather than fixing them afterwards.
>
> 1) Relative Paths
>
> It is common practice for users of Maven to specify relative paths in
> the POM, not to mention that the Super POM does so, too. The intention
> is almost always to resolve such relative paths against the base
> directory of the current project. In other words, the paths
> target/classes
> and
> ${basedir}/target/classes
> should resolve to the same directory for a given POM.
>
> Unfortunately, the class java.io.File does not resolve relative paths
> against the project's base directory. As mentioned in its class javadoc
> [0], it resolves relative paths against the current working directory.
> In plain English: Unless a Maven component has complete control over the
> current working directory, any usage of java.io.File in combination with
> a relative path is a bug.
>
> At first glance, one might be tempted to argue that the project base
> directory is equal to the current working directory. However, this
> assumption is generally not true. Consider the following scenarios:
>
> a) Reactor Builds
> When a child module is build during a reactor build, the current working
> is usually the base directory of the parent project, not the base
> directory of the current module. That is the most common scenario where
> users are faced with the bug.
>
> b) Embedded Maven Invocations
> Other tools, most prominently IDEs, that run Maven under the hood may
> have set the current working directory to their installation folder or
> whatever they like.
>
> c) Maven Invocations using the -f switch
> While it is surely an uncommon use-case, the user is free to invoke
> Maven from an arbitrary working directory by specifying an absolute path
> like
> mvn -f /home/me/projects/demo/pom.xml
>
> In order to guarantee reliable builds, Maven and its plugins must
> manually resolve relative paths against the project's base directory. A
> simple idiom like the following should do just fine:
>
> File file = new File( path );
> if ( !file.isAbsolute() )
> {
> file = new File( project.getBasedir(), file );
> }
>
> Many Maven plugins can get this resolution automatically if they declare
> their affected mojo parameters of type java.io.File instead of
> java.lang.String. This subtle difference in parameter types will trigger
> a feature that seems to be known as "path translation", i.e. Maven
> itself will properly resolve relative paths when it pumps the XML
> configuration into a mojo.
>
> While it will not cure this problem completely, I suggest to review the
> MavenProject API such that it ensures the following invariant: All paths
> reported by means of a getter-like method are absolute. This basically
> requires to resolve all relative paths that are pushed in by a
> setter-like method. MavenProject.addCompileSourceRoot() is just one
> example for a public API method that currently blindly accepts a
> relative path, giving rise to later failures because a misbehaving
> component resolves this path not properly.
>
> 2) Resource Bundle Families
>
> Especially reporting plugins employ resource bundles to support
> internationalization. One language (usually English) is provided as the
> fallback/default language in the base resource bundle. Due to the lookup
> strategy performed by ResourceBundle.getBundle() [1], one must always
> provide a dedicated resource bundle for this default language, too. This
> bundle can be empty because it inherits the strings via the parent chain
> from the base bundle, but it must exist.
>
> Take the following example. A report mojo uses a resource bundle family
> with the base name "mymojo-report" and erroneously provides only the
> following bundles:
> - mymojo-report.properties (base bundle for English)
> - mymojo-report_de.properties (specific bundle for German)
> Further assume that the default locale of the current JVM is "de". Now,
> when ResourceBundle.getBundle() is called to retrieve the bundle for
> locale "en", it will try the following candidate bundles and use the
> first one found:
> - mymojo-report_en.properties (candidate for requested locale)
> - mymojo-report_de.properties (candidate for default locale)
> - mymojo-report.properties (base bundle, always last)
> Because "mymojo-report_en.properties" does not exist, the bundle
> "mymojo-report_de.properties" will be chosen instead of the base bundle
> which would have provided the requested English translation.
>
> Plugin developers can easily expose this bug when calling
> mvn site -Dlocales=xy,en
> where "xy" denotes some another language supported by the plugin.
> Specifying "xy" as the first locale will have the Maven Site Plugin
> change the JVM's default locale to "xy" which in turn causes the lookup
> for "en" to fail as outlined above.
>
> Thanks for your attention,
>
>
> Benjamin Bentmann
>
>
> [0] http://java.sun.com/javase/6/docs/api/java/io/File.html
> [1]
> http://java.sun.com/javase/6/docs/api/java/util/ResourceBundle.html#getBundle(java.lang.String,%20java.util.Locale,%20java.lang.ClassLoader)
>
> [2] http://jira.codehaus.org/browse/MNG-3273
>
> ---------------------------------------------------------------------
> To unsubscribe from this list please visit:
>
> http://xircles.codehaus.org/manage_email
>
>
>
---------------------------------------------------------------------
To unsubscribe from this list please visit:
http://xircles.codehaus.org/manage_email