Wednesday, December 16, 2009

No Next Big Language... Dunno, I suspect we may be stuck with one.

I've just read Alex Miller's blog entry regarding the NBL (Next Big Language) or rather the fact that there will not be a NBL and that the age of multiple programming languages has arrived.

I like the idea and I'm all for it to take off...

It's just that in my experience companies, especially those who's core industry is not IT related tend to minimize risk as much as possible, and therefore try to stay as mainstream as possible.

Java after all, quickly got pushed into the mainstream by companies like IBM and Oracle throwing their weight behind it, And consequently companies adopted it - I daresay - because it presented a much lower risk than many of it's competitors at the time such as Smalltalk.

Furthermore companies seem to like to standardize on a programming language since it makes things like hiring and training and administration a lot easier.

Its also these companies which keep the bulk of the programming community employed.

Therefore as much the acceptance of multiple programming languages is growing among us programmers I see very little acceptance of it with these companies who fork out the majority of the cash to get systems built.

Consider that Microsoft talked much about multiple programming languages when it released .Net and after almost 8 years you will be hard pressed to find a lot of work being done on .Net which isn't written in C# or VB.Net.

Consequently then it's normal that one of the language will get used the most and therefore employ the most people and become the NBL.

Now having said that I think Sun-Acle may actually be in a good position to take the multi-language concept mainstream, more so than Microsoft in 2002. For one thing the JVM is still the most portable runtime around, furthermore it's battle tested and smokin' fast. It's also widely adopted, supported and well understood.

The JVM could allow a company to standardize on the infrastructure but pick the tool which will be the most productive for the development task at hand.

Of course if this idea takes of, then we our next debate will be on the NBR (Next Big Runtime).


Submit to digg Del.icio.us My StumbleUpon Page Google Bookmarks

Thursday, November 19, 2009

Regarding Sun and Java 7 Closures

Here in South Africa we have a colloquial term: "oke". Pronounced "oak" it is basically a casual friendly reference for another male, kinda like "dude".

The word itself is actually from the Afrikaans language and has transferred into daily use by English speaking South Africans males. How it originated in Afrikaans I don't really know, It might simply be the Afrikaans translation of the English "bloke".

Typical usage is normally within a group of friends, for example you might tell your wife: "I'm off to have a beer with the okes" or as a more general reference: "Geez! did you see that try by Brian Habanna! That oke must be on speed or something".

Now regarding Java 7 and closures, I have this to ask of Java's venerable leaders: "Dear Sun, what the [expletive] are you okes doing?!"


Submit to digg Del.icio.us My StumbleUpon Page Google Bookmarks

Tuesday, September 22, 2009

Apple and it's nefarious ways.

I hope this whole Google Voice App scandal completely blows up in Apple's face.

A nice hefty fine consisting of least 9 digits would be perfect.

Why you ask, because like other iPhone developers I'm rather fed up with the whole process.

Furthermore Apple seems to forget that it's not a monopoly, I have plans to write software for the Android platform (when commercial apps come to my region), and quite honestly if the experience is better what reason could I possibly have to do iPhone work.

A nice scandal like this might have the ability to force Apple to be a little more transparent with developers.


Submit to digg Del.icio.us My StumbleUpon Page Google Bookmarks

The naked fan boy

I'm an Apple fan, and I am the proud owner of both a Mac book pro and an iPhone 3G. I've always been quite happy to admit that I am a "fanboy" of Apple products.

It turns out though that I didn't actually know what a "fanboy" is.

My understanding of what a fanboy is, is rather mundane: It's simply a person who is a fan of a product or brand or even a personality.

My friend however has a different view, his view of what a fanboy is seems rather more suited to someone who is a member of Al-Qaeda.

Now much as I like Apple I'm not blowing myself up because someone happens to criticise the new iPod.

So in order to reduce my ignorance I consulted that completely reliable source of truth: Wikipedia to find out more about what a fanboy is. This is what I found:

"Fanboy is a term originating in the United States[citation needed], used to describe a male who is highly devoted and biased in opinion towards a single subject or hobby within a given field. The earliest known recorded use is dated 1919.[5]"

The key phrases here are "highly devoted" and "biased".

Kinda strong words for something that should be as black and white as a technology choice.

