tag:blogger.com,1999:blog-39155440307355874252024-03-14T08:33:50.685-07:00Development for the massesA blog about software development and other software related mattersronenhttp://www.blogger.com/profile/13360463320878175457noreply@blogger.comBlogger55125tag:blogger.com,1999:blog-3915544030735587425.post-12853251608801386362010-04-04T05:26:00.000-07:002010-04-04T05:34:42.432-07:00Moving into narkisr.comThis blog has served me well for the past three years still iv decided to give it a new home that iv developed, eating my own dog food.<br /><br />Since Iv developed the entire thing I believe that the reading experience will be better & more interesting to you all, all the old content has been migrated, ill redirect to the new one. <br /><br />Looking forward to meet you there!ronenhttp://www.blogger.com/profile/13360463320878175457noreply@blogger.com0tag:blogger.com,1999:blog-3915544030735587425.post-60701639984368288982010-01-09T08:13:00.000-08:002010-01-09T09:45:54.776-08:00Cool Groovy techniquesGroovy is a versatile & very powerful language to code with, as a Java super set it enables a Java programmer to write its code with all the known Java idioms & progress into Groovy land in small steps, in this post ill present two techniques that I find to be very powerful.<br /> <br />The first is closure initialization, in Java land its common that when we have an object A which uses another object B with non trivial construction code (which depends on A's input) than we write all the initialization code of B inside A constructor:<br /><div class='gray'><pre name="code" class="java"><br />class ComplexInit { // our B<br /> // ... some state that need to be initialized by users of this class<br />}<br /><br />class UsesComplex {// our A<br /> private ComplexInit v<br /> def UsesComplex(){<br /> v = new ComplexInit()<br /> //.. some complex initialization logic which depends on UsesComplex <br /> }<br />}</pre></div><br />Another common practice is to create a factory that will encapsulate the initialization of ComplexInit class taking A as input:<br /><div class='gray'><pre name="code" class="java"><br />class ComplexInitFactory {<br /> def createComplexWith(UsesComplex u){<br /> // initialization code which depends on <br /> }<br />}</pre></div><br />Groovy offers another way which I named "closure initialization":<br /><div class='gray'><pre name="code" class="java"><br />class UsesComplex{<br /> private ComplexInit val = {<br /> def result = new ComplexInit()<br /> // more logic here<br /> }()<br /> <br /> def UsesComplex(){<br /> // ComplexInit is initialized above <br /> }<br />}</pre></div><br />Note that we are embedding a closure within the UsesComplex class & call it immediately after it has been defined, this resembles static initializer code blocks in Java except that it not static at all, the anonymous closure has access to its surrounding scope & can access other data members during its run:<br /><div class='gray'><pre name="code" class="java"><br />class UsesComplex{<br /> def today = new Date()<br /><br /> private ComplexInit val = {<br /> def result = new ComplexInit()<br /> result.a = today<br /> result<br /> }()<br />}</pre></div><br />By separating our constructors into initialization blocks we modularize the construction of our object, making our code more readable & DRY (no separation between deceleration & initialization).<br />Another interesting technique is dynamic method dispatch, in Groovy we can dispatch methods like so:<br /><div class='gray'><pre name="code" class="java"><br />class Target{<br /> def methodA(){ println 'hey'}<br />}<br /><br />new Target().methodA()<br />new Target()."methodA"()// this works too!</pre></div><br />This means that we can dispatch methods according to run time logic:<br /><div class='gray'><pre name="code" class="java"><br />class Target{<br /> def calcA(){'a'}<br /> def calcB(){'b'}<br /> def calcC(){'c'} <br /> def notCalc(){'d'}<br />}<br /><br />def t = new Target()<br />def calcs = t.metaClass.methods.findAll{it.name.startsWith('calc')}.collect{it.name}<br />calcs.each{println t."$it"()}// will print a b c</pre></div><br />Its true that Java reflection has similar capabilities however the Java API is very verbose & not as elegant, use this technique with care since it may result with hard to read code!<br /><br />Thats about it for this post, let me know if you find these techniques useful in your code.ronenhttp://www.blogger.com/profile/13360463320878175457noreply@blogger.com0tag:blogger.com,1999:blog-3915544030735587425.post-14322866942301957362009-10-31T11:34:00.000-07:002009-10-31T12:23:43.831-07:00Synching your enviroment aroundUbuntu 9.10 has just came out & iv rushed to upgrade, upgrading my 9.04 to 9.10 via the upgrade manager is a working option but usually id rather do a clean install & get a fresh system to poke around.<br />The main issue that clean install brings is restoring your old environment which includes installed programs, settings files (.bashrc, .vimrc etc..), non packaged applications (usually the latest & greatest versions of Clojure, Groovy etc..).<br />Another issue is the need to restore these settings on multiple machines while keeping it all consistent between them, there must a better way than working it all manually!<br /><br />Well the solution that iv come with involve two tools, <a href="http://www.getdropbox.com/">Dropbox</a> & <a href="http://automateit.org/">AutomateIt</a>, Dropbox is no more than a fancy folder to the cloud synchronizer which enables me to access all my settings file from any machine, lsym-ing my .bashrc, .vimrc & any other file that id like to share across machines into the Dropbox folder is all that is required.<br /><br />The second part involves AutomateIt, which is a configuration management framework written in Ruby, an easy way of re-creating symlinks from my Dropbox folder onto a new system is using the following AutomateIt script:<br /><div class='gray'><pre name="code" class="ruby"><br />HOME = ENV['HOME']<br />DROP = "#{HOME}/Private/Dropbox"<br /><br />def link(src,dst)<br /> ln_s("#{DROP}/#{src}","#{HOME}/#{dst}")<br />end<br /><br /># Vim<br />link "vim/.vimrc",".vimrc"<br />link "vim/.vim",".vim"<br />link "vim/.vimclojure-2.1.2",".vimclojure"<br /># Bash<br />link "BashEnv/.bashrc",".bashrc"<br />link "BashEnv/.inputrc",".inputrc"<br /># Languages<br />link "prog-langs/.clojure",".clojure"<br />link "prog-langs/.groovy",".groovy"<br />link "prog-langs/.jruby",".jruby"<br /></pre></div><br />The nice thing about it is that it hides all the nitty gritty details that id have to figure out when using plain Ruby (or any other environment for that matter), AutomateIt wraps common tasks with a bash like DSL, unlike bash this DSL is portable across multiple unix systems & it hides many of the complexities that follow.<br />AutomateIt performs actions only when they are required, this solves annoying cases that rise when scripts run more than once on a system (e.g. appending text to files).<br /><br />Another cool feature is package management, AutomateIt is capable of interacting with multiple packaging systems (yum, apt, gem etc..) in a transparent way, its easy to replicate installed packages onto multiple systems:<br /><div class='gray'><pre name="code" class="ruby"><br /># bash<br />%w(terminator rlwrap).each{ |p| package_manager.install p}<br /><br /># programming<br />%w(vim git-core).each{ |p| package_manager.install p}<br /><br /># communication<br />%w(deluge openssh-server).each{ |p| package_manager.install p}<br /><br /># misc<br />%w(gpodder gnome-do).each{ |p| package_manager.install p}<br /><br /># installing dropbox<br />download_manager.download 'http://www.getdropbox.com/download?dl=packages/nautilus-dropbox_0.6.1_i386_ubuntu_9.10.deb' , :to => '/tmp/nautilus-dropbox_0.6.1_i386_ubuntu_9.10.deb'<br />package_manager.install ({'nautilus-dropbox' => '/tmp/nautilus-dropbox_0.6.1_i386_ubuntu_9.10.deb'} , :with => :dpkg)<br /></pre></div><br />Using these tools has made configuration nirvana a bit closer to me & hopefully to you :)ronenhttp://www.blogger.com/profile/13360463320878175457noreply@blogger.com1tag:blogger.com,1999:blog-3915544030735587425.post-58750152716303882952009-07-25T06:50:00.000-07:002009-07-25T09:41:36.728-07:00The easiest singleton aroundIv just finished watching <a href="http://www.lispnyc.org/wiki.clp?page=past-meetings">stuart-clojure-presentation</a> where the issue of singletons is mentioned (global & thread local ones), a note from the audience mentions delay as a solution, REPL-ing a bit shows how this works:<br /><div class='gray'><pre name="code" class="clojure"><br />user=> (defn singleton-factory []<br /> (println "creating object")<br /> (+ 1 2))<br />#'user/singleton-factory<br />user=> (def singleton (delay (singleton-factory)))<br />#'user/singleton<br />user=> (defn usage []<br /> (force singleton))<br />#'user/usage<br />user=> (usage)<br />creating object<br />3<br />user=> (usage)<br />3<br /></pre></div><br />Stuart does mention <a href="http://code.google.com/p/clojure-contrib/wiki/SingletonApiDoc">contrib singleton</a> which has also per-thread-singleton.<br /><div class='gray'><pre name="code" class="clojure"><br />user=> (use 'clojure.contrib.singleton)<br />nil<br />user=> (def t-singleton (per-thread-singleton singleton-factory)) <br />#'user/t-singleton<br />user=> (defn use-twice [] (+ 1 (t-singleton)) (+ 1 (t-singleton)))<br />#'user/use-twice<br />user=> (defn use-twice-no-singleton [] (+ 1 (singleton-factory)) (+ 1 (singleton-factory)))<br />#'user/use-twice-no-singleton<br />user=> (. (Thread. use-twice) start) ; each Clojure Fn implements Runnable<br />nil<br />user=> creating object ; REPL prints on the wrong line<br /><br />user=> (. (Thread. use-twice-no-singleton) start)<br />user=> creating object ; same thing<br />creating object<br /><br />user=> <br /></pre></div><br />This should come useful when working with all those Java mutable objects.ronenhttp://www.blogger.com/profile/13360463320878175457noreply@blogger.com0tag:blogger.com,1999:blog-3915544030735587425.post-88714209518598636032009-07-23T15:57:00.000-07:002009-07-25T06:49:26.694-07:00Dont overflow yourself!Clojure has many nice less highlighted features, one of these is overflow protection, this can be a true life saver:<br /><div class='gray'><pre name="code" class="clojure"><br />user=> (unchecked-add 1 2); not safe but might be faster<br />3<br />user=> (unchecked-add (. Integer MAX_VALUE) 2); oops<br />-2147483647<br />user=> (+ (. Integer MAX_VALUE) 2) ; using safe arithmetic again<br />2147483649<br />user=> (+ (. Integer MAX_VALUE) 23)<br />2147483670<br />user=> (class (+ (. Integer MAX_VALUE) 23)); Clojure does the right thing for us<br />java.lang.Long<br /></pre></div><br /><br />It does pack more than just concurrency up its sleeve.ronenhttp://www.blogger.com/profile/13360463320878175457noreply@blogger.com0tag:blogger.com,1999:blog-3915544030735587425.post-29380554099411791122009-06-29T14:26:00.000-07:002009-06-29T15:25:45.340-07:00Genericsfaction, getting some generics satisfactionJava generics have a lot of short shortcoming, most of which are the result of the religious backward compatibility that Java is known for. <br />One of the most annoying "features" of generics is type erasure in which the compiler removes (<a href="http://java.sun.com/javase/6/docs/api/java/lang/Class.html#getGenericSuperclass()">almost</a>) any trace of generic types meta data.<br /><br />Iv been pondering about this issue & had a simple idea, what if we could add back in the meta data that the erasing process removed?<br />So, iv decided to create a proof of concept in order to show how this might work and named it <a href="http://github.com/narkisr/genericsfaction/tree/master">genericsfaction</a>.<br /><br />Using genericsfaction requires an additional code manipulation stage in which the source code is scanned & gets its AST manipulated (meta data is introduced), each manipulated source file is dumped into a separate folder (named gen), all that is left is to compile the files under gen (instead of the original src).<br /><br />At the moment there are only two enrichments implemented, the first is method input parameters annotation enrichment:<br /><div class='gray'><pre name="code" class="java"><br />public void twoTypeParamsMet(@GenMeta(stringRep = "((Object ()) (Object ()))", classes = { Object.class, Object.class }) Map <Object, Object> map) {<br /> // method code<br />}</pre></div><br /><br />The second is variable initialization enrichment:<br /><div class='gray'><pre name="code" class="java"><br />public static void main(String [] args) {<br /> List<Integer> list = (List <Integer>)MetaProxy.newInstance(new ArrayList<Integer>(),"(Integer ())",new Class []{Integer.class});<br /> }</pre></div><br />The reason that annotations aren't used in this case is due to this <a href="http://forums.sun.com/thread.jspa?threadID=664018">limitation</a>.<br /><br />There is no release to play with yet, however the source is up on github (mostly Clojure), I am planing on making a release as soon as ill finish to implement a validation module that uses this meta data in runtime.ronenhttp://www.blogger.com/profile/13360463320878175457noreply@blogger.com0tag:blogger.com,1999:blog-3915544030735587425.post-79640729522069488392009-05-23T13:21:00.000-07:002009-05-25T12:05:36.759-07:00Newify your Object<span style="font-weight:bold;">Update</span> a generous Anonymous has left a comment that the following special macro form does the same as the newify function that i present later on:<br /><div class='gray'><pre name="code" class="clojure"><br />(def nested-object (-> GrandFather. Father. GrandSon.)) <br /></pre></div><br />Feel free to skip this entry (unless your interested in an alternative implementation).<br /><br />Instantiating large nested object graphs can be tedious in any language Clojure included:<br /><div class='gray'><pre name="code" class="clojure"><br />(def nested-object <br /> (new Grandson <br /> (new Father <br /> (new Grandfather)))) <br /></pre></div><br />All those new methods call get old pretty quickly and are not DRY, to remedy this will take advantage on a cool property of Clojure <a href="http://en.wikipedia.org/wiki/Homoiconicity">Homoiconicity</a>.<br />Homoiconicity basically means that the code is represented by a basic data structure of the language itself (lists in the case of Clojure), this means that manipulating the AST is easy as pie!<br />It would be nice if we could write something like the following:<br /><div class='gray'><pre name="code" class="clojure"><br />(def nested-object <br /> (def nested-object (newify '(Grandson (Father (Grandfather))))) <br /></pre></div><br />The newify function takes a nested list of objects & adds new before each object, post that the function evaluates the resulting list:<br /><div class='gray'><pre name="code" class="clojure"><br />(defn newify [e] (eval (newify-imp e)))<br />; required since used before defined <br />(defn- newify-rest [e] )<br /><br />(defn- newify-imp [e]<br /> (let [add-new (partial cons 'new) add-rest (partial cons (first e))]<br /> (if (not (empty? e))<br /> (-> (newify-rest e) add-rest add-new) e)))<br /><br />(defn- newify-rest [e]<br /> (map #(if (list? %) (newify-impl %) %) (rest e)))<br /></pre></div><br />The newify-imp & newify-rest functions are mutually recursive, newify-imp adds the new symbol & the first list element to the result of the newify-rest function result, the newify-rest maps each list in the rest of the list to its newified value.<br /><br />This implementation could be transformed into a recursive macro that will spare us from the list escaping:<br /><div class='gray'><pre name="code" class="clojure"><br /> (def nested-object (newify '(Grandson (Father (Grandfather))))) <br /> ; no escaping here<br /> (def nested-object (newify (Grandson (Father (Grandfather))))) <br /></pre></div><br />Ill have to dig that option later on.ronenhttp://www.blogger.com/profile/13360463320878175457noreply@blogger.com2tag:blogger.com,1999:blog-3915544030735587425.post-49674820190430228342009-04-30T15:56:00.000-07:002009-05-01T10:27:41.501-07:00NILFS on JauntyThe latest release of Ubuntu includes the long awaited Ext4 FS (works flawlessly on my system).<br />Ext4 is faster & more secure but still lacks the ability to manage FS snapshots (ZFS excels in that, but runs only in <a href="http://www.wizy.org/wiki/ZFS_on_FUSE">FUSE</a> on linux).<br />An interesting alternative is <a href="http://www.nilfs.org/en/">NILFS</a>:<br /><blockquote>NILFS is a log-structured file system supporting versioning of the entire file system and continuous snapshotting which allows users to even restore files mistakenly overwritten or destroyed just a few seconds ago. </blockquote><br /><br />NILFS maintains a repo for Hardy, the Jaunty repos contain only the user land tools which won't do us much good since we need the kernel module as well, this leaves us only with the option of installing it from source (still quite easy).<br /><br /><div class="gray"><pre name="code" class="bash"><br /># a perquisite<br />$ sudo aptitude install uuid-dev <br /># installing kernel module, result module resides in /lib/modules/2.6.28-11-generic/kernel/fs/nilfs2/nilfs2.ko<br />$ wget http://www.nilfs.org/download/nilfs-2.0.12.tar.bz2<br />$ tar jxf nilfs-2.0.12.tar.bz2<br />$ cd nilfs-2.0.12<br />$ make<br />$ sudo make install<br /># installing user land tools<br />$ wget http://www.nilfs.org/download/nilfs-utils-2.0.11.tar.bz2<br />$ tar jxf nilfs-utils-2.0.11.tar.bz2<br />$ cd nilfs-utils-2.0.11<br />$ ./configure<br />$ make <br />$ sudo make install<br /></pre></div><br />Creating a file system on a file (ideal for playing around):<br /><div class="gray"><pre name="code" class="bash"><br />$ dd if=/dev/zero of=mynilfs bs=512M count=1<br />$ mkfs.nilfs2 mynilfs<br /></pre></div><br />The FS is only a mount away:<br /><div class="gray"><pre name="code" class="bash"><br /># mounting the file as a loop device<br />$ sudo losetup /dev/loop0 mynilfs<br />$ sudo mkdir /media/nilfs<br />$ sudo mount -t nilfs2 /dev/loop0 /media/nilfs/<br /></pre></div><br />Now lets create a couple of files:<br /><div class="gray"><pre name="code" class="bash"><br />$ cd /media/nilfs<br />$ touch 1 2 3 <br /># listing all checkpoints & snapshots, on your system list should vary <br />$ lscp<br /> CNO DATE TIME MODE FLG NBLKINC ICNT<br /> 7 2009-05-01 01:08:09 ss - 12 6<br /> 13 2009-05-01 19:05:34 cp i 8 3<br /> 14 2009-05-01 19:05:59 cp i 8 3<br /> 15 2009-05-01 19:07:09 cp - 12 6<br /># creating a snapshot<br />$ sudo mkcp -s<br /># 15 is the new snapshot (mode is ss)<br />$ lscp <br /> CNO DATE TIME MODE FLG NBLKINC ICNT<br /> 7 2009-05-01 01:08:09 ss - 12 6<br /> 13 2009-05-01 19:05:34 cp i 8 3<br /> 14 2009-05-01 19:05:59 cp i 8 3<br /> 15 2009-05-01 19:07:09 ss - 12 6<br /> 16 2009-05-01 19:08:59 cp i 8 6<br /><br /># our post snapshot file<br />$ touch 4<br /></pre></div><br />Now lets go back in time into our snapshot, NILFS enables us to mount old snapshots as read only FS (while the original FS is still mounted):<br /><div class="gray"><pre name="code" class="bash"><br />$ sudo mkdir /media/nilfs-snapshot<br />$ sudo mount.nilfs2 -r /dev/loop0 /media/nilfs-snapshot/ -o cp=15 # only snapshots works!<br />$ cd /media/nilfs-snapshot<br /># as we might expect<br />$ ls <br /> 1 2 3 <br /></pre></div><br />NILFS has some interesting features, its not production ready yet however it sure worth looking after its development.ronenhttp://www.blogger.com/profile/13360463320878175457noreply@blogger.com0tag:blogger.com,1999:blog-3915544030735587425.post-65344053330582017942009-03-06T07:30:00.000-08:002009-03-06T08:14:43.944-08:00MetaClasses can bite!Groovy has MOP classes built in like the MetaClass class, this class enables (among other things) objects introspection, we could for example use its getProperties() method in order to get the list of all the meta properties of an object and copy their values into another object:<br /><div class='gray'><pre name="code" class="java"><br />class ParentModel {<br /> def String parentProp<br /><br /> /**<br /> * Copying the current object properties into the other object<br /> */<br /> def copyInto(other){<br /> this.metaClass.getProperties().findAll{it.getSetter()!=null}.each{metaProp-><br /> if(metaProp.getProperty(this)!=null){<br /> metaProp.setProperty(other,metaProp.getProperty(this))<br /> }<br /> }<br /> other<br /> }<br />}</pre></div><br />The usage is quite simple:<br /><div class='gray'><pre name="code" class="java"><br /> def parent = new ParentModel(parentProp:"parent")<br /> def copiedParent = parent.copyInto(new ParentModel())<br /> assert copiedParent.parentProp.equals(parent.parentProp)<br /></pre></div><br />While this code runs perfectly fine with object that have identical classes it has some unexpected side effects when one of the classes derives from another:<br /><div class='gray'><pre name="code" class="java"><br />class DerivingModel extends ParentModel{<br /> def derivedProp<br />}<br /><br />def parent = new ParentModel(parentProp:"parent")<br />def derived = new DerivingModel(derivedProp:"derived")<br />def copiedDerived = parent.copyInto(derived)<br />assert copiedDerived.parentProp.equals(parent.parentProp)<br />assert copiedDerived.derivedProp.equals("derived")// throws groovy.lang.MissingPropertyException:<br /> // No such property: derived<br /></pre></div><br />How can this be? the DerivingModel class has the derivedProp but after the copyInto invocation its missing!<br />Lets see what the getProperties method actually returns:<br /><div class='gray'><pre name="code" class="java"><br />def parent = new ParentModel(parentProp:"parent")<br />parent.metaClass.getProperties().each{println it.name}// prints: class, parentProp, metaClass<br /></pre></div><br />It seems that we don't only get the parentProp that we defined but also the metaClass and class properties, this means that in the derived case the copyInto method has set the metaClass and class values of ParentModel into the DerivedModel instance (causing it to lose access to its derivedProp).<br />The fix is quite simple:<br /><div class='gray'><pre name="code" class="java"><br />class ParentModel {<br /> def String parentProp<br /> def excludes = ['metaClass']<br /> def copyInto(other){<br /> this.metaClass.getProperties().findAll{it.getSetter()!=null}.each{metaProp-><br /> // we must not set the metaClass of the current object into the other<br /> if(metaProp.getProperty(this)!=null && !excludes.contains(metaProp.name)){<br /> metaProp.setProperty(other,metaProp.getProperty(this))<br /> }<br /> }<br /> other<br /> }<br />}<br /></pre></div><br />There is no need to exclude the class property since it keeps the original even if set.ronenhttp://www.blogger.com/profile/13360463320878175457noreply@blogger.com0tag:blogger.com,1999:blog-3915544030735587425.post-33947236489115580892009-03-01T14:41:00.000-08:002009-03-01T14:43:35.803-08:00Clojure on youtubeIv really enjoyed watching the Intro to Clojure series:<br /><br /><object width="480" height="295"><param name="movie" value="http://www.youtube.com/v/Aoeav_T1ARU&hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/Aoeav_T1ARU&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="295"></embed></object><br /><br />If your interested what the fuss is about check it out!ronenhttp://www.blogger.com/profile/13360463320878175457noreply@blogger.com0tag:blogger.com,1999:blog-3915544030735587425.post-46704225642757107732009-02-28T11:24:00.000-08:002009-02-28T13:29:26.829-08:00GroovyShell bindings validationGroovy 1.6 got released not long a go with a <a href='http://www.infoq.com/articles/groovy-1-6'>load of new features</a>, one of these is AST transformations which basically lets developers manipulate/access Groovy's AST before it gets loaded into the JVM.<br />This feature enables some really cool MOP options to mind however iv decided to try it in solving a non MOP-ish issue.<br /> <br />The <a href='http://groovy.codehaus.org/api/groovy/lang/GroovyShell.html'>GroovyShell</a> is a very versatile and useful tool that enables us to evaluate any Groovy script file at runtime:<div class='gray'><pre name="code" class="java"><br />def bindings = [lastDay:2]<br />def script = """<br /> import java.util.Calendar<br /> Calendar cal = Calendar.instance<br /> cal.set(2009,Calendar.FEBRUARY,2)<br /> def ghday = cal.time<br /> cal.set(2009,Calendar.MARCH,lastDay)<br /> def spring = cal.time<br /> def days = (ghday..spring).size()<br /> println days<br /> """<br />def shell = new GroovyShell(new Binding(bindings))<br />shell.evaluate(script)</pre></div><br />The script get its input parameters from the bindings hash, forgeting to pass an input variable (lastDay in this case) will cause a groovy.lang.MissingPropertyException to be thrown.<br /><br />This is quite reasonable during development time but not in other scenarios in which the script is written in one machine & evaluated on a remote machine.<br />The exception gets thrown only post its evaluation which might be too late (deep in the execution flow), wouldn't it be nice if it was possible to validate this at will on the client side?<br /><br />We could scan the script for suspect variables that might not have been initialised, such scanning might be possible by inspecting the script AST, looking after variables that weren't declared in the current script, Groovy code visitors to the rescue! <br /><br />The following implementation matches the bill perfectly:<div class='gray'><pre name="code" class="java"><br />package com.jdftm.script.valid<br />import org.codehaus.groovy.ast.ClassCodeVisitorSupport<br />import org.codehaus.groovy.ast.expr.MethodCallExpression<br />import org.codehaus.groovy.control.SourceUnit<br />import org.codehaus.groovy.ast.expr.VariableExpression<br />import org.codehaus.groovy.ast.expr.DeclarationExpression<br /><br />class ClassCodeVisitorSupportImp extends ClassCodeVisitorSupport {<br /><br /> def declared = []<br /><br /> def existsByDefault=['context','args']<br /><br /> def bindings<br /><br /> def notInBindings = {name -> bindings?.keySet().find{it.equals(name)} == null}<br /><br /> def notDeclared = {name -> declared?.find{it.text.equals(name)} == null && !existsByDefault.contains(name)}<br /><br /> def notValid = {notDeclared(it.text) && !it.hasInitialExpression() && notInBindings(it.text)}<br /><br /> def suspectVariables = []<br /><br /> public void visitMethodCallExpression(MethodCallExpression methodCall) {<br /> def variables=methodCall.arguments.expressions.findAll{(it instanceof VariableExpression)}<br /> suspectVariables << variables.findAll{notValid(it)}<br /> }<br /> <br /> public void visitDeclarationExpression(final DeclarationExpression decleration){<br /> declared << decleration.variableExpression<br /> }<br /><br /> protected SourceUnit getSourceUnit() {<br /> return null;<br /> }<br />}</pre></div><br />This visitor keeps a suspects list of all the variables that are either not in the declared variables or in the bindings hash.<br />The following class encapsulates the visitor usage:<div class='gray'><pre name="code" class="java"><br />package com.jdftm.script.valid<br />import org.codehaus.groovy.ast.ClassCodeVisitorSupport<br />import org.codehaus.groovy.ast.ModuleNode<br />import org.codehaus.groovy.control.SourceUnit<br />import org.codehaus.groovy.control.CompilationUnit<br />import org.codehaus.groovy.ast.ClassNode<br />import org.codehaus.groovy.control.Phases;<br /><br />class GroovyScriptValidator {<br /><br /> def validate(script,bindings){<br /> def ast=getAST(script)<br /> def impl=new ClassCodeVisitorSupportImp()<br /> impl.bindings=bindings<br /> impl.visitClass((ClassNode)ast.getClasses().get(0));<br /> impl.suspectVariables.flatten()<br /> }<br /><br /> def ModuleNode getAST(String source) {<br /> SourceUnit unit = SourceUnit.create("Test",source);<br /> CompilationUnit compUnit = new CompilationUnit();<br /> compUnit.addSource(unit);<br /> compUnit.compile(Phases.SEMANTIC_ANALYSIS);<br /> return unit.getAST();<br /> }<br />}</pre></div><br />Validating the script is now simple:<div class='gray'><pre name="code" class="java"> <br />package com.jdftm.script.valid<br /><br />/**<br /> *<br /> * @author ronen<br /> */<br />class InParamValidationTest {<br /><br /> public static void main(String[] args) {<br /> def bindings = [lastDay:2]<br /> def script = """<br /> import java.util.Calendar<br /><br /> Calendar cal = Calendar.instance<br /> cal.set(2009,Calendar.FEBRUARY,2)<br /> def ghday = cal.time<br /> cal.set(2009,Calendar.MARCH,lastDay)<br /> def spring = cal.time<br /> def days = (ghday..spring).size()<br /> println days<br /> """<br /> def validator = new GroovyScriptValidator()<br /> def suspects = validator.validate(script,bindings)<br /> suspects.each{println it.text}<br /> if(suspects.size()==0){<br /> def shell = new GroovyShell(new Binding(bindings))<br /> shell.evaluate(script)<br /> }<br /> }<br />}</pre></div><br />AST introspection is one cool feature to have!ronenhttp://www.blogger.com/profile/13360463320878175457noreply@blogger.com0tag:blogger.com,1999:blog-3915544030735587425.post-85820429401491356402009-01-19T14:16:00.000-08:002009-01-19T14:46:53.937-08:00Injecting Closures with Groovy BeanBuilderProgrammatic Spring configuration has always appealed to me (can't wait for Spring JavaConfig to come out), the clarity and ability to cut down repetitive configuration meta data is the way to go.<br /><br />Groovy eco system has got a lot of builders to configure any thing from build to you'v guessed it right Spring beans.<br />The BeanBuilder is a Groovy builder (google the pattern) class that enables us to define Spring beans in pure Groovy code, for example:<br /><div class='gray'><pre name="code" class="java"><br />class AnyPojo {<br /> def c<br />}<br /><br />def builder=new BeanBuilder()<br />def value="yummy"<br />builder.anyPojo(AnyPojo){<br /> c=value<br />}<br />def context = builder.createApplicationContext()<br />assert context.getBean("anyPojo").c.equals("yummy")<br /></pre></div><br />Note that an external value is injected into the bean (its not a spring bean), this might useful in cases that we want to pass behavior into our Spring beans like so:<br /><div class='gray'><pre name="code" class="java"><br />def builder=new BeanBuilder()<br />def value={"yummy"}// returns "yummy"<br />builder.anyPojo(AnyPojo){<br /> c=value<br />}<br />def context = builder.createApplicationContext()<br />assert context.getBean("anyPojo").c.call().equals("yummy")<br /></pre></div><br />This should work!, however upon running this code we get this exception:<br /><div class='gray'><pre name="code" class="java"><br />.. Error creating bean with name '(inner bean)': Instantiation of bean failed; nested exception is java.lang.IllegalStateException: No bean class specified on bean definition<br /></pre></div><br />The builder thinks that we are trying to created a nested inner bean:<br /><div class='gray'><pre name="code" class="java"><br />builder.anyPojo(AnyPojo){<br /> c={ SomePojo p-><br /> //..<br /> }<br />}<br /></pre></div><br />No matter what as soon as the builder gets a closure as value for a property it fails.<br />The best solution that iv found (without altering the BeanBuilder code) is to wrap the closure in a delegating class like so:<br /><div class='gray'><pre name="code" class="java"><br />class ClosureDelegate {<br /> def c<br /><br /> ClosureDelegate(c){<br /> this.c=c<br /> }<br /><br /> def call(){<br /> c.call()<br /> }<br />}<br /><br />def builder=new BeanBuilder()<br />def value=new ClosureDelegate({"yummy"})// the diff<br />builder.anyPojo(AnyPojo){<br /> c=value<br />}<br />def context = builder.createApplicationContext()<br />assert context.getBean("anyPojo").c.call().equals("yummy")// this passes as well<br /></pre></div><br />This way we avoid the call to inner bean builder method (=(Closure c)).<br />This solution is partial (sometimes closures are applied without a call the the call method), but than again it should do it for most cases (oh and BTW you can get BeanBuilder without Grails from <a href="http://dist.codehaus.org/grails/">spring spring jar</a>).ronenhttp://www.blogger.com/profile/13360463320878175457noreply@blogger.com2tag:blogger.com,1999:blog-3915544030735587425.post-33429948132568425392009-01-17T09:52:00.000-08:002009-01-17T13:00:07.263-08:00Demystifying Spring wiring processMany Java applications these days make use of Spring IoC, taking the initialization management from the hand of the developer has many benefits but also has a couple of down sides like the lose of some control on the wiring process itself.<br /><br />Most of the time its a none issue however there are times in which Spring fails to resolve a dependency and all that the developer is left with is a cryptic stack trace to follow.<br /><br />Iv been thinking on how to make it possible to track down Spring weaving process and see at each stage what has been wired up, basically there are three approaches that iv considered:<br /><ul><br /> <li>The first is to hook into the injection process by some public API, iv decided to drop it since i didn't find any API which notifies me upon beans creation and wiring.</li><br /> <li>The second was to wire some Aspect into Spring injection process, iv started to read Spring source code and saw that pin point all the spots in code in which the wiring takes place is very tedious and error prone to start with.</li><br /> <li>The third option was to think on Spring as an isolated container that has to interact with the JVM in order to create and inject objects into each other, tracing this interaction sholud give us the log of the injection process itself!</li> <br /></ul><br />A little more digging (see org.springframework.beans.BeanUtils) revealed that Spring uses Java reflection API (java.lang.reflect.Constructor.newInstance, java.lang.reflect.Field.set) in order to build/wire beans, armed with this knowledge we are only left to devise a method for tracing the calls to these methods.<br /><br />A possible option is Btrace, Btrace is a Java agent modeled after DTrace which is capable of instrumenting running Java classes, using the following Btrace script would activate the tracing of the wiring process on all the classes under the com.jdftm package: <br /><div class='gray'><pre name="code" class="java"><br />package jdftm;<br /><br />import com.sun.btrace.annotations.*;<br />import com.sun.btrace.AnyType;<br />import static com.sun.btrace.BTraceUtils.*;<br />import java.lang.reflect.Constructor;<br />import java.lang.reflect.Method;<br />import java.lang.reflect.Field;<br /><br /><br />@BTrace public class ReflecTracer {<br /> @OnMethod(<br /> clazz="/java.lang.reflect.Constructor/",<br /> method="/newInstance/"<br /> )<br /> public static void anyNewInstance(Constructor con,Object[] args) {<br /> if(con!=null && matches("public\\scom\\.jdftm(\\.|\\w*)*\\(\\)",str(con))){<br /> println(strcat(strcat("Object ",str(con))," got constructed"));<br /> }<br /> }<br /><br /> @OnMethod(<br /> clazz="/java.lang.reflect.Field/",<br /> method="/set/"<br /> )<br /> public static void anyFieldSet(Field field,Object obj,Object value) {<br /> println(strcat("Set invoked on ",str(field)));<br /> }<br />}</pre></div><br /><br />Using the script with Btrace involve two steps, compilation:<br /><div class='gray'><pre name="code" class="bash">btracec ReflecTracer.java</pre></div><br /><br />Agent attaching (attach before context creation, debugging is an option):<br /><div class='gray'><pre name="code" class="bash">btrace <process id, use jps> jdftm/ReflecTracer.class</pre></div><br /><br />The following beans wiring:<br /><div class='gray'><pre name="code" class="java"><br />public class BeanA {<br /> @Autowired<br /> private BeanB b;<br />}<br /><br />public class BeanB {<br /> @Autowired<br /> private BeanA a;<br />}</pre></div> <br /><br />Produces the following traces:<br /><div class='gray'><pre name="code" class="bash"><br />Object public com.jdftm.spring.context.BeanA() got constructed<br />Object public com.jdftm.spring.context.BeanB() got constructed<br />Set invoked on private com.jdftm.spring.context.BeanA com.jdftm.spring.context.BeanB.a<br />Set invoked on private com.jdftm.spring.context.BeanB com.jdftm.spring.context.BeanA.b<br /></pre></div> <br />An interesting idea that i had is to create a graph out of these traces and give the developer even better visualization on the process.ronenhttp://www.blogger.com/profile/13360463320878175457noreply@blogger.com0tag:blogger.com,1999:blog-3915544030735587425.post-36946379360012990742009-01-10T13:19:00.000-08:002009-01-10T13:25:19.940-08:00Learning some HaskellWell iv been studying a little Haskell lately, mainly by reading <a href="http://learnyouahaskell.com/chapters">Learn You a Haskell for Great Good!</a>, I can only recommend any one to follow this book, my next read will be <a href="http://book.realworldhaskell.org/read/">Real world Haskell</a>.<br />Functional programing rulz!ronenhttp://www.blogger.com/profile/13360463320878175457noreply@blogger.com0tag:blogger.com,1999:blog-3915544030735587425.post-44215596560723312562008-12-25T14:08:00.000-08:002008-12-25T14:15:03.473-08:00Pure Java entertainmentIv really enjoyed this <a href="http://www.youtube.com/watch?v=wDN_EYUvUq0">presentation</a> about Java puzzlers.<br />The main moral of this presentation in my mind is that we should relay more on static tools in order to avoid such corner cases (there is no way to remember them all).<br />Take a look im sure that youl enjoy it as I did.ronenhttp://www.blogger.com/profile/13360463320878175457noreply@blogger.com0tag:blogger.com,1999:blog-3915544030735587425.post-1696746248702854442008-12-18T12:46:00.000-08:002008-12-18T13:12:00.610-08:00VMware recovery methodsIv been using VMware server and player for a time now and usually the hosted OS is XP, it happens to be that iv had the "luck" to witness the crash/corruption of such images and have devised two nifty tricks/methods of data recovery that i think worth sharing.<br />The first is for data recovery for an unbootable image, it matches cases in which you don't seem to be able to boot XP up but the image itself is readable & loaded by VMware (you see the black screen loading), the basic idea is to change the first boot device of the image to a Linux live cd (Ubuntu works perfectly), after booting up all you need to do is to mount the NTFS folder and copy it out (by scp, thumb drive, etc..).<br />The second one is more complex and comes to handle a case in which the image dose not load at all (vmware complains about a corrupted vmx file), in order to recover from this state there are a couple of prequisits:<ul><br /><li>VMware server installed.</li><br /><li>You have another working XP image with a vmx file.</li><br /><li>The corrupted image has a snapshot of a working state</li><br /></ul><br />The solution in this case is to copy the working vmx file into the folder of the corrupted image, load this image in VMware server and replace all the hard drive entries with the corrupted machine images, now all that is done is to revert to the last saved snapshot and see how the system is restored!<br />I hope that these two little methods help you as much as they helped me.ronenhttp://www.blogger.com/profile/13360463320878175457noreply@blogger.com0tag:blogger.com,1999:blog-3915544030735587425.post-32756739693377354552008-12-16T13:32:00.000-08:002008-12-16T14:08:15.378-08:00Java statefull callbacksAny programmer comes to know callbacks at some point or another, in Java it looks something like this:<br /><div class='gray'><pre name="code" class="java"><br />public interface Callback {<br /> void doCall();<br />}<br /><br />public class CallbackCosumer {<br /> public void execute(final Callback callback){<br /> callback.doCall();<br /> }<br />}<br /><br />// usage<br />public class Main {<br /> public static void main(String[] args) {<br /> final CallbackConsumer consumer = new CallbackConsumer();<br /> consumer.execute(new Callback() {<br /> public void doCall() {<br /> System.out.println("doing my callback thingy");<br /> }<br /> });<br /> }<br />}</pre></div><br />The biggest downside is that its hard to pass calling context state into the rigid callback interface, we could try something like:<br /><div class='gray'><pre name="code" class="java"><br />public class CustomCallback <T> implements Callback {<br /><br /> private <T> state;<br /><br /> public void doCall() {<br /> System.out.println(state);<br /> }<br /><br /> public void setState(<T> state) {<br /> this.state = state;<br /> }<br />}</pre></div><br />Note that this implementation is limiting, the doCall method has to work for any type T, custom behavior will require sub classing (not reasonable expectation from the callback provider). <br />A somewhat better (the most elegant that iv found to date) solution is to take advantage of another interface:<br /><div class='gray'><pre name="code" class="java"><br />public interface StatefullCallback<T> extends Callback{<br /> void addState(T state);<br />}<br /><br />// Now we have a custom state object<br />public static class CustomState {<br /> // fields .. <br />}<br /><br />// And usage with a type matching logic<br />public static void main(String[] args) {<br /> final CallbackConsumer consumer = new CallbackConsumer();<br /> final StatefullCallback<CustomState> callback=new StatefullCallback<CustomState>() {<br /> private CustomState state;<br /><br /> public void addState(final CustomState state) {<br /> this.state = state;<br /> }<br /><br /> public void doCall() {<br /> // some custom logic that uses the custom state object<br /> }<br /> };<br /> callback.addState(new CustomState()); <br /> consumer.execute(callback);<br />}</pre></div><br />Its quite easy to see how its possible to pass multiple types of state objects into the callback execution context and do it with relative ease, closure-blessed languages require no such hacking.ronenhttp://www.blogger.com/profile/13360463320878175457noreply@blogger.com0tag:blogger.com,1999:blog-3915544030735587425.post-16512397164747708452008-11-21T13:39:00.000-08:002008-11-21T14:45:22.585-08:00Keeping your Zen with LinuxCreative mp3 players seemed to be a reasonable choice in the early IPod mania days, the single main problem that iv had for years with my trusty Nomad Zen Xtra is the fact that there was no Linux interoperability what so ever, the only (somewhat shaky) solution was to wait for <a href='http://gnomad2.sourceforge.net/'>Gnomad</a> to mature.<br />Things has changed and the Zen access has worked with Gnomad, but two major issues remained:<br /><ul><li>No automation possible (like latest podcast copying with a matching playlist generated).</li><br /> <li>Ugly and limiting UI to deal with.</li> </ul><br /><br />After a bit digging iv found <a href='http://www.adebenham.com/mtpfs/'>mtpfs</a> which is a FUSE file system that can mount MTP devices, installation and usage are simple as:<div class='gray'><pre name="code" class="java"><br />$ sudo aptitude install mtpfs<br />$ sudo mkdir /media/zen<br />$ sudo mtpfs -o allow_other /media/zen/ # allowing other enables non root access to zen folders<br />$ ls /media/zen<br /> Music My Playlists Playlists WMPInfo.xml<br /></div></pre><br />The Music folder holds all the mp3 files in a flat structure and the Playlists folder hold m3u files in the following format (the player root is /):<br /><div class='gray'><pre name="code" class="java"><br />/Music/Outlaws64.mp3<br />/Music/uupc_s01e18_high.mp3<br />/Music/JavaPosse217.mp3<br />/Music/seradio-episode117-branSelicOnUML.mp3<br />/Music/CyberSpeak_98_Nov_16_2008.mp3<br /></div></pre><br />Its quite easy to see how to automate the podcast download and copying combined with <a href='http://podget.sourceforge.net/'>podget</a> utility, my Zen has been restored :)ronenhttp://www.blogger.com/profile/13360463320878175457noreply@blogger.com0tag:blogger.com,1999:blog-3915544030735587425.post-41437069312493280162008-11-13T11:02:00.000-08:002008-11-13T12:03:34.760-08:00Objectifying conditionalsIm sure that any programmer has come across a code snippet which included a long list of nested conditionals, like follows:<br /><div class='gray'><pre name="code" class="java"><br />public class NaiveImpl {<br /> public void process(final String option) {// mapping a type code to behaviour<br /> if (option.equals("first")) {<br /> // first option .. <br /> } else if (option.equals("second")) {<br /> // second option code ..<br /> }//.. a ton load of other conditionals<br /> }<br />}<br /></pre></div><br />Basically conditionals map between state (option) and behavior (a legacy which is carried from the procedural programming days), multiple conditionals are problematic:<br /><ul><br /> <li>They include multiple navigation paths in single condensed code sections.</li><br /> <li>They have a large number of inter dependencies between them (makes changes hard).</li><br /> <li>They are not objects (statements in Java, we cant access them in runtime, they are not "first class citizens").</li><br /></ul><br /><br />One of my favorite ways of handling type code to behavior mapping without the resort to conditionals is binding Enum values to behavior:<br /><br /><div class='gray'><pre name="code" class="java"><br /> public class CleanImpl {<br /><br /> private interface Handler {<br /> void handle();<br /> }<br /> private static Handler firstOptionHandler = new Handler() {<br /> public void handle() {<br /> // first option code<br /> }<br /> };<br /> private static Handler secondOptionHandler = new Handler() {<br /> public void handle() {<br /> // first option code<br /> }<br /> };<br /><br /> private enum Option {<br /><br /> First("first", firstOptionHandler),<br /> Second("second", secondOptionHandler);// more options to come ..<br /> private final String name;<br /> private final Handler handler;<br /><br /> private Option(final String name, final Handler handler) {<br /> this.name = name;<br /> this.handler = handler;<br /> }<br /><br /> private static Option fromString(final String optionString) {<br /> for (Option option : values()) {<br /> if (option.name.equals(optionString)) {<br /> return option;<br /> }<br /> }<br /> throw new RuntimeException("no matching option found");<br /> }<br /> }<br /><br /> public void process(final String option){<br /> Option.fromString(option).handler.handle();<br /> }<br />}<br /></pre></div><br />This code seem to be more verbose at first glance but its more than reasonable to split the handler interface and implementations into separate files (all in one file enables minimal visibility of members and getter-less code), its easy to see how all the above downsides are answered:<br /><ul><br /> <li>No multiple navigation paths in single condensed code section (each handler is seperated).</li><br /> <li>No inter dependencies between different options handling.</li><br /> <li>All round objects.</li><br /></ul><br />Hopefully will see more usage of similar patterns and enjoy an if-less world!ronenhttp://www.blogger.com/profile/13360463320878175457noreply@blogger.com0tag:blogger.com,1999:blog-3915544030735587425.post-34639813536512454832008-10-24T07:05:00.000-07:002008-11-01T11:52:01.912-07:00The spreading Java and Ubunut loveThese days it seems that the Java community is more and more Ubuntu friendly, the integration of Java and Linux (Ubuntu in particular) has been steadily improving making it easy to install (with a bit <a href="http://java.randgestalten.de/?p=31">tinkering</a>) Java 6 update 10, Netbeans and other Java goodies.<br />The Linux and Java open spirit are starting to merge, these are good times to be a Java developer on Linux systems.<br /><br />Note:<br />It seems as if in Ubuntu 8.10 running sudo apt-get install sun-java6-jdk installs 6 update 10 by default.ronenhttp://www.blogger.com/profile/13360463320878175457noreply@blogger.com0tag:blogger.com,1999:blog-3915544030735587425.post-57583297753282559522008-10-20T06:23:00.000-07:002008-10-20T07:10:48.623-07:00Oracle Cursor and SimpleJdbcCallThe title does sound innocent enough, calling a store procedure by using Spring SimpleJdbcCall should be simple and well <a href="http://static.springframework.org/spring/docs/2.5.x/reference/jdbc.html#jdbc-simple-jdbc-call-1">documented</a>, in usual circumstances this is the case however when Oracle Cursor is involved all hell brakes loose.<br /><br />An example for such a procedure:<br /><div class='gray'><pre name="code" class="sql"><br />CREATE PROCEDURE GET_COUNTRIES_BY_INDEPENDECE (cursor OUT types.ref_cursor , date NUMBER) AS <br />BEGIN <br /> OPEN cursor FOR select * from COUNRTY where INDEPENDENCE >= date;<br />END;<br /><br />-- note that the ref_cursor type has to be declared in a package<br /><br />CREATE OR REPLACE PACKAGE types<br />AS<br /> TYPE ref_cursor IS REF CURSOR;<br />END;<br /></pre></div><br /><br />The first problem starts with the fact that the Oracle driver doesn't provide the metadata that Spring requires, this means that the programmer has to define all the in and out parameters by himself and that the metadata depended functionality of Spring has to be disabled (failing to do so make Spring ignore in/out parameter decelerations, verified by Spring source code debugging).<br /><br />The second problem is how to make Spring work with the result set that the procedure provides via the cursor, i didn't find any mentioning of this on the web (besides some <a href="http://forum.springframework.org/showthread.php?t=59328">forum entries</a> that didn't show a clear solution path), one tutorial that did help was <a href="http://www.enterprisedt.com/publications/oracle/result_set.html">jdbc</a> related.<br /><br />After a couple of attempts and Spring source code reading iv managed to find a winning solution: <br /><div class='gray'><pre name="code" class="java"><br /> ParameterizedRowMapper<Map> mapper = new ParameterizedRowMapper<Map>() {<br /> @Override<br /> public Map mapRow(ResultSet rs, int rowNum) throws SQLException {<br /> BasicRowProcessor processor = new BasicRowProcessor();// commons dbutils <br /> return processor.toMap(rs);<br /> }<br /> };<br /><br /> <br /> final Map in = new HashMap();<br /> in.put(inParam, value);<br /> JdbcTemplate template = new JdbcTemplate(dataSource);<br /> SimpleJdbcCall jdbcCall = new SimpleJdbcCall(template).withProcedureName("GET_COUNTRIES_BY_INDEPENDECE").withCatalogName("CATALOG");<br /><br /> // taking care of the cursor result set with a custom mapper<br /> jdbcCall.returningResultSet("cursor", mapper);<br /><br /> // disabling metadata so that Spring won't reject parameter declaration<br /> // this is due to the lacking oracle jdbc driver <br /> jdbcCall.withoutProcedureColumnMetaDataAccess();<br /><br /> // order matters! spring uses them according to the position in the collection <br /> jdbcCall.addDeclaredParameter(new SqlOutParameter("cursor",OracleTypes.CURSOR));<br /> jdbcCall.addDeclaredParameter(new SqlParameter(someDateInMili,OracleTypes.NUMERIC));<br /><br /> List<Map<String, Object>> result = (List<Map<String, Object>>) jdbcCall.execute(in).get("cursor");// getting back the result set that was provided by the cursor<br /><br /></pre></div><br /><br />There are a couple of weird things in this code, first we must declare not only that the call returns a result set but also an out parameter for the cursor, second the order of the deceleration matters! (which makes sense since Spring can't guess the placement of the parameter without metadata).<br />Thats about it, hopefully iv saved you some time ;)ronenhttp://www.blogger.com/profile/13360463320878175457noreply@blogger.com0tag:blogger.com,1999:blog-3915544030735587425.post-39013439128490178542008-10-17T08:31:00.000-07:002008-10-17T08:39:09.120-07:00Gookup 0.0.3 is outFor those of you who don't know Gookup is a backup utility for three Google online main services (Gmail Blogger and Reader), the basic idea is taking back control on your data and back it up.<br />Its true that Google has some strong back up procedures however even they can't protect you 100%.<br /><br />Iv been using it now for a while to back up all my online content on Google servers and its been quite a useful tool, taking back the control on your own data is a liberating experience. <br /><br />See the release notes and download link <a href="http://code.google.com/p/gookup/">here</a>.ronenhttp://www.blogger.com/profile/13360463320878175457noreply@blogger.com0tag:blogger.com,1999:blog-3915544030735587425.post-46519412516956088292008-10-03T09:52:00.000-07:002008-10-03T11:56:22.316-07:00Closjure it not a spelling mistac ;)Its seems that these days any programmer has to have a triple set of languages in his tool set, the first one is the static imperative which brings on the food to table (Java or C#), the second one is the dynamic imperative one which is fun and productive to use, it saves the ceremony code (let it be Ruby Python or Groovy) and is useful in configuration code, tests and fast prototypes projects.<br />As for the third type the magic keyword is <span style="font-weight:bold;">functional</span>, learning such a language won't make you code faster or more productive (not from day one at least) instead it will make you smarter and could improve the way in which you solve programing problems (functions all the way baby!!).<br />The main question here is which one to pick from (Scala, Haskell, ML etc..), i won't go deep into which one you should choose but instead propose a surprising contender called <a href="http://clojure.org/">Clojure</a> (a lisp dialect that runs on the JVM), some of the things that appealed to me from the start about Clojure were:<br /><ul><li>Dynamic typing</li><br /><li>Complete Immutability (has STM and persistent collections) no hidden side effects </li><br /><li>REPL</li><br /><li>Macros</li><br /><li>Java interop</li></ul><br />Iv made a bold attempt to write a small clj program which emulates svn blame functionality, the implementation is a trimmed version of an existing <a href="https://wiki.svnkit.com/Annotating%20a%20file">svnkit snippet</a>:<br /><div class='gray'><pre name="code" class="java"><br />import java.io.File;<br />import java.util.Date;<br />import org.tmatesoft.svn.core.SVNException;<br />import org.tmatesoft.svn.core.SVNURL;<br />import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;<br />import org.tmatesoft.svn.core.internal.util.SVNFormatUtil;<br />import org.tmatesoft.svn.core.wc.ISVNAnnotateHandler;<br />import org.tmatesoft.svn.core.wc.SVNClientManager;<br />import org.tmatesoft.svn.core.wc.SVNLogClient;<br />import org.tmatesoft.svn.core.wc.SVNRevision;<br /><br />public class Annotations {<br /><br /> public static void main(String[] args) {<br /><br /> DAVRepositoryFactory.setup();<br /><br /> try {<br /> SVNURL fileURL = SVNURL.parseURIEncoded("http://gookup.googlecode.com/svn/trunk/gookup-jruby/build/artifacts.rb");<br /> SVNLogClient logClient = SVNClientManager.newInstance().getLogClient();//SVNLogClient is the class with which you can perform annotations <br /> boolean ignoreMimeType = false;<br /> boolean includeMergedRevisions = false;<br /> logClient.doAnnotate(fileURL, SVNRevision.UNDEFINED, SVNRevision.create(1), SVNRevision.HEAD,<br /> ignoreMimeType /*not ignoring mime type*/, includeMergedRevisions /*not including merged revisions */,<br /> new AnnotationHandler(), null);<br /> } catch (SVNException svne) {<br /> System.out.println(svne.getMessage());<br /> System.exit(1);<br /> }<br /> }<br /><br /> private static class AnnotationHandler implements ISVNAnnotateHandler {<br /><br /> /**<br /> * Deprecated.<br /> */<br /> public void handleLine(Date date, long revision, String author, String line) throws SVNException {<br /> handleLine(date, revision, author, line, null, -1, null, null, 0);<br /> }<br /><br /> /**<br /> * Formats per line information and prints it out to the console.<br /> */<br /> public void handleLine(Date date, long revision, String author, String line, Date mergedDate,<br /> long mergedRevision, String mergedAuthor, String mergedPath, int lineNumber) throws SVNException {<br /> String revStr = revision >= 0 ? SVNFormatUtil.formatString(Long.toString(revision), 6, false) : " -";<br /> String authorStr = author != null ? SVNFormatUtil.formatString(author, 10, false) : " -";<br /> System.out.println(revStr + " " + authorStr + " " + line);<br /><br /> }<br /><br /> public boolean handleRevision(Date date, long revision, String author, File contents) throws SVNException {<br /> // We do not want our file to be annotated for each revision of the range, but only for the last <br /> // revision of it, so we return false <br /> return false;<br /> }<br /><br /> public void handleEOF() {<br /> }<br /> }<br />}</pre></div><br /><div class='gray'><pre name="code" class="java"><br />The Clojure implementation:<br />(in-ns 'main)<br />(clojure/refer 'clojure)<br />(import '(org.tmatesoft.svn.core SVNException SVNURL)<br /> '(org.tmatesoft.svn.core.wc ISVNAnnotateHandler SVNClientManager SVNLogClient SVNRevision)<br /> '(org.tmatesoft.svn.core.internal.util SVNDate SVNFormatUtil)<br /> '(org.tmatesoft.svn.core.internal.io.dav DAVRepositoryFactory))<br /><br />(def url "http://gookup.googlecode.com/svn/trunk/gookup-jruby/build/artifacts.rb")<br /><br />(def format (fn [notEmpty spacing value] (if notEmpty (SVNFormatUtil/formatString (str value) (long spacing) false) " -")))<br /><br />(def handler (proxy [ISVNAnnotateHandler] []<br /> (handleLine [date revision author line] ())<br /> (handleLine [date revision author line mergedDate mergedRevision mergedAuthor mergedPath lineNumber] <br /> (println (format (>= revision 0) 6 revision)(format (not (nil? author)) 10 author) line))<br /> (handleRevision [date revision author contents] false)<br /> (handleEOF [] ())))<br /><br />(defn main [args]<br /> (DAVRepositoryFactory/setup)<br /> (let [fileURL (. SVNURL parseURIEncoded url) <br /> logClient (.. SVNClientManager (newInstance) (getLogClient))<br /> revision (SVNRevision/create (long 1))]<br /> (. logClient doAnnotate fileURL SVNRevision/UNDEFINED revision SVNRevision/HEAD false false handler nil))<br />)</pre></div><br />The Clojure implementation is less verbose and demonstrates nicely the how well Java is integrated into the language (note the proxy method that implements the ISVNAnnotateHandler interface), the ".." macro is another nice feature that makes method calls on Java object feel more natural.<br />Clojure has also function objects (closures), the format closure saves yet more duplication in the handleLine method.<br />The ugly thing which is common to both implementation is the huge parameters list of svnkit (what were they thinking?).ronenhttp://www.blogger.com/profile/13360463320878175457noreply@blogger.com0tag:blogger.com,1999:blog-3915544030735587425.post-32713108161559343862008-09-27T14:08:00.002-07:002008-09-28T13:00:43.217-07:00Custom findbugs detectors and mavenIv been writing a custom find bugs detector during the weekend, the bug that this detector has to detect is String.getBytes() usages, default system encoding is used when converting the char sequence into bytes which can make it work on one machine and fail on another (use String.getBytes(charsetName) instead).<br />The writing of the detector was not straight forward but im not going to focus on this issue (see <a href="http://www.ibm.com/developerworks/library/j-findbug2/">this</a> and <a href="http://dschneller.blogspot.com/2008/04/localegetdefault-findbugs-detector.html">this</a>), instead id like to focus on how to create a findbugs plugin by using maven and running it with maven findbugs plugin.<br />First here is the detector code:<br /><div class='gray'><pre name="code" class="java"><br />package com.jdftm;<br /><br />import java.text.DateFormat;<br />import java.util.Calendar;<br /><br />import org.apache.bcel.generic.ObjectType;<br /><br />import edu.umd.cs.findbugs.BugInstance;<br />import edu.umd.cs.findbugs.BugReporter;<br />import edu.umd.cs.findbugs.ba.*;<br />import edu.umd.cs.findbugs.bcel.OpcodeStackDetector;<br /><br />public class StringGetBytesDetector extends OpcodeStackDetector {<br /><br /> private BugReporter reporter;<br /> private final ObjectType stringType = ObjectTypeFactory.getInstance("java.lang.String");<br /> private final static String tBugType = "SGB_STRING_GET_BYTES";<br /><br /> public StringGetBytesDetector(BugReporter aReporter) {<br /> reporter = aReporter;<br /> new String("").getBytes();<br /> }<br /><br /> @Override<br /> public void sawOpcode(int seen) {<br /> if (seen != INVOKEVIRTUAL) {// we are only interested in method calls<br /> return;<br /> }<br /><br /> try {<br /> ObjectType tType = ObjectTypeFactory.getInstance(getClassConstantOperand());<br /> if (!tType.subclassOf(stringType) || <br /> !getClassConstantOperand().equals("java/lang/String") || <br /> !getNameConstantOperand().equals("getBytes")) {<br /> return;<br /> }<br /><br /> reporter.reportBug(new BugInstance(this,tBugType, NORMAL_PRIORITY).addClassAndMethod(this).addCalledMethod(this).addSourceLine(this));<br /> } catch (ClassNotFoundException e) {<br /> AnalysisContext.reportMissingClass(e);<br /> }<br /> }<br />}<br /></pre></div><br />This class should reside in the src/main/java path of your maven module, findbugs requires another two files to be present in the plugin jar, findbugs.xml (contains bugs and detectors meta data):<br /><div class='gray'><pre name="code" class="xml"><br /><FindbugsPlugin><br /><Detector class="com.jdftm.StringGetBytesDetector" speed="fast"/><br /><BugPattern abbrev="SGB" type="SGB_STRING_GET_BYTES" category="CORRECTNESS"/><br /></FindbugsPlugin><br /></pre></div><br />And messages.xml (contains bug messages and detector description):<br /><div class='gray'><pre name="code" class="xml"><br /><MessageCollection><br /> <Detector class="com.jdftm.StringGetBytesDetector"><br /> <Details><br /> <p>This detector warns about String.getBytes uages.</p><br /> </Details><br /> </Detector><br /> <BugPattern type="SGB_STRING_GET_BYTES"><br /> <ShortDescription>Call getBytes on String instance</ShortDescription><br /> <LongDescription>Call getBytes on String instance</LongDescription><br /> <Details>Using String.getBytes is bad!</Details><br /> </BugPattern><br /></MessageCollection><br /></pre></div><br />Both files should reside in the src/main/resources path, the plugin also has the following dependencies:<br /><div class='gray'><pre class='xml' name='code'><br /><dependency><br /> <groupId>findbugs</groupId><br /> <artifactId>findbugs</artifactId><br /> <version>1.3.5</version><br /></dependency><br /><dependency><br /> <groupId>org.apache</groupId><br /> <artifactId>bcel</artifactId><br /> <version>5.2</version><br /></dependency><br /><dependency><br /> <groupId>asm</groupId><br /> <artifactId>asm</artifactId><br /> <version>3.1>/version><br /></dependency><br /><dependency><br /> <groupId>asm</groupId><br /> <artifactId>asm-tree</artifactId><br /> <version>3.</version><br /></dependency><br /></pre></div><br />The easiest way of getting them is by downloading findbugs distribution and deploying them from the lib folder into your favorite maven proxy (artifactory in my case).<br />All that is left is to deploy the plugin and to add it to your maven findbugs plugin configuration:<br /><div class='gray'><pre class='xml' name='code'><br /><reporting><br /> <plugins><br /> <plugin><br /> <groupId>org.codehaus.mojo</groupId><br /> <artifactId>findbugs-maven-plugin</artifactId><br /> <version>2.0</version><br /> <configuration><br /> <effort>Max</effort><br /> <threshold>Low</threshold><br /> <xmlOutput>true</xmlOutput><br /> <debug>true</debug><br /> <pluginList>{artifact_path}/findstringtobyte-1.0.jar</pluginList><br /> </configuration><br /> </plugin><br /> </plugins><br /></reporting><br /></pre></div><br />Thats about all :)<br /><br />* A small note:<br /> The findbugs maven plugin has a <a href="http://jira.codehaus.org/browse/MFINDBUGS-54">bug in the 1.2.0 release</a> that was fixed for the 1.2.1 & 2.0 snapshot versions, it prevent the use of custom detector which means that youll need to use one of the snapshots versions.ronenhttp://www.blogger.com/profile/13360463320878175457noreply@blogger.com0tag:blogger.com,1999:blog-3915544030735587425.post-75909367925784992582008-08-30T08:11:00.000-07:002008-09-13T11:14:12.131-07:00AMF serialization from Java to Flex and backThere are some scenarios in which you want to pass objects to and from a Flex application to a Java back end, if your using an Adobe framework (LCDS or BlazeDS) than you get this functionality out of the box however there are some cases that you wish to escape Adobe's grip and uses some third party technology.<br />Some solutions that may come to mind are JSon or XML, the problem with these solutions is that they may require a lot of bandwidth and even lots of computing power for complex objects graphs, <a href="http://en.wikipedia.org/wiki/Action_Message_Format">AMF</a> to the rescue.<br />AMF is a binary protocol which is used natively by the flash player, with the release of BlazeDS it was made accessible to any Java client that wishes to use it, in order to use AMF we need to serialize an object into bytes and pass it as the payload of any protocol that we choose, the easiest way to do so is to encode the resulting AMF bytes into BASE64 encoding (a format that transforms byte arrays into a readable string form) and append it to the existing payload.<br />Ill start with the Java side first: <br /><br /><div class='gray'><pre name="code" class="java"><br />import com.google.inject.Inject;<br />import flex.messaging.endpoints.BaseHTTPEndpoint;<br />import flex.messaging.io.SerializationContext;<br />import flex.messaging.io.amf.Amf3Input;<br />import flex.messaging.io.amf.Amf3Output;<br />import java.io.ByteArrayInputStream;<br />import java.io.ByteArrayOutputStream;<br />import java.io.IOException;<br />import java.io.InputStream;<br />import sun.misc.BASE64Decoder;<br />import sun.misc.BASE64Encoder;<br /><br />/**<br /> *<br /> * @author ronen<br /> */<br />public class AmfSerializer {<br /><br /> @Inject<br /> private SerializationContext context;<br /><br /> public <T> String toAmf(final T source) throws IOException {<br /> final StringBuffer buffer = new StringBuffer();<br /> final ByteArrayOutputStream bout = new ByteArrayOutputStream();<br /> final Amf3Output amf3Output = new Amf3Output(context);<br /> amf3Output.setOutputStream(bout);<br /> amf3Output.writeObject(source);<br /> amf3Output.flush();<br /> amf3Output.close();<br /> final BASE64Encoder encoder = new BASE64Encoder();<br /> return encoder.encode(bout.toByteArray());<br /> }<br /><br /> public <T> T fromAmf(final String amf) throws ClassNotFoundException, IOException {<br /> final BASE64Decoder decoder = new BASE64Decoder();<br /> byte[] input = decoder.decodeBuffer(amf);<br /> InputStream bIn = new ByteArrayInputStream(input);<br /> Amf3Input amf3Input = new Amf3Input(context);<br /> amf3Input.setInputStream(bIn);<br /> return (T) amf3Input.readObject();<br /> }<br />}<br /></pre></div><br /><br />This code uses BlazeDS API (the messaging-core, messaging-common and messaging-remoting jars) in order to serialize an object of type T into AMF byte array the bytes are encoded to a Base64 string, encoding result of an instance of the following VO:<br /><br /><div class='gray'><pre name="code" class="java"><br />package com.jdftm.vo;<br /><br />import java.util.Date;<br /><br />public class CurrentDayVO {<br /><br /> private Date now;<br /><br /> public CurrentDayVO() {<br /> }<br /><br /> public void setNow(Date now) {<br /> this.now = now;<br /> }<br /><br /> public Date getNow() {<br /> return now;<br /> }<br />}<br /></pre></div><br /><br />might look something like ChMzY29tLmpkZnRtLnZvLkN1cnJlbnREYXlWTwdub3cIAUJrjUw54AAA.<br /><br />Now lets turn to the Flex side:<br /><br /><div class='gray'><pre name="code" class="java"><br />package com.jdftm.stomp.interop {<br /> import flash.utils.ByteArray;<br /> import mx.utils.Base64Encoder;<br /> import mx.utils.Base64Decoder;<br /> <br /> public class AMFSerializer {<br /> public function serializeToString(value:Object):String{<br /> if(value==null){<br /> throw new Error("null isn't a legal serialization candidate");<br /> }<br /> var bytes:ByteArray = new ByteArray();<br /> bytes.writeObject(value);<br /> bytes.position = 0;<br /> var be:Base64Encoder = new Base64Encoder();<br /> be.encodeBytes(bytes);<br /> var res:String = be.toString();<br /> be.reset();<br /> return res;<br /> }<br /> <br /> public function readObjectFromStringBytes(value:String):Object{<br /> var dec:Base64Decoder=new Base64Decoder();<br /> dec.decode(value);<br /> var result:ByteArray=dec.drain();<br /> result.position=0;<br /> return result.readObject();<br /> } <br /> }<br />} <br /></pre></div><br /><br />The logic is quite similar to the Java side code however when using the AMFSerializer we must register the serialized classes prior to serializing them:<br /><br /><div class='gray'><pre name="code" class="java"><br />registerClassAlias("com.jdftm.vo.CurrentDayVO", CurrentDayVO); <br /></pre></div><br /><br />Failing to so will cause the de-serialization process (on both sides) to fail since it uses the alias in order to create the resulting instance object, its also required that the serialized classes on both ends to be in the same package as implemented in the CurrentDayVO Flex class:<br /><br /><div class='gray'><pre name="code" class="java"><br />package com.jdftm.vo{<br /> [Bindable]<br /> [RemoteClass(alias="com.jdftm.vo.CurrentDayVO")]<br /> public class CurrentDayVO{<br /> private var _now:Date;<br /> <br /> public function get now():Date{<br /> return _now;<br /> } <br /> <br /> public function set now(value:Date):void{<br /> _now=value;<br /> }<br /> } <br />}<br /></pre></div><br /><br />As youv seen AMF isn't to hard to use and may prove to be a powerful contender in the crowded integration protocols market.<br /><br />Updated 2/09/08<br />Here is the SerializationContext implementation which is used in the Java serialization class<br /><br /><div class='gray'><pre name="code" class="java"><br />import com.google.inject.Provider;<br />import flex.messaging.io.SerializationContext;<br /><br />public class SerializationContextProvider implements Provider<SerializationContext> {<br /><br /> @Override<br /> public SerializationContext get() {<br /> SerializationContext serializationContext = SerializationContext.getSerializationContext();// Threadlocal SerializationContent<br /> serializationContext.enableSmallMessages = true;<br /> serializationContext.instantiateTypes = true;<br /> serializationContext.supportRemoteClass = true;// use _remoteClass field<br /> serializationContext.legacyCollection = false;// false Legacy Flex 1.5 behavior was to return a java.util.Collection for Array, New Flex 2+ behavior is to return Object[] for AS3 Array<br /> serializationContext.legacyMap = false;// false Legacy flash.xml.XMLDocument Type<br /> serializationContext.legacyXMLDocument = false;// true New E4X XML Type<br /> serializationContext.legacyXMLNamespaces = false;// determines whether the constructed Document is name-space aware<br /> serializationContext.legacyThrowable = false;<br /> serializationContext.legacyBigNumbers = false;<br /> serializationContext.restoreReferences = false;<br /> serializationContext.logPropertyErrors = false;<br /> serializationContext.ignorePropertyErrors = true;<br /> return serializationContext;<br /><br /> /*<br /> serializationContext.enableSmallMessages = serialization.getPropertyAsBoolean(ENABLE_SMALL_MESSAGES, true);<br /> serializationContext.instantiateTypes = serialization.getPropertyAsBoolean(INSTANTIATE_TYPES, true);<br /> serializationContext.supportRemoteClass = serialization.getPropertyAsBoolean(SUPPORT_REMOTE_CLASS, false);<br /> serializationContext.legacyCollection = serialization.getPropertyAsBoolean(LEGACY_COLLECTION, false);<br /> serializationContext.legacyMap = serialization.getPropertyAsBoolean(LEGACY_MAP, false);<br /> serializationContext.legacyXMLDocument = serialization.getPropertyAsBoolean(LEGACY_XML, false);<br /> serializationContext.legacyXMLNamespaces = serialization.getPropertyAsBoolean(LEGACY_XML_NAMESPACES, false);<br /> serializationContext.legacyThrowable = serialization.getPropertyAsBoolean(LEGACY_THROWABLE, false);<br /> serializationContext.legacyBigNumbers = serialization.getPropertyAsBoolean(LEGACY_BIG_NUMBERS, false);<br /> boolean showStacktraces = serialization.getPropertyAsBoolean(SHOW_STACKTRACES, false);<br /> if (showStacktraces && Log.isWarn())<br /> log.warn("The " + SHOW_STACKTRACES + " configuration option is deprecated and non-functional. Please remove this from your configuration file.");<br /> serializationContext.restoreReferences = serialization.getPropertyAsBoolean(RESTORE_REFERENCES, false);<br /> serializationContext.logPropertyErrors = serialization.getPropertyAsBoolean(LOG_PROPERTY_ERRORS, false);<br /> serializationContext.ignorePropertyErrors = serialization.getPropertyAsBoolean(IGNORE_PROPERTY_ERRORS, true);<br /> */<br /> }<br />}<br /><br /></pre></div><br /><br />This is the guice provider which is used when creating such contexts.ronenhttp://www.blogger.com/profile/13360463320878175457noreply@blogger.com24