Dynamic Languages: Rationalizations and Myths

61 Comments

The Patriots loss in the Superbowl has gotten me so depressed and down that I need to take it out on somebody. I need to rant about something, so why not about some things that have annoyed me over the past few months about the dynmaic language community.

I recently emailed the mandelbrot benchmark to a dynamic language evangelist colleague. Although benchmark results are usually pure propaganda, poor representations of how a language or framework is used in the real world, or even just plainly out of date with the latest versions of the technology, still, the performance of dynamic languages compared to Java in the example is quite embarrassing. Ruby, for example, is 500 times slower! Yeah, its hard to take seriously a benchmark that outputs to stdout, but still, if you look at the code you’re thinking, WTF is Ruby doing that causes so much overhead?

Now, when I forwarded this benchmark to my evangelist colleague, he immediately accused me of trying to put down or stamp out any challenge to the “One True Language” (Java). Its not about putting down or stamping out. Its about testing whether or not a language is a viable application platform. The thing is, if the dynamic language crowd is going to position itself as a replacement for Java in application development then they are going to have stop giving silly rationalizations for their shortcomings and promoting myths about their language and Java. This, and this alone is what irritates me about this crowd. Let me give you some examples about the rationalizations and myths they try to pull over on us:

RATIONALIZATIONS

Dynamic Language XXXX didn’t do well against Java in XXXX benchmark

Rationalization: “Benchmarks indicate very little practical information about the overall utility and performance of a given language or runtime.”

Reality: Although benchmarks are either propaganda, out-dated, or not a good representation of real-world usages, glaring differences must be recognized. A 5%, 10%, or even 100-200% difference is probably as a result of tuning or some simple undiscovered bug. In the grand scheme of things, those kind of numbers ain’t very relevant. But a 50000% difference? For such a simple benchmark? Something is seriously wrong here.

This reminds of 2002, when I first ran JBoss against the J2EE SpecJ benchmark. We had some pretty embarrassing numbers at first way back then. Although SpecJ is clearly a silly, non-real-world benchmark, it allowed us to identify many major and minor bottlenecks and helped our project to mature. For some dynamic languages like Ruby, I think what the mandelbrot benchmark showed was that the VMs/implementations of dynamic languages like Ruby are still very immature compared to Java. I don’t believe that it shows anything seriously wrong with the language syntax of these dynamic languages themselves though. Java received similar attacks in the mid 90s when it came out. Since then, the JVM has improved dramatically and according to the mandelbrot benchmark, only 10% slower than C. I expect the same out of the Ruby guys eventually. I’ll have to see how this benchmark improves under JRuby.

Ruby VM cannot support kernel threads

Rationalization: “Green threads are good enough.” OR: “Who cares, I can just run multiple processes.”

Reality: Even the basic laptop nowadays has parallel computing power. Green threads don’t take advantage of this. Blocking I/O also creates huge problems with Green Threads. Solving the problem by running many processes is a poor solution. A process is just too heavy weight compared to a thread which is why we have threads in the first place. It is very common for server-side Java applications to service hundreds of concurrent users. Besides, running multiple single-threaded processes starts to negate some of the benefits of simple design patterns like caching.

If dynamic languages like Ruby want to position themselves as a viable alternative to Java for an application platform, they are going to have to solve these issues. Many will say, “Its probably good enough for simple apps”, but it is not uncommon for project leaders to underestimate how much traffic they will get, or how much they have to scale.

Dynamic languages like Ruby, Python, etc… are not typesafe/statically typed

Rationalization: “Type-safety makes my code too verbose and makes me less productive.”

Reality: Why can’t these people learn how to type? Modern IDEs make this point totally moot with code completion and code generation. Besides, why can’t we have a dynamic statically typed language?

Lack of type safety doesn’t scale well to large teams

Rationalization: Anybody noticing the “Any software written by a large team will ultimately fail.” articles floating around in the community? Am I paranoid, or is this yet another attempt at brainwashing us into believing dynamic languages are the next fad in software development?

Reality: There are a lot of large applications in the industry being written. This reminds me of a story my colleague Jason Greene told me. He was working on a very large python project. Lack of static typing ending up being such a coordination and maintenance problem they ended up having a coding policy where everybody had to embed type information into the variable names of method parameters. Funny, eh?

Lack of static typing does not allow for reliable refactoring in modern IDEs

Rationalization: “The productivity of dynamic language XXXX makes refactoring irrelevant. Anyways, there are IDEs for Ruby out there that support refactoring”. OR, my favorite: “I don’t use an IDE, what do I care?”

Reality: I was a VI/Emacs user up until 2002 when Intellij came out with refactoring capabilities. Up until then, I was as productive with emacs, find, grep, and sed as I could be with any IDE out there. After finally becoming familiar with Intellij and its refactoring capabilities, I found that I was 5, 10 times more productive with my IDE than I was before. Now, Ruby fanboys will argue, “Intellij and Netbeans have refactoring capabilities for Ruby!” My answer is, it is not reliable refactoring. Take this example Cedric Beust gave on a recent TSS thread:

def f1(o)
  o.init
end   

def f2(o)
  o.init
end   

class C
  def init
    ...
  end
end    

class D
   def init
     ...
   end
end

If you rename C.init to C.init2, how can the IDE know which o.init must be renamed in f1 and f2? The IDE could either do these refactorings automatically (dangerous) or prompt you to confirm at each replacement point (tedious). In either case, any productivity you’ve gained with the elegance of Ruby is lost 10 times over.

So, these are just some of the rationalizations the dynamic language crowd gives when confronted with criticism. Now let’s talk about some of the myths and propaganda that is being fostered.

MYTHS

Software Engineers should use the best language for the job

Reality: I don’t know about the rest of you, but throughout my career I’ve either been developing middleware or writing applications. What other job is there really out there? Or maybe they are saying, “XXX dynamic language is good enough to solve certain application requirements”? Good enough has never really been good enough for me.

Besides, its hard enough to find an expert in one language. Its a maintenance and integration nightmare to have a project written in multiple languages. This can be bridged, to a degree, with dynamic language implementations that run on the JVM: JRuby and Jython are good examples. But unless these implementations become mainstream, they can quickly become out of date, i.e. Jython.

More lines of code means more bugs, thus dynamic languages are better.

Reality: Modern IDEs fills this gap. TDD is viable in type-safe languages too! I’m probably doing my own rationalization here, yes… JBoss 5, for example, is the 3rd major refactoring of the JBoss Application Server that I’ve lived through. I just can’t imagine doing it without the reliable refactoring that modern Java IDEs provide.

I am more productive in XXX dynamic language because the syntax is cleaner, more elegant, and more powerful.

Reality: Because Modern IDEs with a statically typed language can do reliable refactoring, this productivity gain has diminishing returns as your project gets larger. Even with small, one man projects, this reliable refactoring offsets any productivity gain you get with the dynamic language. At least, that’s what I’ve experienced.

I’ve done a decent sized project in Python before. I did find I was more productive with the first implementation. The problem is, I’m not a very clean programmer, so I end up iterating and refactoring constantly. In my case, a powerful IDE has made me incredibly more productive. Something I just could not get with a dynamic language.

Am I just a Java fanboy?

Maybe, but I don’t think so. Throughout my career I’ve done projects in Pascal, assembly, C, C++, Fortran, Tcl, Perl, Python, Visual Basic, Java, and even hacked around a little bit with PHP. While I don’t believe that Java is the one langauge to RULE THEM ALL, I do believe it is vastly superior to anything out there to build applications with. I also do not believe that Java is the end all, be all of existence. It still needs elegant, typesafe closures to complement annotations as a way to implement DSL. It needs a standard, non-code generating way of adding behavior to annotations. It needs a structural syntax to make initialization easier. AOP support might be nice too, or at least JVM support to make it easier to implement AOP-like features. Better zero-turnaround development features in both the JVM and APIs like Java EE, Seam, Hibernate, Spring, and JBoss AS would help out tremendously as well. Really, I’d be fine to dump Java for a language that supports all these things but the new language must:

  • Be typesafe, statically typed
  • Have an IDE that supports the same features as modern Java IDEs
  • Have a rich set apis and libraries to build my applications from
  • Have a viable commercial ecosystem
  • Have a vibrant open source community

While current dynamic languages do have some of these attributes, none contain all, so until then Java is my choice and I will remain a boy who is a Java fan.

Finally, I hope you realize that I’m not trying to stamp out dynamic languages, but rather hoping, in vain, that the dynamic language community admits their faults. I do wish that a statically typed dynamic language would come of age, but until then, I’ll stick with Java. Really, I don’t know why somebody hasn’t done it it. Is static typing really that hard to implement well? For example, why not gut Groovy and have Dynamic Java? Or do the same with Scala? Or add static typing to Python and get Jython up-to-date?

Well thats it, expect more ranting in the next few weeks/months on a variety of subjects. Its gonna take a long long time to get the Pats loss out of my system….

Edited: 2/22/08

Many people have been confused on what I meant by statically typed dynamic language.

1) Typesafe introductions/mixins to either an instance or a class

For example:

class Foo {}
class Mixin implements MixinInterface {}
Mixin.add(Foo.class, new Mixin(), MixinInterface.class);
Foo foo = new Foo();
 MixinInterface intf = (MixinInterface)foo;

Or:

Foo foo = new Foo();
Foo bar = new Foo();
Mixin.add(foo, new Mixin(), MixinInterface.class);
(foo instanceof MixinInterface) == true
(bar instanceof MixinInterface) == false

2) Ability to do AOP things like field/method/constructor interception without having to do bytecode magic
3) Ability to plug in at runtime annotation processing (not the Javac crap).
4) An instrument library that allows you to make schema changes to classes. (didn’t state this before)


Best Pats games I’ve been to