The fact is though that if you step back and look at the whole IT scene and apply this definition you can't help but feel that us computer geeks are nothing much but a whole bunch of fanboys. Here is a short non exhaustive list of some of the fanboy debates I've been privy to during my time as a computer geek:

  • AMD vs Intel.
  • ATI vs NVidia.
  • 3Dfx vs NVidia.
  • .Net vs Java.
  • C++ vs Java.
  • [for brevity's sake: Insert your language of preference here] vs Java.
  • RISC vs CISC.
  • Linux vs BSD.
  • Linux vs Windows.
  • OS2 Warp vs Windows 95.
  • Xbox vs Playstation.
  • Microsoft vs Open Source.
  • OSX vs Windows.
What really amazes me though is how the same person who can explain to you the nuances of Lisp on the one hand, can then on the other hand scream bloody murder because you bought product X instead of Y and that makes you an idiot because product Y is clearly 5 attoseconds faster than product X and unlike product X, product Y's maker does not sacrifice little children in order to gain market share.

And we're supposed to be that smart guys....

I guess it's perhaps a reflection of our passion, by in large technology people are very passionate about what they do and have a strong belief in the importance of what they do, after all; no other profession has caused as a dramatic a change in the last few decades to the way the world works as we have.

Of course it's perhaps also indicative of the fact that when it's all said and done, Computer geeks are just as driven by emotion as the rest of humanity.


Submit to digg Del.icio.us My StumbleUpon Page Google Bookmarks

Friday, September 18, 2009

A quick sample of Lists and Tuples in Scala

So I've been challenged with a simple problem to solve in Scala, that is; to take a List of values and and then sum each corresponding value in the list together into a resultant list.

For example:

[1,2,3,4,5] becomes [3,5,7,9]

You can accomplish this in Scala using the List class and its functions, these include:

  • zip : this function takes an input list and creates a list of tuples with each mapping pair, discarding jagged values.
  • tail : this function returns a list minus the first element of the list on which tail is performed.
  • foldLeft : combines the elements of the list together with a seed value (in my case I use a target List).
  • reverse : reverses the order of the list.
so here is the code to do this:
object SumPairs extends Application {

val numbers = List(1,2,3,4,5);
val result = numbers.zip(numbers.tail)
.foldLeft(List[Int]()) (
(list, y) => {
y._1 + y._2 :: list
}
)
.reverse;
println(result);

}

Basically this works as follows:
  1. I create a List of Tuples of each adjacent value in the List by getting the tail of the List.
  2. I get each Tuple in the list, sum it and prepend it to the List returned by "foldLeft".
  3. I reverse the List to fix the order as a result of doing a prepend.
Now this is is designed to be functional but not overly complex (at least I hope not), Since I'm still fairly green in the Scala dark arts I'd like to hear on improvements.

BTW the challenge I'm talking about can be found here.

UPDATE:

Another solution would be to use List.flatMap which basically takes a function which returns an Iterable and appends it to a function, it pretty similar, It's maybe a little more concise, I'll let you decide:

val numbers = List(1,2,3,4,5);
numbers.zip(numbers.tail).flatMap {
value => {
List(value._1+value._2);
}
};


Submit to digg Del.icio.us My StumbleUpon Page Google Bookmarks

Friday, July 31, 2009

Dynamic Data Access Objects for JPA

JPA is pretty cool and JPA 2.0 looks even better, in a standardised way JPA has managed to rid us of the pain of CRUD, which; when it's all said and done is still the heart of most enterprise apps.

One thing that isn't very clear is how to implement the Data Access Object pattern in JPA. For one thing EntityManager pretty much takes car of abstracting your data access and that as some notable authors have pointed out you don't necessarily need to create a DAO at all. I agree with this but there are a couple of problems I keep running in to:

  • How to manage the vast numbers of queries that you get when you start doing anything useful in an Enterprise System.
  • Testing is made hard in that EntityManager is the pits to test especially when you start writng queries with many parameter, inevitably you end up with a vast brittle network of mocked objects which don't actually add any value and make my life miserable every time you make a change.
  • Named queries are great but but they really bloat your code for a multitude of "adhoc" queries which just seem overkill for me to put into a NamedQuery.
  • Queries are still strings and until JPA2.0 rolls out we can't avoid this indirection. One of things that the DAO pattern used to provide is a method for a query which normally named the purpose of the query and named its parameters and typed them, which was a real blessing when you had to work on code several years old.
Of course the other side of the coin is that we don't want to bring back a lot of boilerplate code, and end up writing too much custom stuff which re-implements features that JPA already has.

My suggestion therefore is to shamelessly steal ideas from Ruby on Rails albeit in a Java-fied manner.

The idea in question is the concept of a finder method in Rails. The one where you can simply call a class method on your Entity: EntityClass.findByName(theName) and thanks to the magic of Ruby's MOP; Rail's ActiveRecord pattern ORM framework can dynamically generate a sql query to go hunt for records for the entity where the name column is equal to "theName". All this without you having to write a single line of additional code.

Of course by now most readers will be smiling since they know that Java definitely has no Meta class facilities. This is of course very true, We can't replicate the exact flexibility of ActiveRecord but we can get some features by resorting to the closest thing Java gives; none other than the good old Dynamic Proxy.

Lets take the following interface:

package repo;
import java.util.Collection;

public interface AnEntityRepository extends EntityRepository<AnEntity> {

AnEntity findByName(String name);

Collection<AnEntity> findAll();

}
This interface extends an interface called EntityRepository (this is just a little marker interface so that I can hit F4 in Eclipse and I also use the type parameter to link the interface to an Entity) Each method on the interface maps to a specific query we want to run against an Entity class "AnEntity", the first method is a simple findByName which will have JPAQL generated dynamically, the next one is findAll which we map to a Named query.

Here is how we will do it: we will pass this interface to the dynamic proxy framework together with our own code to handle invocations which will do the following: first try map the invoked method name to a named query, if that fails we check if the method name starts with "findBy" we then do some funky string gymnastics on the rest of the method name to attempt to extract properties of the targeted entity and then build some JPAQL from that, then create the query and map the passed method parameters as query parameters to it. If any of the previous steps fail we blow up with a Runtime exception.

First step: The proxy framework requires an invocation handler (java.lang.reflect.InvocationHandler), this class is responsible for handling method dispatches from the proxied interface, mine is called RepoInvocationHandler (Repo being short for Repository):

package repo;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class RepoInvocationHandler implements InvocationHandler {

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

}

}
the invoke method will actually handle all the dispatches coming from the proxy, the parameters indicate the proxy instance that called with method, the actual method being called and the parameters that were passed to the method respectively. The first iteration of this invocation handler will be to build a JPAQL from the simple finder method, note that we pass a class in to the invocation handler, this is the entity we wish to query. Here is the implementation of the RepoInvocationHandler to do precisely that:

package repo;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Collections;
import javax.persistence.EntityManager;
import javax.persistence.Query;

public class RepoInvocationHandler implements InvocationHandler {

Class<?> targetEntity;
EntityManager entityManager;

public RepoInvocationHandler(Class<?> targetEntity, EntityManager entityManager) {
this.targetEntity = targetEntity;
this.entityManager = entityManager;
}



public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String name = method.getName();
String query = buildQuery(name);
Query q = entityManager.createQuery(query);
int parmIndex = 0;
for (Object arg : args) {
q.setParameter(parmIndex++, arg);
}
//we can add the functionality to return a single result or multiples
//by checking if the return type is a Collection instance.
if (Collections.class.isAssignableFrom(method.getReturnType())) {
return q.getResultList();
} else {
return q.getSingleResult();
}

}

String uncapatalise(String property) {
return property.substring(0,1).toLowerCase()+property.substring(1);
}

String buildQuery(String name) {
if (name.startsWith("findBy")) {
String property = name.substring("findBy".length());
//uncapitalise to adhere to conventions
property = uncapatalise(property);
return "select x from " + targetEntity.getName() + " x where x." + property + " = ?";
}
throw new RuntimeException("oops, looks "+name+" is not a finder method");
}

}
A note: you can make finder methods as complex as you want, this case just takes a single property and does an equals to query (select x from repo.AnEntity x where x.name = ?). The possibilities -however - are endless, Ive implemented this with AND and OR functionality so I can write "findByNameAndSurname(String name, String surname) or "findByNameOrSurname(String name, String surname) with n levels of predicates. however I want to keep the features of the generated finder method simple, if your query becomes to complex it should become a NamedQuery, which then brings us to the next iteration.

The next iteration of the invocation handler adds the ability to utilise NamedQuery functionality in order to handle complex queries, it also allows us to override the standard finder functionality:
package repo;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Collections;
import javax.persistence.EntityManager;
import javax.persistence.Query;

