Friday, 12 October 2007

Roll your own poor man's injection, dirty style..

So I have to be honest, I'm a big fan of dependency injection, declarative transactions and automated session management, but I'm not a great fan of the almighty container. One of the weaknesses of EJB3 in my view is that you don't get services ala carte. I want Hibernate session management, but do I REALLY need object pooling (which is oft bad for garbage collection on high performance multiprocessor systems)? I want resource injection or declarative transaction management, but do I really need a special interface? I understand some of the technical reasons for these, but the technology for going without the full monty exists. That is why I'm kind of excited by both the work that Bill Burke is doing on EJB 3.1 and Spring's embrace of annotations. Still sometimes both are way overkill. The other night I was explaining to someone that sometimes I do my own "dirty injection". Take the following example from the not yet committed LDAP integration code in Meldware:

        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        Class handlerClass = null;
        XMLCommand cmd = null; 
        try {
            String classname = FULL_PKG+op+COMMAND_EXT;
            handlerClass = loader.loadClass(classname);
            cmd = (XMLCommand) handlerClass.newInstance();
        } catch (Exception ex) {
            // TODO remove stack trace, add formal error handling messages
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
...
        try {
        	Method m = handlerClass.getMethod("setUserProfile", new Class[]{UserProfileService.class});
        	m.invoke(cmd, new Object[]{this.ups});
        } catch (Exception m1) {
        }

The key part is at the end with the "Method m =" stuff. This is basically part of a servlet that delegates to command handlers, some of which need certain services and some of which don't. You could do this with annotations if you wanted, by calling getMethods(..) and checking them for the wanted annotation, but this isn't a general use framework so a naming convention is fine for us.

I'd probably be more inclined to use EJB3ish type stuff for things like this if I could just new up stuff sans container and get just the services I ask for. JBoss has the technology to do this in fact with CgLib and such, but I think Burke has an AOP and EJB mindset which means: classloaders and pre/postcompilers or the almighty container. On the other hand Spring wants me to learn about "The RequiredAnnotationBeanPostProcessor" which sounds just awful. Worse there still seems to be XML spawned, and I would possibly remove the angle brackets from my keyboard if they weren't so darn useful in if statements. I get the "I don't want to play tricks" but I dunno CgLib (used by hibernate to make its proxies) seems pretty solid to me and I realize I'll need some kind of factory that does essentially what the above does, but why does the amount of reading I have to do to use it have to exceed the length of the above code sample and this blog entry (which is full of bloviation to boot)? Could be the doc, could be that I'm in a cranky mood, or it could be that the implementation could still be simpler. I report, fair and balanced, you decide :-).

I guess my bias would be to go with Spring if I had to choose now a days. I love Burke and the gang but my tolerance for closed-committee design is low. I can tell that Burke wants that to change, his frequent and detailed technical blog entries virtually make EJB committee secrecy not worth the time, but unlike Burke, the rest of the committee isn't taking accountability for the ideas and all of the other BS that goes into a committee. Kudos to Burke for giving us an inside look into the witch potion making (I assume all secret committees are doing something unholy possibly involving bestiality and things that would make Hani blush)! I think that right now the representative to the EJB committee from Oracle must have just proven he doesn't understand relational databases! The representative from IBM has just insisted that we have 12 new required interfaces instead of none and that the EJB3.1 TCK contains terms which will prevent open source implementations. Why do I assume this? Because if they don't want me to know...they must be dirty and incompetent. Since I don't know -- I have a very vivid imagination. (And why has Sun made worshiping the "dark lord" a requirement of the EJB3.1 TCK license?)

Technorati Tags:

Posted by acoliver at 9:45 AM in Tech tips

Friday, 3 August 2007

Jamie Zawinski's jwz.org expires

So jwz.org is expired and links to a "buy this domain" type page... We should buy it or something and link the groupware post to http://buni.org ;-)

Technorati Tags:

Posted by acoliver at 2:33 PM in Tech tips

Friday, 8 June 2007

Rails