7 Comments

In honor of the Patriots 18-0, one to go, season and Superbowl XLII, I thought I’d reminisce a bit. Tailgating at the AFC championship game last week, my dad and I were trying to come up with the top five, top ten, best Patriots games we’ve ever seen live. Really, when you’ve been a season ticket holder for 15 seasons, most of the games blur into one another. The one’s that actually stand out are the ones that are the best. Here’s my top ten, in ascending order, least favorite to favorite. Remember, these are games I was actually at. This list would be very different if it was a combined games I was at and watched on TV.

#10. September 9th, 2004. Patriots vs. Colts, regular season. 27-24

This was the season opener after the Pats 2nd Super Bowl victory. These games are cool because they have a big, Super Bowl like, ceremony before the game unveiling the banner. The game itself was a little ugly. The best was Vanderjerk missing the tieing field goal at the end of the game.

#9. October 14th, 2001. Patriots vs. Chargers, regular season. 29-26 in overtime

Flutie was San Diego’s starting quarterback. This was the game when you knew we had something special in Tom Brady. The Pats came back from I think a 10 point deficit in the 4th quarter to beat the Chargers in overtime. Adam Vinateri kicked the game ending kick. One of many that season.

#8. January 18th, 2004. Patriots vs. Colts, AFC championship. 24-14

This was the first playoff matchup between the Pats and Colts. Corey Dillon was a beast that day. Brady threw a late 4th quarter interception that made the game a lot closer than it really was. After this game Bill Polian, the Colts GM, complained to the rule committee in the offseason about the physical play of Patriot’s corners and got a rule change. Scumbag. If you can’t win, change the rules. What a putz. I’d much rather break rules that are stupid and be called a cheater than to use personal power to change the rules in my favor. In my mind, this action was far far worse than Cameragate.

#7. January 10th, 2004. Patriots vs. Titans, divisional playoff. 17-14

The game was kinda boring. What was memorable was the temperature. This was a night game in January. The temperature was 0 F degrees (that’s very negative for all you Celsius guys). We tailgated before the game in T-Shirts. What?!?! T-Shirts? Well, my dad brought a propane heater which we put under a canopy. We tied a hug plastic tarp around the canopy to keep the heat in. What was funny was that when you were standing it was incredibly toasty. I was wearing a T-shirt. But, if you sat down, you froze your ass off. During the game, I remember this guy sitting next to me bring 2 beers to his seat. Halfway through his first beer, it became frozen. The other one was frozen as well. What a waste of $15 for the dude. I stayed with hot chocolate that game. Stayed pretty warm until about the end of the 4th quarter. The lesson of this game, as a fan, was survival.

#6. November 13, 1994. Patriots vs. Vikings, regular season. 26-20 in overtime

The Patriots were 3-6 on that date and it looked like yet another year of no playoffs with a losing season. The Patriots, under Drew Bledsoe came back from a deficit to beat the Vikings at home in overtime. In this game, Bledsoe threw an NFL record for passes and completions. The Pats went on to win their next 6 games to launch themselves into the playoffs.

#5. September 9th, 2002. Patriots vs. Steelers, regular season. 30-14

This was the season opener after the Patriots 1st Super Bowl victory. This game was incredible for two reasons. One, they had a huge ceremony before the game showing a video made by the players on the big screen. When they unfurled the Pats 1st Superbowl banner, the place went nuts. I have never-ever heard Gillette stadium be that loud and this was *BEFORE* the game! You just knew there was no way the Patriots were going to lose that game. The second reason? Well, if you remember, the Pats had beaten the Steelers in the AFC championship game. The Steelers talked a lot of smack after that game saying that they lost to an inferior team, that the Pats were lucky, that if they played again, the Steelers would definitely win. (BTW, this is what half the teams said about the Pats all year long after they lost to them). The Pats absolutely destroyed the Steelers in that game. Throughout the game, to get the fans psyched up (like they needed it at all), the would put Kordell Stewart’s press conference on the big screen where he talked smack about the Pats. Kordell was heckled throughout the game. Cool stuff.

#4. December 21st, 1996. Patriots at Giants,. 23-22

This game was not at Foxboro, but in NYC at the Meadowlands. It was the last game of the 1996 season. The Patriots needed a win to clinche a 1st round bye. IIRC, the Pats were down 22-3 (or something) going into the 4th quarter of that game. Dave Megget ran back a punt return. The pivotal play was the Pats last score to go ahead. Ben Coates received a Drew Bledsoe pass at about the 2-3 yard line of the Giants. Coates was met by 2-3 Giants defenders, but would not go down. Pushing, driving a mass of players came together like a Rugby scrum until Coates was pushed into the endzone. I went nuts. I had endzone seats that game in the same endzone Coates scored. I was wearing my old Pats jacket and was receiving constant flack from Giants fans the entire game. When Coates I was jumping, screaming and yelling with joy with tears in my eyes, hugging one of my friends. When I finally stopped rejoicing I looked around me to see the whole section staring at me angrily. It was a special moment. 🙂