public class RepoInvocationHandler implements InvocationHandler {

Class<?> targetEntity;
EntityManager entityManager;

public RepoInvocationHandler(Class<?> targetEntity, EntityManager entityManager) {
this.targetEntity = targetEntity;
this.entityManager = entityManager;
}


public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String name = method.getName();

Query q = null;
//Note that I create a named query in the format EntityClassSimpleName.methodName
//this is because named queries are global not so by prefixing the entity class name
//it mostly eliminates duplicate named queries, it also gives a useful convention.
try {
String namedQuery = targetEntity.getSimpleName()+"."+method.getName();
q = entityManager.createNamedQuery(namedQuery);
} catch (IllegalArgumentException e) {
//yes there are more efficient ways to do this, however this is easiest
}
//no named query so lets build one from the method name
if (q == null) {
String query = buildQuery(name);
q = entityManager.createQuery(query);
}
int parmIndex = 0;
for (Object arg : args) {
q.setParameter(parmIndex++, arg);
}
if (Collections.class.isAssignableFrom(method.getReturnType())) {
return q.getResultList();
} else {
return q.getSingleResult();
}


}

String uncapatalise(String property) {
return property.substring(0,1).toLowerCase()+property.substring(1);
}

String buildQuery(String name) {

if (name.startsWith("findBy")) {
String property = name.substring("findBy".length());
//uncapitalise to adhere to conventions
property = uncapatalise(property);
return "select x from " + targetEntity.getName() + " x where " + property + " = ?";
}
throw new RuntimeException("oops, looks "+name+" is not a finder method");
}

}
For reference purposes I've included what the NamedQuery declaration would look like on AnEntity for the method "findAll":
@NamedQueries( {
@NamedQuery(name="AnEntity.findAll", query="select x from AnEntity x")
})
public class AnEntity implements Serializable{
...
}
And there we have the basic functionality I want to implement, the last thing we need to do is create the proxy, I have a simple factory which takes in the Interface (I've forced all the interfaces to extend the EntityRepository interface, for documentation and typing purposes) as follows:
package repo;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Proxy;
import javax.persistence.EntityManager;

public class EntityRepositoryFactory {


public static <T extends EntityRepository<?>> T createEntityRepository(Class<T> homeRepositoryClass, EntityManager entityManager) {
ParameterizedType type = (ParameterizedType) homeRepositoryClass.getGenericInterfaces()[0];
Class<?> entityType = (Class<?>) type.getActualTypeArguments()[0];
return (T) Proxy.newProxyInstance(
Thread.currentThread().getContextClassLoader(),
new Class[] {homeRepositoryClass},
new RepoInvocationHandler(entityType, entityManager));
}

}

Finally using this interface is as simple as creating it via the factory and then calling the methods:
   AnEntityRepository repo = EntityRepositoryFactory
.createEntityRepository(AnEntityRepository.class, entityManager);
AnEntity entity = repo.findByName("Fred");
Collection<AnEntity> allEntities = repo.findAll();

A few final notes:

  • For testing purposes you simply mock out the interface, either with a mocking framework or an anonymous classes.
  • There's nothing stopping you from creating the factory in Spring if you are using Spring.
  • I wish EJB3.1 had introduced a Factory concept for creating instances of beans much like Spring has this would make life easer in the EJB world.
  • Sooner or later you will need to create pagination, you can add this functionality by using parameter annotations, I was thinking of something like: "findAll(@Start int start,@Max int max)";.


Submit to digg Del.icio.us My StumbleUpon Page Google Bookmarks

Monday, June 8, 2009

Is Javaless Java reaching critical mass?

There is a lot of talk about how this is possibly the last JavaOne, as Oracle is about to buy Sun out.

However if you look at what everybody was at talking about at JavaOne you can't but help get the idea that JavaOne is an anachronism any way, this trend seems to involve:

- JavaFX.
- Groovy.
- Scala.
- JRuby.
- Honourable mentions for Clojure and Jython.

It's hard to miss the lack of Java here...

Ok so people are interested in other languages in the JVM, however interest doesn't necessarily translate into use.

This brings me to my question: have alternative JVM languages gone mainstream? can I go to my client who is still trying to get COBOL out of their system and confidently sell him on one of these alternative languages?


Submit to digg Del.icio.us My StumbleUpon Page Google Bookmarks