I don't normally listen to podcasts because they're long and linear and I can't scan past the boring parts as easily. However Norm Richards turned me on to this Drunk and Retired podcast about Rails that I listened to in the background while doing clerical work. It is good to hear some of the things I've observed technically as well as some of the community issues that I'm oblivious to. They didn't talk about things like the transaction API and stuff that guarantee unmaintainable un-reusable crappy code... What is interesting is what a lemming this guy is, so why use rails? I mean I do love Ruby, don't get me wrong...its Rails that I think is crap.

Technorati Tags:

Posted by acoliver at 10:18 AM in Tech tips

Thursday, 24 May 2007

javaBlogs gone screwy again

Max asked why we repost to JavaBlogs... I answered that we don't. In fact JavaBlogs now is including things in feeds that aren't actually in the feeds. Case in point my feed vs what JavaBlogs includes. Of course it then for some reason makes all of our stuff new again, which made everyone ignore us...

Technorati Tags:

Posted by acoliver at 10:09 AM in Tech tips

Sunday, 20 May 2007

DeadBox-360

Yesterday we got the XBox-360 E74 error. After disconnecting everything and reconnecting and trying w/o the hard drive connected (you can remove it by pressing the button on the side and pulling on the big block that says HDD), we called support. A very nice lady with an Indian accent (who despite claims in the aforementioned google search spoke perfect and understandable English) who claimed her name was Shaniqua helped us, figured out the warranty and is sending us a box to ship it back in. So after nearly a year of relatively light gameplay it has given up the ghost. Meanwhile the Playstation III is downloading another system update.

Technorati Tags:

Posted by acoliver at 8:48 PM in Tech tips

Friday, 11 May 2007

Dive Into Mark on Adobe Apollo

Following a blog-refer-thread off of Sam Ruby's 'Control You' entry:

Whether or not you agree with Mark Pilgrim on Flex/Flash, he writes a hell of a piece.

Adobe introduced Apollo, their latest attempt to recreate the web in their own image. Apollo is based on Adobe’s own markup language, Adobe’s own runtime, Adobe’s own graphics and animation framework, Adobe’s own video and audio codecs, and Adobe’s own developer tools. You can do many things with it, but “you may not sublicense or distribute the Software. … You may not modify, adapt, translate or create derivative works based upon the Software. You may not reverse engineer, decompile, disassemble or otherwise attempt to discover the source code of the Software. … You may not install or use the Software on any non-PC device or with any embedded or device version of any operating system.” It requires at least Windows XP SP 2 or Mac OS X 10.4.

The only part I disagree with is "the web". Actually Apollo is more about the desktop. Adobe needs to pursue openness more aggressively than it is. Announcing something 7 months before you do it with only a mailing list is...curious. Implying that you're doing that so that open source doesn't derail all stability and destroy your product is...an interesting message. Apollo isn't that relevant actually, I have several technical concerns with it and am dubious about its chance of success. In fact you probably don't need Apollo at all to achieve a good 90% of what Apollo wants to achieve and with only today's technologies. Java Webstart + izPack + Tomcat + a Flex API and you could do all the local storage you want and arguably most of the other stuff too. But as Mark points out, you'd be leaving vendor wonderland. That being said, I'm not opposed to Adobe having an even bigger role in defining the web provided they democratize and open up their platform a bit.

This guy raises a few good points but thinks that Mozilla will save us:

(We also don’t make you sign licensing agreements to get the format specifications, or prevent you from competing with us. We don’t tell you where you can and can’t install the software. We don’t tell you what you can and can’t tell people about your experiences, or that you can’t give it to other people with whom you might want to collaborate.)

...

Mozilla has always valued and supported web developers, and in turn those who support developers with tools and other assets, and we’ll invest more in this area over the coming year. But we’ll do it in a way that makes sense for the whole web, and brings to bear the human-manipulable power of web technology: a great set of primitives that people combine in very different ways, giving developers a great opportunity to choose tools and toolkits and patterns and technology that suit how they want to work and what they want to build.

