If you've been following my blog on java.net, you'll know that I've completed the Mavenization of the blueMarine Core. It's refreshing to see the thing running again, together with the new software factory, after so much work. In fact, I started the conversion to Maven about nine months ago. Of course, I wasn't working on it fulltime and I had to learn a lot of new things, also related to the integration with Hudson. Furthermore, some projects are used for paid jobs and I couldn't just stop working on them until the Mavenization was complete, since that would have blocked the process. So, since I had so many other things to do, I ended up taking a couple of months to complete the task. However, if you are already experienced with Maven, or hire a consultant who is and can teach you in a short time what you'd learn in months of trials, I think you should be able to Mavenize a project of the same size in a matter of weeks.
What Process to Follow?
A serious question, now, is about what the best process to follow is for the Mavenization of a large, industrial project based on the NetBeans Platform. For sure, since the code already works correctly, it must be an iterative and incremental process. I myself took advantage of the fact that I had split blueMarine into several separate projects already. For instance, a photo format codec (jrawio) and the imaging engine (Mistral, note the new domain for this project, but I'm still moving the site and it's not accessible at the time of writing this article) are plain Java SE projects, so I started teaching myself Mavenization with them - since it's simpler to start with simpler things.
Then I started attacking the problem of creating reusable wrapper NetBeans modules for third party libraries (NBPWR) and experimented with a NetBeans Platform project using forceTen, which is much smaller than blueMarine. I worked a lot with this stuff, refactoring the POMs, learning better ways to write them in a modular way, and integrating them with Hudson, up to the point where I recently discovered how to make them smaller. I re-did some of the stuff from scratch, since the first attempt proved to be not good in all scenarios. Only at that point, having somewhat consolidated the way I work with Maven and a NetBeans project, did I move to blueMarine.
Co-Existence of Maven and Ant?
This is not the only way to work incrementally. For instance, Alexander Hanschke,
author one of the core developers of the Visual Thesaurus application that Geertjan just reviewed, a few days ago wrote me asking whether I knew how to have, in a single NetBeans Platform project, some modules on Ant co-existing with some modules on Maven. The idea for this, clearly, is for a temporary hybrid solution, so that you can Mavenize one module at a time. It was an approach that I hadn't thought of, and could have made much more sense than what I ended up doing myself, since it would have allowed me to still work on the code during the process, since now I am in the situation where blueMarine Core has been basically frozen in the process of Mavenizing it. I'm really interested in this hybrid scenario, since I still have the whole blueMarine to deal with, as well as projects in an incubator, blueOcean (the server side version), and two projects depending on blueOcean to be Mavenized.
An evident problem with this approach is that of cross-dependencies. Since Maven works with the automatic retrieval of required artifacts, it makes sense to start with the modules that are "leaves" in the dependency tree, that is, those that only depend on the NetBeans Platform artifacts and eventually on some library. Then you move on to modules that depend on modules that have already been Mavenized and so on until you're done. But in the middle of the river, how do you make the Ant-based modules to use the Mavenized stuff?
A few days ago I told Alexander that I was going to try and blog on it soon. Unfortunately, the thing is a bit more complex than I thought and I didn't have much time (I've just started working on a project performance assessment activity for a brand new customer) so, instead of blogging on a working solution, I'd like to discuss this in the open, starting with a proposal of what I have in mind and maybe some of you will be able to try it before I can.
The idea is to re-use some work I did 2.5 years ago fighting with the poor performance of the NetBeans Ant build system when building large NetBeans Platform projects. It was the trick that made it possible to split blueMarine into multiple interdependent build projects, in particular a couple of Ant extensions (generate-platform) that make it possible to create a custom platform out of a set of NBM files.
In short, my idea is:
- You first create a custom platform only using the required NBM files from the NetBeans Platform distribution.
- You adapt your Ant-based NetBeans Platform project to use the custom platform (it's a thing that you do only once, at NetBeans Platform Project Suite level).
- You Mavenize a "leaf" module.
- You customize the Ant script so it runs Maven first (it is possible via some Ant-Maven integration tasks), then copy the produced NBM artifacts, add them to the custom platform NBM modules, and use "generate-platform" on them.
- At this point, you can compile the rest of the Ant based project.
As soon as you mavenize another module, you fix the Ant script so it takes the new NBM artifact and add it to the custom platform.
It's clearly cumbersome to work in this way, but it would only be so for a limited time until you finish the conversion. But, in the meantime, you can still work on the project, fixing bugs and adding new features.
There might be many devils in the details, though. For instance, I don't know whether in such a mixed environment the NetBeans IDE is able to apply refactorings to both Ant- and Maven- based modules.
It can also be argued that if one had a NetBeans plugin that is able to automatically perform the Mavenization, no iterative approach would be required and you could convert everything within a single step. Unfortunately, I used a bunch of badly written scripts to Mavenize my stuff and while I'm experienced with the NetBeans Platform APIs, I know little of the NetBeans IDE APIs about manipulating a project. Indeed, Mavenizing a NetBeans Platform project only involves moving some files around (to comply with the Maven file layout) extracting some information (version, description, dependencies) from "project.properties", "project.xml", and "manifest.mf" and generating the POM out of them.
Note: The sources of my Ant tasks for generating a custom platform are available at the old OpenBlueSky repository at java.net.