#3. January 5th, 1997. Patriots vs. Steelers, divisional playoff game. 28-3

This game was the year the Pats went to Superbowl XXXI. It was a very very strange day. We had gotten a bunch of snow the week before. That day, however, the temperature was very warm. 50’s or 60’s or something, IIRC? It was very cloudy, and intensely foggy. In the opening game ceremonies, they had fireworks to go along with the national anthem. It was so foggy that combined with the smoke from the fireworks, you could see nothing. I have endzone seats and the fog was so bad you couldn’t see past mid-field. There were two plays that were memorable to me. The 1st was the 1st offensive snap by the Pats. Drew Bledsoe threw a bomb to Terry Glenn and the route was on. The 2nd play was a 70 yard touchdown run by Curtis Martin. I remember him breaking threw the defensive line and sprinting down the field. He disappeared into the fog at about the 50 yard line. My dad and I didn’t know he scored until we heard the cheers of the fans and the scoreboard change.

#2. January 16h, 2005. Patriots vs. Colts, divisional playoff game. 20-3

Another game where the national media picked the Colts to defeat the Patriots. With less than one minute to go in the game, the Colts were driving down the field to try to salvage some dignity after being held to 3 points the entire game. Not one person in the stands had left on this cold January day. Gillete was actually the 2nd loudest I have ever heard it. Bruschi was going crazy. Usually, linebackers are lined up in position before the snap. Bruschi was running sideline to sideline jumping and flapping his arms to get the fans even more riled up. Nobody wanted the Colts to score even one more point. They didn’t. Rodney Harrison intercepted a Manning pass in the endzone to really finish the game.

#1. January 19th, 2002. Patriots vs. Raiders, divisional playoff game. 16-13 in overtime

