November, 2008


28
Nov 08

Reflection with generics and annotation introspection

So I ran into an issue today that cost me an hour scouring documentation on reflection to see how it behaves with generics only to not find any sensible info and rather find some blog posts from folks that experienced similar issues. The basic idea is that reflection and generics or rather reflection and runtime type binding doesn’t work as some might expect. Well, at this time of the night, code speaks better than words to me, so here is a small example…

Compiling and running above with assertions enabled will throw the java.lang.AssertionError. Why one might as, well that’s because although the reflection package seems to locate the method using supertype arguments in place of actual types, this must yield some different runtime binding of that method, since introspecting for an annotation of that method yields nothing.

I’m not sure what the intention of this is and whether it’s my lack of understanding the reflection APIs and how they introspect runtime types. I’ll do more digging over the weekend and report if I find something interesting. For now the only way this can be resolved unfortunately is by writing a dynamic search method that will find the right method based on its name and argument types. The types can be supertypes, as we dynamically compare the method argument types to the required types using Class#isAssignableFrom(Class) method. Here is a util method that takes care of locating the annotation…


23
Nov 08

AlexBuild refactoring

So we're going through some major refactoring for AlexBuild. We quickly realized that the original syntax didn't have enough provisions to make Alex extensible for 3rd party plugins as well as making it easier for us to add various lifecycle strategies.

Here is what we have so far…

################################################

define project as {
 name: “some_widget”,
 version: “0.01-alpha”
}

set property src to “java/src”
set property build_dir to “target/classes”

define dependency ivy://commons-logging.commons-logging version 1.1.1 as logging for all
define dependency commons-lang.commons-lang version LATEST as lang for compile, test, package
define dependency file:///home/user/dependencies/spring-2.5.5.jar as spring-full for compile

compile java from “${src}” to “${build_dir}”
compile groovy from “groovy/src” to “target/groovy_classes”
compile resources from “resources” to “target/classes”

create jar named “CoolWidget.jar”
 from “${build_dir}” and “target/groovy_classes”
{
 manifest: “path/to/MANIFEST”,
 include: [ “**/*.class”, “**/*.xml”, “**/*.properties” ]
}

################################################

The basic idea is that each statement is implemented as an AlexPlug, which is an extensible set of interfaces that allow you to develop and extend how various statements in particular contexts are implemented.  Each AlexPlug will consume a set of parameters called AlexParams and arguments called AlexArgs.  The difference between AlexParams and AlexArgs is that AlexParams is a strongly typed set of parameters injected into the implementation of the plugin and AlexArgs is a JSON-like data structures which allows you to provide extensive loosely typed configuration for plugins.  Take a look at the "create jar" statement above.

I'm hoping to have the grammar redefined tonight with the refactoring complete sometime this week.  Once that's done, we can finally do our initial release.  I say finally because before this refactoring exercise, the code in the trunk was ready for the first alpha release, though it didn't provide any points of extensibility that didn't require tinkering with the grammar.  I believe this small delay is good and we can release the initial version with extensive extension APIs to allow for folks to write AlexPlugs.

More to come….