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]