The web can eat toolchain bait like this for breakfast. And, if Mozilla has anything to say about it, it will do just that. You won’t have to give up the web to work offline any more, or programmable 2D graphics, etc. Soon you’ll have the power of 3D and great desktop/application integration as well, via projects like canvas3d and registration of content handlers, and you’ll have it in a way that’s built on open specifications and a tool ecosystem that isn’t a monoculture. Why wouldn’t you choose the web, given its record and power and openness?

While I agree Mozilla is certainly more open and credible than Adobe as far as openness, standards support and lock-in avoidance... How does any of this stuff work in IE? Secondly, if everyone uses Mozilla then won't it fall into the same rut as IE did? Thirdly, Mozilla's credibility in the "Rich" of RIA...XUL is Mozilla's IE... They had a great thing...dropped the ball and let it whither. Meanwhile they haven't shown a great deal of motivation to work with or around Microsoft to make all of this stuff work anywhere BUT in Firefox. While buni.org traffic is > 50% Gecko based browsers (~48% Firefox) though nearly 75% Windows (I use Linux) -- I would bet that this is not a representative sample of the web at large.

Ultimately DHTML (aka AJAX) isn't enough. Sun's "silly season" scripting language over applets (aka JavaFX) is more of the same (and very disappointing). Microsoft's Silverlight smells of .NET and I'm sure will please their regulars, but will whither in adoption on the web as a whole. The richer web is coming and it is a race to openness as to who "wins". Guys...you can help define it, and make a lot of money selling the tools/services around it...but not own it. Any attempt to do so will create a "wedge issue" and limit your message and market opportunity to the party faithful...or your regulars if you prefer.

Technorati Tags:

Posted by acoliver at 11:49 AM in Tech tips

Monday, 7 May 2007

James Ward's Google talk on Flex/Flash/Apollo

While looking down a list of Google Tech Talks, I discovered James Ward's Flex/Flash/Apollo talk. For some reason my sound is gone so other than the fact that James is still sporting the Buddy Holly evangelical preacher look that he adopted this year, I can only say that next time I reboot I'm sure it will be good. James is a "Technical Evangelist" for Adobe and contributor to Buni's Webmail/Webcal client which is written in Flex.

Technorati Tags:

Posted by acoliver at 3:38 PM in Tech tips

Saturday, 31 March 2007

Apple gets it right...mostly (Fun with Apple pt V)

So I guess I get to eat a little crow. As it turns out my mouse wasn't broken in fact my battery had swollen to the point that it was preventing the mouse from being clicked. Although my battery wasn't one of the recalls, it was nonetheless defective. Now the good in this is that the Apple "genius" was good, he acknowledged my quickly and then when I showed him the problem, he flipped it over and saw the battery had swollen and demonstrated that w/o the battery the laptop was fine. Following this he (while helping someone else) got me another battery. The bad in this is that Apple is apparently aware that there are batteries that have metal shards in them that are swelling and are a potential hazard -- but they have not recalled them. So my laptop is back.

Technorati Tags:

Posted by acoliver at 6:55 PM in Tech tips

Apple !$!@ pt IV

I whined to a fellow LUG member who works at the Apple Store the other night about my really "fun" Apple experiences. He explained the whole $250 isn't enough, they need another $100 to not suck. I knew this. It only reinforces my bad attitude. So today because I was bad mouthing my Laptop's parent company...my mouse button broke. Now it it just wasn't working, no big deal hook up an external mouse...take it in as you have time... However, it broke in a stuck down position. You can imagine my pure pleasure at this. I think I need a backup laptop, to quote Q-Bert: "#!$!@#".

So this is probably how this will roll. It is futile to call Apple because they feel I might be wrong that the mouse button that is physically stuck down (apparent to any moron who attempts to press it) is broken. It will require a "genius" to attempt to press it and realize that indeed it is stuck down. Next, the "genius" after 10 minutes of dorking with the computer, will realize that they do not have the part and I must bring the laptop back in for repair. It will take a number of days. Then they have me come back in...wait at the counter well past my appointment type just to print out a sheet of paper and take the laptop into the back room. I will mumble to myself and plot their deaths. I'll go catch a movie, and get the laptop back. In three weeks another key will break.

