Hi everybody!

I've been using Maven 2 for a few projects now, and found that, although
it provides some nice features, it doesn't seem to be the right tool for
most of my applications. I'll write down some of my experiences here, so
that they might help improving development tools in general.

I'm an individual Java programmer interested in developing open source
applications. I don't work for any company, therefore copany
repositories don't apply to me. Most of my projects are swing GUI
applications intended to be run by users on their local computers, so
integration tests are mostly irrelevant, and the possibilities for
automatic testing are limited as well.

This mail is not intended to start a flame war. I know there are people
using maven and happy with it, and for good reasons. I might even
continue using it for my library projects.

I guess many of the issues I don't like about maven could be helped with
more knowledge about Maven, customized plugins, hackish workarounds, or
any other kind of additional work. It's the sum of all together and the
amount of work required which lead me away from Maven. I list these
issues in no particular order.


MAVEN REPOSITORY AS ONLY SOURCE OF DEPENDENCIES

While the large repository used by maven is a great thing, one of the
most prominent advantages of Maven, it is in no way complete. Whenever I
want to make use of some library not available in a common repository, I
first have to get it into some repository I control, then have to get
that repository into the pom of my project, and at some point have to
grant public access to that repository if I want to share with other
developers. I would much prefer some kind of lib directory, where I
could simply drop the library and start using it, to see if it is fit
for the job I want to use it for in the first place. Then if I decide to
keep it, I would rather add some instructions to my repository about how
to get this library from its official source. Such instructions might
involve downloading some bundle, checking its md5sum in case its file
name contains no version number, extracting it, maybe running some
installer and interactively accepting some license, stuff like that. I'd
rather include such descriptions with the dependency than have an extra
file that describes how to set things up for maven.


ORDER OF TASKS

The maven POM seems to lack a clear concept of task order. This seems
especially important in the packaging phase. Suppose I produce a jar
which I want to pack200, jarsign, gpgsign, include in an assembly, and
gpgsign that assembly again. Clearly order matters a lot. While I
believe it might be possible to get the order correct in Maven as well,
there is no intuitive way to express this order when conceptually all
you do is load a bunch of plugins.


TOO SLOW

Maven is simply to slow, especially while starting up. WHile developing,
I often want to edit the code, compile the code, and run the code, all
in a tight loop. When over 50% of the time is spent starting that maven
monster, that's no efficient use of time. As Maven seems to lack a
simple "run" target, running the code usually means either some
complicated java invocation, or a packaged jart with the dependencies
included in its Classpath, which means executing the package phase and
before that the test phase, leading to even longer build times.


SECURITY CONCERNS

Maven does a lot of things automatically. While this is a good thing if
I simply want to grab a piece of code and build it, it can be annoying
under security aspects. I can't specify repositories for specific
artifacts only. So whenever I want to grab a dependency from a given
repository, I'll have to include it in the POM, and it will be queried
for every artifact Maven wants to download or update. So a malicious
repository could introduce malicious artifacts into my local repository,
affecting all my other projects as well.

Another aspect of this security issue is the fact that there seems to be
no way to ask the user for a password for e.g. jarsigner and hand that
to jarsigner by some means other than a command line argument. On a
multi-user *nix machine, users can see what commands other users are
running, and I don't like them seeing my keystore passphrase. And
storing these passphrases in a file for maven seems comparably evil.


TERRIBLE COMMAND LINE INTERFACE

I know, many developers are using IDEs and probably wouldn't even notice
such issues. But I still prefer to edit my source code in an editor and
build its artefacts from the command line. If I do so with maven I find
the output from the help commands which might be good for machines to
read, but is plainly annoying to me. I find all messages preceeded by
the message category and thus hard to read. I find absolute file names
all over the place, leading to excessively long lines. On the whole,
maven doesn't look well suited to command line operations.

When I compare this to command line tools like e.g. bzr, where I can get
exhaustive and easy to read help for every command, this feels like a
different thing altogether.


JNI ISSUES

In some cases I use libraries which employ JNI, or write JNI code
myself. Mavens lack of cross-compiler support severely limits the
development of JNI builds. Installing third party JNI artifacts in the
repository in such a way that they can be loaded seems difficult work at
best, if possible at all. Probably native libs would have to be copied
to some library dir from where they could be loaded. The fact that the
install:install-file mojo doesn't seem able to attach additional
artifacts further complicates issues, as I would need one POM per
os/arch combination, instead of a classifier.


DOM STRUCTURE

