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

Reply via email to