Mike, I changed my mind. Marc was right about Apple...even the magnet power isn't worth all this.

Technorati Tags:

Posted by acoliver at 1:03 PM in Tech tips

Friday, 16 March 2007

Bring on the Blue: Java port of Nagios

I just found Rich Friedman's blog. Rich was head of management stuff at JBoss and moved to doing the overall thing at Red Hat. I just read in his archives that he is writing a Java version of Nagios. I fell in love with Nagios when Nicholas Whitehead demoed it at JBossWorld a few years back. The results those ADP boys were able to achieve were incredible. However, I've never run it...it requires Windows. That is why I say "GO RICH GO!" I can't wait to see this one.

Just one suggestion..."Blue" is such a generic name. Pick a better project name. For instance, I offer you conclusive evidence that Spring is a bad brand name whereas JBoss is a good brand name as is Meldware. Blue is a terrible brand name for many reasons. In fact this project was unofficially codenamed "Blue" for a little while.

Posted by acoliver at 1:01 AM in Tech tips

Is JBoss your friend?

Is JBoss your friend? Maybe it is just me, but some days I think it is my friend. Other days I think it is out to make me loose my mind. If you're a good bit younger than me, and JBoss is your friend, maybe you can add JBoss to your friends list on MySpace. If JBoss is not your friend today, maybe JIRA is a better place to start.

Posted by acoliver at 1:00 AM in Tech tips

Thursday, 15 March 2007

Belated Pi Day post

I saw this:

and thought I'd share.

Posted by acoliver at 12:59 PM in Tech tips

Monday, 12 March 2007

Design Issues in High-Performance Transactional Applications using Java and Linux

I have another article on Java performance on Red Hat's 108 site. This article focuses at the persistence layer.

Posted by acoliver at 1:00 AM in Tech tips

Friday, 9 March 2007

Fun with Apple's part III

So last week I did get my keyboard replaced. An apple person called and told me it was there. I went in the morning and dropped my laptop off and they replaced the keyboard. Then they called and told me it was ready. I had to assail someone going back and forth and shove my work order down their throat after about 30 min of standing there unacknowledged by the "genius"es or various employees walking by. They were like "not my job but I'll try"..

So my MagSafe power cord shorted out. Apple's cords are really pretty and really flimsy. Granted this is still better than ripping a power coupling out, but after wrapping and unwrapping the cord between home and office for some months the cord had come unglued from the plug (or more accurately the cord came unglued from the sheath that is connected to the plug).

So I saw this was happening and ordered a new one from the Apple Store Website. Notice all of the negative reviews (Mine is AO from Durham) saying similar things "right idea, poor construction". Of course it shorted out before the new one arrived (the plastic melted as the exposed wires touched the sheath at an angle). So I drove back to the actual Apple Store and bought a new one. Of course you know what happened...I unpacked it, used it at the cafe while I ate lunch and had a quick con call at the office...when I got home of course the other one had arrived (despite using the cheapest shipping option).

update: after writing this entry and clicking on the magsafe Technorati tag...I discovered this entry. Indeed my new cord seems to have the improved sheath. I'll probably wrap electric tape around it as well and keep both just in case. I also forgot to mention how fun it was when I handed a business credit card to the counter wonk who immediately tried to get me to fill out for their business card (like it was procedural) and as a chief selling point they would give me business consultation. I probably sounded really snobby when I said "I'm a software developer and run Linux on it" but I find the whole marketing experience of the Apple Store kind of annoying. Aside from the "you bought a Mac and therefore must be stupid" assumption -- the iPodization has them catering to a crowd who don't scoff at the "put some music on" fashion ads. I guess as a "genXer" -- in marketing terms -- I want to delete those screen savers and then kick the cardboard cut outs in their androgynous girl-boy parts.

Posted by acoliver at 1:00 AM in Tech tips

Thursday, 1 March 2007