I believe that the DOM is mixing multiple things that don't belong into
one file in my opinion. The DOM contains information about what the
project is, like name, description, authors, license. This information
is intended for every user of the project. Next it contains information
about the plugins and their configuration, which describes how to build
the project and is thus intended for developers, including contributors,
and also for people who prefer building apps from source. And last there
is information about the deployment process and site generation, which
is relevant only to the official developers with write access to the
necessary infrastructure, and might contain internal information like
paths to local directories or similar. I believe these three aspects
should be split in two to three files. I'll grant you that the
distinction between build and deployment description isn't always a neat
line, and internal infrastructure can always be hidden in properties set
by private Maven configuration files.

On the other hand, the DOM is missing several top level elements I would
consider part of the project itself, not belonging to one of the
plugins. Foremost among these I would count file encoding. Why do I need
to configure it again and again for every plugin that operates on source
files, instead of specifying it once and for all, with the possibility
to override it on a per-file and per-plugin basis if need be? Yes, I can
have some common ancestor configure the plugins and use a common
property name for the encoding, but this kind of hacks seems to go
against the whole idea of POMs describing projects.


MODULES AND ARTIFACTS

Theoretically the pom describes a single module, and several files could
belong to this module. However, one of them is the "main artifact", the
others are "attached artifacts". This distinction seems somewhat
artificial. Furthermore, there is no single place within the dom where
all the possibly generated artifacts were listed. And interdependence
between artifacts (like one containing the other) are not expressed
either. I guess I would prefer clean instructions, like these source
files are processed by these build tools in order to produce these
artifacts.


LANGUAGE AND API VERSIONS

There are still systems out there that don't use Java 1.5, often can be
updated only at a cost or not at all, and therefore applications that
need to run on 1.4. On the other hand, I prefer to use the latest JDK
here for development, with all the latest features like -Xlint. (By the
way: as Maven claims to promote "best practises": I'd consider -Xlint
one of these.) I also would want to use Java 1.5 syntax for test cases,
as it is much shorter and clearer in many cases. So I'd like to compile
all my code using the latest javac, but substutute the bootclasspath of
a different Java API version when compiling the main project code, along
with providing the appropriate -source and -target switches. Not
possible in Maven, afaik. I'm not sure how these different APIs could be
managed by any build tool. I guess you could either provide information
where to look for these on common systems, like Windows, OS X, Solaris
and the major Linux distributions, while leaving the user an option to
specify non-standard paths per user or per system, not per project. An
alternative would be to ship stub JARs with the tool, containing all the
public interface of the official Java APIs but no executable code, thus
preserving space and avoiding licensing issues.


EXTENDING MAVEN

Many things in maven can be solved by writing your own plugins. I don't
like the plugin interface at all, though, especially the way
configuration works. Most Mojos use private variables for configuration,
something I would consider part of the public interface of the plugin.
This means you can't simply derive your own Mojo by subclassing some
existing one, as you can't get at those private variables. It also means
that you can have no getters and setters checking the access to these
variables. And if you want to use complex types for plugin
configuration, you have to state class names in the pom.xml. So most
plugins are configured with simple key/value pairs, with the values
being passed as text, even when they have some internal structure. That
pretty much ruins most benefits of XML. I think ant has done a much
beter job with their plugin interface, in all of these aspects.


CONTRIBUTING

I also tried to play my part in improving maven. In some places I
failed, as I couldn't find my way around the complicated network of tiny
modules depending on one another and the immensely bulky plexus
interactions between them. In other cases I succeeded to tweak my local
code here. Sometimes I could even get my maven to use my own snapshot
version of a plugin. I submitted patches to jira and in some cases I
didn't get even a reply till now, more than half a year later. That
doesn't exactly encourage working on maven to match it to my needs.


DOCUMENTATION

Maven documentation is difficult to find and to read. Help pages for
mojos consist mostly of machine-generated text, with often only a single
sentence of less about the role of each parameter. Most maven generated
project pages provide little information distributed over many pages.


CONCLUSION

On the whole, I spent way too much time tweaking Maven, time I'd rather
spend working on my project code. I now decided to abandon maven, at
least for my end user applications. I'm not sure what I'll be using
instead. Maybe some form of ant, with or without ivy, with or without
build files generated from xslt. I also started thinking about writing
my own build tool. If I do, I might use a Java interface to it instead
of an XML interface. After all, we are all Java developers and know how
to speak Java; why should we need to learn a new language for our build
tools? But that's a different topic.

Greetings,
 Martin von Gagern

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to