This is a classic I wish they would replay in its entirety on NFL Network. This game was at night in the Patriots Superbowl XXXVI run during a N’oreaster. (Severe New England blizzard). This was the most intense tailgating experience we had ever had. This guy Jason we tailgated with brought lobster and fried up an entire turkey. Delicious! The snow was coming down hard the entire game. When the famous Tuck Rule happened where it looked like Brady had fumbled, but really didn’t, my whole section had gathered up their things and starting walking up the stairs to leave the stadium. We couldn’t believe it could end like that. But wait! It didn’t. Review from the booth! The rest was history. Much like the fog game, (but not even as close as bad), it was hard to see things past the 50 yard line. Vinateri’s 45 yard tieing field goal to send the game into overtime was a kick I did not see. The snow was coming down too hard. Had to listen for the roar of the fans to know had scored. I was lucky enough to have the game winning kick in our endzone. Took us forever to get out of the parking lots that night, but nobody cared.

    What? No Superbowls in this list? Yeah, unfortunately I’ve never been to a Superbowl. You are not guaranteed seats as a season ticket holder. Instead you are placed in a lottery. In the 5 Superbowls the Pats have been to in the last 15 years, I have yet to win it (including this year). What? I didn’t scalp tickets? Go to stubhub.com or a similar site and see how much they cost. Anyways, I’m not bitter. I have a lot of great memories. I hope to see the Pats set NFL history with the first perfect 19-0 season.

    Improvements to Scannotation

    1 Comment

    I made a few little improvements to Scannotation that I needed to have in our JSR-311 implementation:

    • CrossRefException is now a checked exception. You should be forced to deal with this exception.
    • Configurable ignored packages. You can specify which packages you do not want to scan. Performance tweak.
    • Meta-annotations are now cross-referenceable if you invoke the appropriate APIs. What do I mean by this?

    Example of cross-referencing meta-annotations:

    @HttpMethod("GET")
    public @interface GET {}
    
    public class BookStore {
        @GET String getBook() {...}
    }

    BookStore can now be cross-referenced with @HttpMethod if you call the appropriate method on AnnotationDB.

    
    			

    Is JAX-RS (Restful Java) just another IDL?

    3 Comments

    I was reading a bit of Steve Vinoski’s blog on how some think REST requires a definition language like WSDL or IDL. He first mentions it within Serendipitous Reuse, and further expands on it in the blogs Lying Through Their Teeth: Easy vs. Simple, IDL vs. Human Documentation and More REST and IDL. If you are a REST fan or detractor these blogs as well as the blogs they link to are a good read and gets you thinking about things.

    I’ve been implementing JAX-RS, JSR-311, off and on the past few months. Vinoski’s blogs made me think, is JSR-311 just another definition language? The language being Java + JAX-RS anotations? Maybe I’m dwelling over the obvious here, but let’s do the exercise anyways…

    Vinoski paraphrases Ryan Tomayko on what might be the erroneous use of a RESTful definition language:

    Among other things, Ryan touches on one of the favorite assertions of the REST detractors, which is that REST can’t be effective without an interface/service/resource definition language. After all, without such a language, how can you generate code, which in turn will ease the development of the distributed system by making it all look like a local system? Not surprisingly, the first comment on Ryan’s blog entry is exactly along these lines.

    First of all, I don’t think JAX-RS is trying to make a distributed system look like a local one. Yes, its trying to remove a lot of boilerplate code. Yes, using JAX-RS could turn a POJO into a distributed RESTful resource.

    public class BookStore {
        @GET @Path("/books/{id}")
        @ProduceMime("application/json")
        public String getBook(@PathParam("id") int id) {
             ... return a json representation of the Book
        }
    }

    JAX-RS does have some characteristics of a definition language. From the @GET and @Path annotations, you can determine how the resource is going to be invoked on. But, IMO though, it is more of a mapping language than a definition language. Its mapping a URI and http request/response to the invocation of a Java method. Its not trying to make our distributed system look like a local system.

    Now, what about the idea I had of providing a client framework using JAX-RS annotations?

    public interface BookStore {
        @GET @Path("/books/{id}")
        @ProduceMime("application/json")
        public String getBook(@PathParam("id") int id);
    }

    The idea here would be you generate a RESTful client proxy from a JAX-RS annotated interface that you could invoke on without writing http client code. Are we blurring the lines here? Are we hiding too much the fact that our BookStore is a remote distributed service? I’ll leave that up to you to decide…

    Scanning Java Annotations at Runtime

    36 Comments

    When writing an annotation-based framework, you many times have the need to find all classes that use a specific annotation at deployment time to initialize your framework. For example, the EJB 3.0 deployer needs to know which classes are annotated with @Stateless, @Stateful, and @MessageDriven, so it can create a container for each of those classes. For JPA, it needs to find a given set of classes within an archive that are annotated with @Entity so that it can define its ORM mapping. This scanning for annotations can be done at runtime using various techniques and open source libraries. I want to discuss how to do this in my blog and point you to a small project I created at sourceforge to help out with this.

    Finding archives to scan

    The first thing you need to do is to find actual archives you want to scan for classes. Depending on your environment there are different ways to accomplish this.

    Java classpath

    The “java.class.path” system property, if set properly (FYI, maven doesn’t set it properly), can be a way to obtain a list of classpath/archives you can scan for annotated classes. Although it it only provides relative paths, you can easily turn these into URLs and/or InputStreams for iterating over.

    Using your classloader

    Using ClassLoader.getResource() and ClassLoader.getResources() is a way to obtain URLs to specific resources in your classpath. From these specific resources you can extract the base url of the classpath/archive the resource resides in by chopping off the base resource name. For example, one common technique is to have a marker file in each of your archives. For JPA, this marker file is META-INF/persistence.xml. You could then to ClassLoader.getResources() to find all classpaths/archives that contain that file:

    ClassLoader cl = Thread.currentThread().getContextClassLoader();
    Enumeration<URL> urls = cl.getResources("META-INF/persistence.xml");

    Calculating the URL of the classpath/archive is just a matter of a little string manipulation of the url.

    Web Applications

    In web applications its very easy to obtain URLs that point to jars within WEB-INF/lib or to extract where the WEB-INF/classes path is by using the ServletContext class. The class has a nice method getResourcePaths() that returns URLs to what you want. For example:

    List<URL> urls = new ArrayList<URL>();
    
    Set libJars = servletContext.getResourcePaths("/WEB-INF/lib");
    for (Object jar : libJars)
    {
        try
        {
           urls.add(servletContext.getResource((String) jar));
        }
        catch (MalformedURLException e)
        {
           throw new RuntimeException(e);
        }
    }

    ServletContext.getResourcePaths() returns a directory like list of all paths under the specified base path you provide as a parameter. Passing in “/WEB-INF/lib” will get you a listing of all .jar files within /WEB-INF/lib of your web application. Once you have this listing, you can do ServletContext.getResource() to obtain a URL pointing to each of the .jar files.

    To find the /WEB-INF/classes is a little trickier.

    URL classesPath = null;
    Set libJars = servletContext.getResourcePaths("/WEB-INF/classes");
    for (Object jar : libJars)
    {
       try
       {
          URL url = servletContext.getResource((String) jar);
          String urlString = url.toString();
          int index = urlString.lastIndexOf("/WEB-INF/classes/");
          urlString = urlString.substring(0, index + "/WEB-INF/classes/".length());
          classesPath = new URL(urlString);       break;    }
       catch (MalformedURLException e)
       {
          throw new RuntimeException(e);
       }
    }

    You use the same ServletContext.getResourcePaths() and ServletContext.getResource() but you must do some string manipulation to the URL to get the base path. If you are deploying things within a web framework, you can write a ServletContextListener that obtains access to the servlet context.

    Browsing archives

    Once you have URLs pointing to directories or .jar files that make up your classpath (or the set of archives/paths you want to scan) you need to browse them. You can usually assume that URLs ending in “/” are some form of a directory while those not ending in “/” are .jar files. If you hack and step through URLClassLoader code, you’ll find that it makes the same assumption. Browsing jars is very easy. If you have a URL pointing to a .jar file all you need to do is open an InputStream to it and instantiate a JarInputStream. This class has methods that allow you to list and open files within the jar archive.

    URLs that point to a directory poses an abstraction problem. Browsing a directory structure is protocol specific. If the URL protocol is “file:” you can just use java.io.File. If its “http:”, you need to use a WebDAV library. If its a different protocol, you need to find a library that allows you to browse that particular protocol.

    Finding annotated classes

    So, once you have access to your classpaths you can obtain a list of .class files within those classpaths. It generally is a very bad idea to load each and every one of those classes using your ClassLoader and use the Java reflection API to scan for annotations you are interested in.

    1. Use the Java reflection API only allows you to see annotations that are visible at runtime. If you remember your JDK 5.0 lessons, there are 3 types of annotation. Source, Class, and Runtime. Class and Runtime are compiled into your .class files, but only Runtime are visible at runtime.
    2. You generally do not use each and every class in the libraries you are scanning. If you load each class into your ClassLoader, you are filling up the JVM’s perm-gen space and wasting resources.

    So, if you’re not going to load the class through your classloader, how do you scan for annotations? The answer is to use a bytecode processing library like Javassist or ASM. I am most familiar with Javassist since I wrote the annotation processing for it so let’s show examples using that library. ASM is perfectly good as well for this purpose.

    With Javassist, you load up a ClassFile instance from the InputStreams you browse from your .jar or classpath. This object allows you to view the bytecode structure of your .class file without loading the class and find the string names of the annotations attached to each element of the class

    DataInputStream dstream = new DataInputStream(new BufferedInputStream(bits));
    
    ClassFile cf =  new ClassFile(dstream);
    String className = cf.getName();
    AnnotationsAttribute visible = (AnnotationsAttribute) cf.getAttribute(AnnotationsAttribute.visibleTag);
    AnnotationsAttribute invisible = (AnnotationsAttribute) cf.getAttribute(AnnotationsAttribute.invisibleTag);
    for (javassist.bytecode.Annotation ann : visible.getAnnotations())
    {
         System.out.println("@" + ann.getTypeName());
    }

    The visible and invisible attributes correspond to Runtime and Class visible annotations. From this information you can obtain annotations attached to the class. Javassist has a reflection-like api that allows you to iterate over methods and fields of the ClassFile. Getting annotation information for methods and fields is exactly the same as getting them from the class.

    New Scannotation Framework

    I’m writing this blog because I actually had to do a lot of this scanning for JBoss’s EJB container and recently the JAX-RS implementation I’m working on. Because I thought this code might be useful, I created a sourceforge project for it called Scannotation. The Scannotation framework encapsulates all the ideas and functionality I talked about in this blog. It centers around three classes: ClasspathUrlFinder, WarUrlFinder, and AnnotationDB.

    ClasspathUrlFinder finds classpath URLs for you. It has methods to obtain them from the java.class.path System property. Other methods to find an archive URL by providing a classloader resource name as described earlier in this blog. WarUrlFinder encapsulates finding URLs for your WEB-INF/classes directory as well as the jars in WEB-INF/lib. Its pointless to repeat the javadocs for these classes so just follow the links above to find out more information.

    The AnnotationDB class consumes URLs you find through ClasspathUrlFinder or WarUrlFinder. It scans them for .class files and uses Javassist to make two indexes:

    • An index keyed on the fully qualified name of an annotation, with a set of classes that use that annotation
    • An index of fully qualified class names with a set of annotations that that particular class uses

    Here’s an example of scanning your Classpath:

    URL[] urls = ClasspathUrlFinder.findClassPaths(); // scan java.class.path
    AnnotationDB db = new AnnotationDB(); db.scanArchives(urls);

    Here’s another example of scanning all JPA archives:

    URL[] urls = ClasspathUrlFinder.findResourceBases("META-INF/persistence.xml");
    AnnotationDB db = new AnnotationDB();
    db.scanArchives(urls);
    Set<String> entityClasses = db.getAnnotationIndex().get(javax.persistence.Entity.class.getName());

    From this mini annotation database, your annotation frameworks can pick out which classes the care about more easily. Eventually I want to write ant task and maven plugin that will add an annotation index into a file within META-INF of your jars. That way you could precompile this index at build time and save some CPU cycles. If anybody is interested in doing this, let me know and I’ll give you SVN access to the project.

    EDITED 3/31/2009:

    You might want to check out the Reflections project.  I think they have taken scannotations to the next level.  I personally have not been able to maintain the scannotations project.

    MVC plumbing sucks

    3 Comments

    I agree with new JBossian, Andy Rubinger. Plumbing sucks. Andy talks about how he hates Struts, et al. and wished he could rip it out for a more lightweight model where the client is Ajax/JavaScript talking directly to EJBs on the server side. Andy is a young guy (still in his 20’s I believe) so he possibly missed all the 3-tiered application development done in the mid-90’s with VB, VC++, and Power Builder. Personally, I miss those days because GUI development was fun and productive.

    If Andy likes this idea so much, he should take a look at what Jeff, Nolan, and Ben are doing at Appcelerator. The Appcelerator approach is interesting in that it is very much like Andy wants. They turn HTML/Ajaxey based applications into an event/message based model. What I think is interesting about their approach is:

    • You can mock-up your server interactions directly within your web pages. This allows the client app developers to create a working application that doesn’t require a server to run and that can be developed independently of server side business logic
    • Your server can become stateless. Since AJAX applications can hold state, this means no more HTTP Session replication on the server side and that the server needs less memory.
    • Client architecture is decoupled from the server side architecture (but not completely, I’ll explain later). With JSF, Seam, Spring, or (insert your favorite Java webflow framework here), you’re basically married to Java. This means no experimenting with Ruby, Groovy, Rails, Grails (why you’d want to, I don’t really know 😉 but hey, you have the option). Appcelerator works with Java, Ruby, Python, and even .Net.
    • Things like validation are done on the client by marking up the validation logic directly on HTML elements. Other AJAX frameworks do validation on the server by sending tons of mini messages back and forth. What a silly idea guys. You wonder why you have to do unnecessary rearchitectures like Jetty’s continuations. Anybody who has ever written a distributed application realizes that to scale you must minimize message passing.
    • You don’t write much Javascript. You embed event modeling directly with HTML attributes.

    There’s a billion AJAX frameworks out there. I couldn’t find any out there that had all these attributes. (If you know of one, I’d be happy to add and edit this blog). What I didn’t like about their project was:

    • You still have to edit HTML. Not sure how well app-dev lifecycle would work if you used a professional designer app with Appcelerator.
    • I’m not sure how they would handle localization/internationalization.
    • Their widget set is still relatively small
    • Appcelerator’s distributed messaging architecture is Appcelerator specific. Yeah, it works on Ruby, Java, et al. but you still have a coupling between your client and server architectures via Appcelerator’s messaging layer. Which brings me to my next point…

    What if you replace EJB invocations in Andy’s utopia and appcelerator messages in Appceleratorland with a REST based approach? Bill Higgins wrote a great article about AJAX + REST awhile back. If this approach goes mainstream, we’re just turning the clocks back to a 3-tiered architecture. I dont’ think that’s a bad thing though!

    There is at least one drawback I can thinking of. Hyperlinks. Hyperlinks are just so important in integration and propagation of information. In a pure AJAX+REST approach, you give up on hyperlinking and your app behaves really like a traditional Swing/VB/PB app.  Another thing is that sometimes it does make a lot of sense for the server to render content.  In these situations I still believe we can keep the server stateless and combine it somehow with teh AJAX+REST approach.  Whoever can pick out the valuable pieces of Struts-like apps and combine it with the AJAX+REST approach will truly have something compelling.

    Geronimnogo

    1 Comment

    Seems Geranium is having problems.  Can’t say didn’t tell you so Savio.

    Maven, Hibernate, JPA

    9 Comments

    I’m a maven noob. Wanted to integrate Hibernate 3 and JPA into a Maven 2 project.  Not really into the hibernate maven plugin (anybody have good/bad experiences with it?) because I’m actually superstitious and like to control things myself, so I decided to integrate manually.  After a little bit of trial and error and updating the JBoss maven repository here’s a sample pom.xml

     <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>org.resteasy</groupId>
        <artifactId>titan-cruise</artifactId>
        <packaging>jar</packaging>
        <version>1.0</version>
        <name>titan-cruise</name>
        <url>http://maven.apache.org</url>
        <repositories>
            <repository>
                <id>jboss</id>
                <url>http://repository.jboss.org/maven2</url>
            </repository>
        </repositories>
        <dependencies>
            <dependency>
                <groupId>hibernate</groupId>
                <artifactId>hibernate3</artifactId>
                <version>3.2.4.SP1</version>
            </dependency>
            <dependency>
                <groupId>hibernate-annotations</groupId>
                <artifactId>hibernate-annotations</artifactId>
                <version>3.3.0.GA</version>
            </dependency>
            <dependency>
                <groupId>hibernate-commons-annotations</groupId>
                <artifactId>hibernate-commons-annotations</artifactId>
                <version>3.0.0.GA</version>
            </dependency>
            <dependency>
                <groupId>hibernate-entitymanager</groupId>
                <artifactId>hibernate-entitymanager</artifactId>
                <version>3.3.1.GA</version>
            </dependency>
            <dependency>
                <groupId>javax.persistence</groupId>
                <artifactId>persistence-api</artifactId>
                <version>1.0</version>
            </dependency>
            <dependency>
                <groupId>javax.transaction</groupId>
                <artifactId>jta</artifactId>
                <version>1.1</version>
            </dependency>
            <dependency>
                <groupId>antlr</groupId>
                <artifactId>antlr</artifactId>
                <version>2.7.7</version>
            </dependency>
            <dependency>
                <groupId>hsqldb</groupId>
                <artifactId>hsqldb</artifactId>
                <version>1.8.0.2</version>
            </dependency>
            <dependency>
                <groupId>jboss</groupId>
                <artifactId>jboss-common-core</artifactId>
                <version>2.2.0.GA</version>
            </dependency>
            <dependency>
                <groupId>commons-collections</groupId>
                <artifactId>commons-collections</artifactId>
                <version>3.2</version>
            </dependency>
            <dependency>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
                <version>1.1.0.jboss</version>
            </dependency>
            <dependency>
                <groupId>javassist</groupId>
                <artifactId>javassist</artifactId>
                <version>3.6.0.GA</version>
            </dependency>
            <dependency>
                <groupId>cglib</groupId>
                <artifactId>cglib</artifactId>
                <version>2.1_3</version>
            </dependency>
            <dependency>
                <groupId>dom4j</groupId>
                <artifactId>dom4j</artifactId>
                <version>1.6.1</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.1</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.5</source>
                        <target>1.5</target>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>

    JRuby and ActiveHibernate

    1 Comment

    No, I’m not changing my mind about Ruby just yet, I’m just building up debate ammo actually. 🙂

    Anyways…I’ve been trying to read up on Ruby, Rails, and ActiveRecord lately and came across two different technologies I’d like to ask you readers about. The first is JRuby. JRuby is a Java implementation of Ruby, in the same mold as Jython. It allows you to run Ruby code with the JVM and also gives you the ability to use any Java API you have available in the classpath. The question:

    If JRuby is stable, why would you ever want to use vanilla Ruby?

    Ruby has traditionally had huge threading problems, from what I’ve read, that Java has pretty much nailed down since it improved its memory model in JDK 5.

    The next piece of technology I came across was ActiveHibernate. The idea of this project is to allow Hibernate to generate Ruby rather than Java objects when you interact with your database. The project looks a little raw (there’s no downloads), but if you dive down into the code, you see that the implementation is very small. ActiveHibernate uses Hibernate’s dynamic-map entity mode along with a Ruby specific tuplizer, so there’s only a handul of things to implement. JRuby actually has done most of the work for you by providing nice utility methods to convert Java objects to Ruby. I haven’t tried ActiveHibernate out at all, but what you’d be doing is solely defining hbm.xml mapping files. The Hibernate Tools project allows you to point to a DB and generate hbm.xml files (as well as Java classes and even a small website scaffolding like Rails does), so you’d have the same productivity as active record.

    Hibernate has caching (2nd level and query), optimistic locking, a rich query language, and rich mapping strategies. They have also thought about migration strategies as well. So the question is:

    If ActiveHibernate is viable why would you ever want to use ActiveRecord?

    There are so many great technologies in Java land beyond Hibernate that you are able to leverage with languages that run on top of the JVM. If you believe dynamic un-typesafe languages are the future (i’m not one of them BTW), then don’t you think we should be leveraging all this old technology?

    JBoss to be rebranded

    12 Comments

    RALEIGH, N.C.–(BUSINESS WIRE)–Red Hat (NYSE: RHTNews), the world’s leading provider of open source solutions, today announced that their JBoss division which they acquired for $350 million dollars back in June, 2006, will undergo a complete rebranding of their product line. JBoss will be rebranded to JMoss. The move is expected to skyrocket sales and take the old JBoss product line to an undefeated presence in the middleware market.

    “Having boss as your brand is one thing. I like being the boss, but having Moss be the cornerstone of your brand turns a great team into an unbeatable one,” said Matthew Szulik, CEO of Red Hat. “The executive team, being Massachusetts natives, are all behind such a move,” said Paul Cormier, Executive VP of Engineering, “One of our engineers, Bill Burke, came up with the idea while watching our local football team embarrass an overrated opponent over the weekend. I thought it fit, so I passed the idea along to Matthew.” When Sacha Labourey, CTO of the JMoss division, heard that the rebranding was inspired by Masschusett’s american football team he said, “Us Europeans realize that american football is the best sport in the world and that soccer is for girly men, so I’m 100% behind the rebranding.”

    About Red Hat, Inc.

    Red Hat, the world’s leading open source solutions provider, is headquartered in Raleigh, NC with over 50 satellite offices spanning the globe. CIOs have ranked Red Hat first for value in Enterprise Software for four consecutive years in the CIO Insight Magazine Vendor Value study. Red Hat provides high-quality, affordable technology with its operating system platform, Red Hat Enterprise Linux, together with applications, management and Services Oriented Architecture (SOA) solutions, including the JMoss Enterprise Middleware Suite. Red Hat also offers support, training and consulting services to its customers worldwide. Learn more: http://www.redhat.com.

    Edited 12/11: I can’t believe I have to say this, but a couple of people thought this entry was real.  GUYS, its just for fun!

    Older Entries Newer Entries