Removing AOP magic with Java Closures and Java Closure method assignment

So I love VMs and I don't think Java is a great language (it is an "OK" language), but the JVM is the most productionable VM to date! Java doesn't make your mail server slow, your storage strategy makes your mail server slow :-). You will live or die by IO, not the few extra microseconds in Java's type system or the time between not-JIT and JIT or 1-10 line to instruction ratios or anything that the uninformed would complain about...Though it will suck air if you invoke the RMI subsystem anywhere and don't do this. Most professional C programmers use memory pools rather than malloc and free because they recognize that they are not indeed infalliable. Most of today's professional C programmers also use a sort of home-grown type system. So we're really not even talking about garbage collection or typing we're talking magic pixy dust (the same ASM out of the C compiler is just FASTER than the same ASM from Hotspot) or "load time". Don't "be a man"...just grow up and get some facts. I'd rather have a spot for you next to one of the world's best software developers and not at the kiddy table. But I digress...

I don't really love AOP very much (and if you aren't an AOP/EJB buff bear with me, this isn't REALLY about either, I'm using this as a demonstration for some candy I'd like to eat). I regard it as a lot of academic BS wrapped around some dirty hacks for what Java should do anyhow. You do hear about AOP in other languages but they're mostly talking about the runtime system to apply advice selectively (complete with academic gobbledy-gook language meant to complicate simple things), but not even 1/10th as much as in Java. They just don't need it as much.

Java's static typing coupled with missing features are why so much Majick is needed. The first things is closures. Closures as specified for JDK 7 more or less let you extend the language as follows:

public Currency transferMoney(Account from, Account to, Currency amount) {
    Currency transferred = null;
    transaction.required {
       Currency withdrew = withdraw(from, amount);
       Currency deposited = deposit(to, amount);
       if (!withdrew.equals(deposited)) {
          throw new CurrencyException("The amount withdrawn did not equal the amount deposited in transfer money (amount,withdrew,deposited)", amount, withdrew, deposited);
       }
       transfered = new Currency(amount);  //copy constructor
    }
    return transferred;
}

In EJB3, you would do this with the @TransactionAttribute(TransactionAttributeType.REQUIRED) annotation. I would argue that in many cases closures are more appropriate. On one hand pervasive imperatives such as is required with "Bean Managed Transactions" in EJB and JTA is horrible. BTW Ruby on Rails's transaction support looks more like BMT in EJB/JTA than any of the above ;-). On the other hand EJB transaction tags are rather limited too (as described below).

The weakness of closures is that a lot of things really do have inherent transactional natures. Closures capture the above case where depending on the transaction you might do a withdrawl REGARDLESS of a deposit, but in this case you want them both in the same transaction. Doing this right means doing it in a way that is both simple and flexible. However, *not* having a default transactional nature is dangerous. Developers may forget something especially if 99% of the time it is repetitive template code (indeed EJB defaults to "REQUIRED"). A good API, language or whatever is designed for use by fallible programmers to use.

With EJB3+ this isn't a big deal. Since EJB3 maintains the same calling semantics. If I did this:

