Is Maven going away? 7
First, let me say, I like Maven - a lot. I’ve liked the idea, if not the execution, since 1.0 (yes, I know there is some serious bad blood for the implementation of 1.0, and yes I still liked it). But I’ve recently run into some irritating problems with Maven that would again, I think, require a major reworking of what it does.
Here is the main issue Maven is designed to handle one language only for its compilation - primarily Java. This is rapidly starting to fall apart now that the JVM has some serious contenders besides Java, namely Groovy, JRuby, Jython, and Scala. There are some hackish things for getting Maven to deal with these, however it still only has one “true” source directory for compilation. A case in point is a mixed Java/Groovy project - trying to get IntelliJ to respect the fact that I want not one, but two main source directories is a pain in the ass as I have to either tell it not to sync everytime I launch or I have to refix the source directories each time I update the project.
This is what triggered this post - what happens when I want to do some Flex programming with some Java, ActionScript and MXML, all of these are true source files (and in Maven specfic directories). I’m sure some Mavenite is going to say that these should be separate projects, but in alot of cases they aren’t and it doesn’t make sense to actually separate them into sub-projects. And I’m equally as sure that some Ant-ite is going to come along and tell me to use Ant - I won’t. Ant is stuck in the past and I won’t use it unless I absolutely have to. I like the “imposed” structure that Maven offers. I can walk up to any project and know where to find stuff instead of blindly hunting around for hours trying to piece it together like some giant source-code jigsaw puzzle, blech.
So, I’m at cross-roads, what should I do? There is Ivy (for dependency management -which they got from Maven natch), but that requires Ant, blech. There’s also Gant, ok, this is better, but still Ant. GMaven, but I’m right back where I started.
Enter, Gradle, a new Groovy-based build system that offers alot of the benefits of Maven without locking you in and the flexibility of Ant. I’m not 100% sold on it yet, but I’m going to give it a shot for a relatively complex project that will have a fair amount of Java, Groovy and other fun resource files. It looks interesting in that all the build files are actually Groovy scripts that are a DSL (like Gant files). Here’s a short example with some dependencies (taken directly from their examples in the download).
import org.gradle.api.tasks.util.FileSet
usePlugin('groovy')
group = 'org.gradle'
version = '1.0'
sourceCompatibility = 1.5
targetCompatibility = 1.5
dependencies {
clientModule(['groovy'], ":groovy-all:1.6-beta-1") {
dependency(":commons-cli:1.0")
}
compile project(':groovycDetector')
testCompile ":junit:4.4"
}
compile {
exclude('**/Exclude.java')
groovyExclude('**/ExcludeGroovy.groovy')
groovyJavaExclude('**/ExcludeGroovyJava.java')
}
manifest.mainAttributes(myprop: 'myvalue')
metaInf << new FileSet(new File(srcRoot, 'metaInfFiles'))
test.options.systemProperties['org.gradle.integtest.buildDir'] = buildDir.absolutePath
I will try and keep everyone up to date as I continue to investigate this new build system. They also state that they are going to be supporting polyglot programming in the near future which I’m looking forward to.
Looking for a good CMS 11
I’ve been working on a project for a family member and need a good Content Management System for them to use. Here are my requirements:
- Easy to understand interface
- Generates URLs that are human readable - no blah.php?page_id=123 crap
- Easily supports internationalization as the site itself will need to be translated into multiple languages
- Preferrably Java (but open to Rails, and not really interested in PHP)
- Doesn’t take a rocket scientist to create and edit site templates
What I’ve looked at so far has been:
- Radiant CMS - too simple, with code embedded and no Rich Text editor that they won’t understand
- Magnolia - Waaaay too complex, nice for an enterprise solution but not for what they need it for
Just downloaded Liferay and will be taking a look at that, Daisy and JBoss Portal. Another suggestion made to me was to possibly use Contribute, which I think I’ll have them download and try out to see if it works for them (but then I’ll have to do the whole locale thing through Apache).
I’ve looked at the CMSes listed here.
- Jahia - ok, after relooking at it I may download it and try it out
- Magnolia - too complex for my needs
- InfoGlue - looks complex just like Magnolia
- Apache Lenya - had a very bad experience with this in the past and the interface looks just as awkward to use as it did before - pass
- Daisy - looks interesting
- MMBase - no online demo and I wasn’t wild about the screenshots I did see, passing for now
What I’ve found so far with alot of these (just through using their online demo) is that the interfaces are very complex. I don’t know if this is supposed to go along with their “Enterprise” tag or not, and of course a fair number of them tout their JSR-170, 168 compliance. Ok, JSR-168 might be important to know, but do I really care if they are a fully compliant Java Content Repository? Nah, not really, I just want it to work and have a usable interface. Some may care about that but to me it isn’t a selling point. I respect the CMSes who put up an online demo, it gives me a chance to play with it first to see if it’s even close to something I want, those that don’t I look for screenshots, and most likely move on anyways.
Interesting trick to finding Java caller 17
Have you ever wondered how to find the Class that has just called your class? Well, now you can (or rather you always could) by using this little trick that I got from my friend and former co-worker Leo.
Class.forName(new Throwable().getStackTrace()[2].getClassName()));
This will retrieve the caller name from the stacktrace and then you can get the actual class using Class.forName(). He uses this in an interesting way for logging.
private static final Log getLog() {
try {
return LogFactory.getLog(Class.forName(new Throwable().getStackTrace()[2].getClassName()));
}
catch (Exception e) {
return LogFactory.getLog(FormattedLogger.class);
}
}
Which he then imports as static methods so that he can just do:
info("Some intereting INFO logging going on here");
Pretty slick and an interesting use of the Java libraries.
DSL book on hold...unfortunately
Well we got the first round of reviews back from the technical reviewers and there’s a lot of work to be done. So much so that we’ve decided to put the book on hold while we regroup and figure out if/how we are going to address the issues that the reviewers found with the book. In a lot of cases it is going to require a complete rewrite of the example (and hence the chapter itself). Personally I feel the core is there, but maybe the examples weren’t as fleshed out as they could have been.
Now of course I’m a little embarrassed that I announced the book before it was done, but that’s what happens sometimes. Not sure at this point whether or not the book will continue, taking some time to regroup/rethink things and see if it is something that I want to push forward with.
I will keep everyone up to date here on the progress of things once I’ve decided what to do. In the meantime I am going to get back to some of my back-burner projects (a few of which have some DSLs in them ;-).
DSL book in progress 6
Now that things feel a little bit more final to me I thought I would take this opportunity to announce the book that’s been keeping me from blogging. The tentative title is Creating DSLs using Java and Groovy and it will be published by Pragmatic Programmers. I started working on this idea after last years No Fluff Just Stuff where I saw Neal Ford speak on DSLs and I talked to him briefly about a project I was working on. His talk inspired me to push forward with using DSLs for code generation specifically using Groovy.
The book will cover both Java and Groovy techniques for writing DSLs, as well as have some general guidelines for writing DSLs. We also have a chapter on ANTLR and JavaCC for writing external DSLs using Java. I tried to cover as much as I could of Groovy meta-programming and some of the additional capabilities of Groovy that make it a good language to write an internal DSL on top of, but there’s only so much space ;-).
We just sent off the book for peer review, which means its about half-way finished, maybe a little more. We are currently shooting for a release date sometime early next year, which looks very doable at this point, but I expect a ton of edits to come back from this first review.
On a final note I just want to say what a pleasure it has been working with the PragProg crew. I love, love, love their book build system and my editor Susannah rocks. I have had a blast working with them so far on this book and am looking forward to finishing this up and getting it published.
Groovy DSL steps 4
What are some of the basic steps that I’ve followed as I create my DSLs (especially with respect to Groovy)?
- What are your spoken and unspoken requirements?
- Who is the intended user? (this will help you decide some of the other questions later)
- Has this kind of problem been solved before?
- How did they solve it? (Language, Toolset, Techniques?)
- How closely does that solution match our requirements?
- What can we take away from that solution (if it doesn’t match the requirements)?
- What kind of DSL do you want overall? (Internal or External)
- Prototype, prototype, prototype - even if it is an Internal DSL you will still want to start out with a working prototype that your intended audience can play with and give you feedback on. This should be an iterative process to refine the language.
- External DSL - how to implement?
I will cover the first 8 of these, and I will leave the External DSL for a later post (sorry ;-). For this I’ll use the steps that I’m currently going through on my own code to illustrate my own thought process.
Requirements
So, what are my requirements for my main two DSLs - QueryBuilder and ViewBuilder (this doesn’t exist yet, but starting on the planning right now). For QueryBuilder I wanted a clean syntax that makes it easy for developers to create constraints/restrictions on a database query. Ultimately the query could be executed by Hibernate, JPA, iBatis, whatever, so it should be ORM-agnostic. This actually isn’t too hard as they all have this concept of a criteria on an object/table and restrictions for that query. And the same goes for ViewBuilder, I want an HTML-like tree syntax that I can specify components in as well as attributes that will be applied to the view when it is built for me.
User
This one is easy, I am targeting Web application developers, initially I am targeting Tapestry Web application developers, but since the framework will be pluggable (probably around the 2.0 time) you can specify what specific pieces you want to use (Tapestry/JSF + Hibernate/JPA + Spring 1.x/2.x/Guice, etc.).
Has this problem been solved before?
In the case of the QueryBuilder, yes. Grails currently has an implementation called HibernateCriteriaBuilder. This has a nice syntax for specifying criteria and restrictions on that criteria. As for the ViewBuilder I don’t think this has been solved yet, but I will be looking. There is something similar in Groovy’s core for creating arbitrary HTML, which is close but not exactly what I’m looking for as I will need to generate more than just HTML from it.
How did they solve it?
Both of these were solved using Groovy’s BuilderSupport object which allows you to build up arbitrary “nodes” from a collection of method, property and closure calls. Very powerful and a little difficult to wrap your head around the first 10 times you look at it ;-) (alright, maybe it was just me, but that took a bit to fully understand what the hell it was doing).
How closely does that solution match our requirements?
First, for the HibernateCriteriaBuilder it actually will build up a real, live Hibernate criteria and use it, which unfortunately is not what I want. I need to generate the Java code that will come out of it. And the MarkupBuilder gets me part of the way there but not quite what I’m looking for.
What can we take away from that solution?
I decided to take away the syntax from HibernateCriteriaBuilder and looked at how they implemented it to see what I could do with that. And for the ViewBuilder I am going to extend BuilderSupport itself and use that to build up my nodes of whatever objects (so more than just plain HTML text, actually objects that represent things).
What kind of DSL do you want overall?
Definitely shooting for internal I think, but that doesn’t preclude having some kind of external DSL for the class creation stuff (that was a giant pain to do in Groovy/Java - just not all of the information I actually needed). So, having some kind of custom language for defining models could definitely come in handy down the road, but I haven’t decided anything yet. Plus, as I learn more Groovy and get feedback/suggestions I may stumble across something that simplifies my design greatly.
Prototype, prototype, prototype
This, aside from requirements and research is probably the most valuable step. Once you decide what you are going to do, how in the world do you do it? Especially if you’re dealing with Meta-programming (which can be a hard concept to wrap your head around)?
Here is where my experience will hopefully prove valuable to someone out there, here are the steps that I took when developing my QueryBuilder:
- Write the Unit tests first, start with the simplest test you can think of for how your language should work
- Run it - yeah I know its going to fail, but prove it to yourself ;-)
- Make it go green - whether you go ahead and create a simple class that has one method in it that does what you want do that
- Write another 2 tests - think about them, how are they going to change that class you just wrote, how much more complex is it going to make the logic you need to write to make sure you do what you expect.
- Fix the first test - is it time to extend
DelegatingMetaClassyet? Or maybe try something simpler like aCategory? Maybe the newExpandoMetaClasswill work. Try a few of them out, but I don’t recommend you dive right into extendingBuilderSupport, not yet, not unless you have already used it before and understand fully what it does. Throw in lots ofprintln "calling so and so with these arguments". These help identify that what you are expecting is actually happening while you write your DSL. - Did that work? Good, write it so the next test succeeds.
- Continue doing 4, 5, and 6 until you are happy and ready to show it to someone
- Let them play with it, get their feedback. Rinse, repeat, refactor. (Here is where I would suggest you revisit the
BuilderSupportidea, does it make sense? Remember not everything is an arbitrary nested tree, so not everything will benefit from using this structure.)
Well, I hope that this is helpful to someone ;-). I really have gotten the DSL bug and (mostly) enjoy writing them. If you run into a weird error, throw it out to the Groovy list, someone should be able to help you out.
Addendum
I meant to add this in when I first started thinking about this post. When I started writing my QueryBuilder I didn’t start out with it generating anything but simple select strings. This helped me visualize the proper nesting of things without getting too complex. Once that was working right I changed my unit tests to expect the actual Java code I wanted back and changed the logic of what the DSL output.
First Maven plugin
I’ve been working on Chama recently and have been making some good progress. One of the last big hurdles before getting all of the Model, View, Controller generation working has been:
- Connecting to a database and gathering metadata - 90% complete (just have the relationship, primary key, foreign key stuff to work out)
- Getting Chama packaged up as a real distributable app that you can download and get up and going quickly
Rather than go through a whole bunch of Ant copy scripts and integrating that with my Maven build I decided to write a plugin that would copy everything over into a specific directory structure and zip up for me (and I can also add in the tar.gz stuff real easy now too). I gotta say it wasn’t too difficult, although the docs leave a lot to be desired in this department. With all the plugins out there you would think this would be more fleshed out, especially since they want everyone to move away from the old Jelly scripts that people wrote in Maven 1. Anyways, it’s fairly simple to do with some caveats.
- There appear to be no docs on what all the custom expressions are such as:
expression="${project}"expression="${project.build.directory}"expression="${component.org.codehaus.plexus.archiver.manager.ArchiverManager}"
- Or if you can actually use expressions like these when setting default values of properties (you can, at least that’s what I’ve gathered by looking at other plugins)
- And if you do or do not need to have getters and setters for your variables that you’ve “annotated” (I say that in quotes because it doesn’t act like true annotations, or at least there isn’t a package in Maven called annotations where you can find docs on all of these)
- My assumption is that at least the setters are necessary so that it can use those to populate the variables you want Maven to populate your plugin with)
All that said it was mostly easy to write my little packaging plugin as I was willing to dig through the source code of some of the existing plugins that were doing similar things (maven-assembly-plugin and maven-war-plugin). That isn’t to say that I’m 100% sure I understand exactly how everything works (good idea but not 100% ;-).
If I get a chance I’ll see if I can contribute something a little more to the plugin docs than what is there currently because others shouldn’t have to do what I did to get through this and it isn’t that difficult once you know the secret handshake.
Processing (the language) as a DSL
I first read about Processing in an old Wired issue (wow, finally found it, do you know how hard it is to search on “processing” on the Web? Uggh). When I first found Processing I wasn’t even thinking about DSLs (this was 3 years ago), but I know that one of my first thoughts was “Why not just use Java directly?”, but now I definitely see the light. I’ve been following the amazing work that others have been doing with Processing who have very little Java programming experience, but they know 2d and 3d graphics.
The cool thing is, is that while Processing is a DSL it is built on top of Java and can leverage any of the packages that Java has (much like Groovy can) which leads to some very interesting hardware projects. And of course, I’m also interested in Processing because I love 2d and 3d graphics and finding interesting ways to interact with them.
In short, I guess, I just wanted to point out that DSLs are everywhere, even if we didn’t see them at first, they aren’t a new idea, they’ve just been given power by naming them (much in the way that Ajax was).
Anyone have some other interesting DSLs that they’ve found?
New project "Chama"
So, where has all this DSL stuff been leading? One of my projects that has been sitting on the back-burner for a while has been Chama. Chama was born out of the frustration of writing the same boiler-plate code over and over for database-backed sites that are run on Tapestry. While you can certainly use something like Trails I was not happy with the additional amount of configuration I needed to do in order to get the forms to look and behave the way I wanted them to.
Why not use Ruby on Rails then, or even Grails if I want to stick with the Java theme?
A variety of reasons:
- I'm familiar with Tapestry, Hibernate, etc.
- I'm very familiar with Java
- I want to learn Groovy as a language
- I don't want to switch out my deployment options to have to deal with deploying my apps to a new server and having to configure it all over again so that it'll run RoR
- I like generators ;-), no really this is an exercise that I want to undertake and if others find value in it that's great
- Mostly to make it easier for me to get some app ideas I've had off of the ground
What will Chama use:
- Groovy as the primary language, with some Java thrown in where needed
- Most likely Yaml for configuration with JYaml for dealing with it
- Quite possibly several DSLs for each area (Model, View, Controller)
I don't know yet exactly how far I'm going to take Chama, mostly I just want to get a tool together that will help me build stuff. If others find value in it and it gets extended from there and heads in a direction I never thought about, great! All the code will be available under an Apache License once I start working on stuff. I have some tentative dates setup in my Trac instance (what?! using Python for a Java app?). Comments are welcome, and I will use this blog to announce releases as they happen, the first milestone is set for 12/22/06 (oops was tomorrow, moving to two weeks, wow it's been two weeks since I first set this up already).