SomeEjb {
   @TransactionAttribute(TransactionAttributeType(TransactionAttributeType.REQUIRES_NEW)
   public void requiresNew() {...}

   @TransactionAttribute(TransactionAttributeType.REQUIRED)
   public void required() {
      doStuff();
      this.requiresNew();
      doOtherStuff();
   }

}

and called "required", I would ONLY have one transaction and not the expected 2. EJB3 maintains the call by proxy semantics of EJB2. Meaning if I want the transactional nature of the method I must get the local or remote interface and not just do a Java-to-Java call. This is where the legacy of EJB2 infects EJB3. It isn't intuitive even though you may understand that IBM isn't going to stick byte code manipulation in WebSphere. You can solve this unintuitiveness by using something like JBossAOP @Tx(TxType.REQUIRED) annotation that actually does require/use bytecode manipulation:

SomeEjb {
   @Tx(TxType.REQUIRES_NEW)
   public void requiresNew() {...}

   @Tx(TxType.REQUIRED)
   public void required() {
      doStuff();
      this.requiresNew();
      doOtherStuff();
   }

}
 

Now I get two transactions because I either used JBoss's bytecode weaving at deploy time or I used "aopc". However, aren't you uncomfortable with bytecode manipulation in the classloader or a post compilation process in your build that forever ties each build to that version of the appserver or JBossAOP? I know I am. On the other hand a pre-compilation process sucks even more.

The closure version (with "inherent transactional nature") might look like this:

SomeEjb {
   
   public void requiresNew() { 
      Transaction.requiresNew {
      ...
      }
   }

   public void required() {
      Transaction.required {
          doStuff();
          this.requiresNew();
          doOtherStuff();
      }
   }

}

But boy it is easy to screw that up huh? And worse the caller can't override it. Maybe the original implementor thinks it has an inherent transactional nature and maybe 99.9% of the time it does. Ideally I want both annotations AND closures but NO bytecode magic. The cool thing is that if you're happy with the special proxy calling rule, then all you need to do is add it to your InvocationHandler or in the container code itself (WebSphere doesn't use dynamic proxies) and you're done!

However I'm not happy with the special proxy calling rule are you? That's cruddy and inherently confusing. What we need to round this out is a way for the deployer to assign a closure to a method. Meaning it would reflect on the bean, see that it had an annotation, then assign a closure to the method. "whenever you see this, then assign this closure to it".

  Class clazz = ...;
  Object bean = ...;
  Method method = ...;

  if (methodHasTransactionRequired(method)) {
     method.setClosure(bean, required);
  }

Meaning whenever that method is called on that bean on that instance...wrap it in the closure. However there can be only one closure in the above code. Really we want to allow at least 32767 of them, give or take. So we could just do method.addClosure(bean, required)...but I'd like to be able to manipulate them really.

  Class clazz = ...;
  Object bean = ...;
  Method method = ...;

  if (methodHasTransactionRequired(method)) {
     InstanceCallStack stack = method.getInstanceCallStack(bean);
     if (!stack.contains(required)) {
         stack.add(required);
     }
     //method.setInstanceCallStack(bean, stack); ?
  }

Where InstanceCallStack subclasses Stack and contains closure objects. You can then inspect, add, and remove them. Obviously there are other uses for this. My point is that it accomplishes much of what AOP does (AOP advocates would say it is just a replacement for a method of implementing AOP rather than AOP itself meaning the closure is the encapsulated advice).

At the lower level there would have to be a similar switch as was done in the jit for contended and uncontended locks (syncronized) [pdf] to avoid needless dispatches for the 99.999% of all methods that have a null instance callstack. Indeed initial callstack creation wouldn't be entirely thread safe (meaning any instances about to go into it might get the null instance call stack) and therefore the instance call stack itself might be better off semi-immutable (instead rely on a semi-atomic "set" and any "getInstanceCallStack" is merely a copy thereof). If done correctly this means no or immesurable performance decrease for invocations on methods with a null call stack and stack.size() * methodDispatchPerformance degredation for those with a call stack (excepting what work is actually done in the closures).

So right now as I read the closure spec there is nothing like this and Java still has no runtime meta-model. This would be a first step in my mind towards mutators on Method objects (add a method to an object) and optional dynamic typing (maybe a DynamicObject obj = Class.getDynamicType(object)), but at least it removes the need for 99% of AOP precomplation and postcompilation code magic :-). Sadly except for the first code snip with closures...this all only exists in this blog entry :-).

I'm interested in what people think about this and the Java closures proposal itself so I'm putting it in my semi-spam protected Buni tech tips blog...which was originally going to just be a continuation of my "stupid shell tricks" and "how to" type stuff (which is the ultimate search engine optimization ;-) )...but it has evolved I guess into "stuff I want to say about technology but don't want on the front page" ;-). If you haven't watched the GoogleEDU video on closures you probably should. Might also make the above parse better.

Posted by acoliver at 1:50 PM in Tech tips