Tuesday, December 22, 2009

Recurring patterns in applications

I was just doodling around the architecture of my latest project when I suddenly realize that I have done the same thing over and over again for every project. I'm sure anyone of you who has successfully delivered more than ,say ,5 projects would realize that there is a pattern to almost 80-90% of stuff out there.

I started to scribble some of the recurring patterns I have seen again and again in many projects. I'm putting it here and am very greatful if anyone could add more to this. Now to verify what I'm saying is in fact recurring, I'm going to examine the presense of these patterns in three different context a) A social network ala facebook b) A workflow application c) A content management system (CMS)

1) All system must have Users

a) Social network : Yes
b) Workflow app: Yes
c) CMS: Yes

2) Users live in a Context (for example, roles, location etc.)
a) Social network: Yes. Two very obvious context: logged in logged out.
b) Workflow app: Definately yes. Swimlanes (roles) can be considered context
c) CMS: Yes. There are plain old users, there are admins, there uploaders, there are downloaders etc.

3) Given a User and a Context, there are a few Lists of Items.
a) Social network: YES. When you log in to facebook or twitter there is a list of entries/microblog
b) Workflow app: YES, you would have a list of tasks (either done, pending, kiv, delegated etc.
etc.)
c) CMS: YES. You would have a list of contents

4) An Item can contain either basic data: texts, numbers, links, images, videos, file attachments or links to other Items
a) Social network: Yes. You have all the classic types of data but also replies and "retwitts" etc.
b) Workflow app: Yes, you would have tasks descriptions and attachments for example. If the item is delegated, you will also see the delegated items
c) CMS: Yes. You will see the content and if you have "folders", you can have links to other data.

5) An item is aware of whom (Users) and how (Contexts) it should be accessed
a) Social network: Yes, only users and probably their friends could access certain photos for example
b) Workflow app: It is obvious with swimlanes, certain users canonly access certain data. What is more interesting is that certain users can access part of an item while others can only access other parts (think of government forms where you have "For Office Use Only" part)
c) CMS: Yes, folders have rights much like a Unix file system.

6) A User could be in a Relationship with N other Users. We call this relationship Contact.
a) Social network: Yes, obviously
b) Workflow app: Yes. In most workflow applications I've seen, Contacts are amed 'Supervisors', 'Subordinate' or 'Team member'.
c) CMS: You can certainly share content with other people. Not formally a Contact but still uses the same principles.

7) User should be able to log in to the system and eventually log out
a,b,c) Yes, obviously

8) A user can create Item and make it accessible to other Users (either from within his Contact or not)
a,b,c) Yes, obviously. This puts the responsibility of creating an Item on the User's hand.

9) User who creates an Item is responsible for the lifecycle (CRUD) of that Item
a,b,c) Yes, obviously

10) User who has access to an Item should be able to Read and optionally Update an Item
a,b,c) Yes, obviously

11) A system should be able to listen to the lifecycle of Items. User defined filters could be defined at each lifecycle action.
a) Social network: Yes. This is similar to Facebook email alerts when people reply to your post. The reply can be considered an Item, creating a reply is an event listened to by the system.
b) Workflow app: Yes. At every stage of a workflow, a filter can be triggered (I think Adempiere works this way to update its account database).
c) CMS: Yes. Again, email alerts can be sent when items are uploaded/created/deleted

12) There are 2 types of lifecycle action 1) Rules: To validate the lifecycle action
a) Social network: Yes. An email alert should only be sent if the new item created is a response to an existing item.
b) Workflow app: Yes. A rule is always attached to every "decision path" (the exclusive choice pattern) in a workflow.
c) CMS: Yes. A rule for example that states when a non-empty forlder cannot be deleted. Or a content viewed by another user cannot be deleted.

13) Type 2) Events that could trigger lifecycle actions on other objects.
a) Social network: Yes, adding a Contact (I.E. adding another person into your Contact) triggers an event that will add you to the contact of that other person. (I add u as friend implies, you will also add me as a friend).
b) Workflow app: Yes, for example in Adempiere, a workflow that creates an Invoice triggers the modification of Account.
c) CMS: Yes. Recursively deleting a non empty forlder might delete all its contents.

14) Users can do CRUD lifecycle on their Contacts. These actions will also generate Events.
a,b,c) Yes, obviously. You can always delete and add new people to your contact.


Now why are these patterns important? Well imagine now I've created a bare bone application (call it a framework if you will) and imagine that I want to create a Social Network. All I have to do is customised that "framework" and within a short time, tada~ a social network. I have only to define what is Item in my application context (which is social network), what is a User, what Events need to be generated and what Rules need to be triggred and I'm done. Someone else might define Items as Account, Activity, Invoice, Inventory etc. They might define Events as CreditToAccount and DebitFromAccount etc. and define Rules such as "When Inventory is low, start Procument process" and bam!, the framework is now an ERP.

Now let us take this further, what if this framework define not just bare bone stuff but also things like open persistence policy (which allows you to connect your app to any database), a well thought out GUI, a caching mechanism out of the box, a clustering facility , a reporting and BI facility and some security enhancement here and there. Suddenly, I can focus on creating my latest shiny new social network or create my own ERP focusing mainly on what the application should do rather than all the nitty gritty stuff like scalability.

Of course, what is defined here is probably incomplete at best and naive at worst. There are overlaps I'm sure (like Rules and Context could be the same thing). If you do have other stuff to add, please do enlighten me. (Or if you think certain things are just superflous). Maybe creating this framework could be my next big FOSS project :)

Saturday, December 12, 2009

Weld DI and Glassfish Example



Last Thursday I gave a presentation to a few Experian staffs on Weld DI. You can find the presentation here:

http://www.scribd.com/doc/24005727/Look-Ma-No-XML


Examples can be found here:

http://www.freedrive.com/member/viewfolder/250059

Tuesday, December 8, 2009

Message Driven POJO with Java Content and Dependency Injection API (Weld) a.k.a Look ma! No XML!

I am supposed to be presenting 'Something new and exiting in Java' to staff of Experian Malaysia. Looking around, it seems that I am frekin lucky since we have a few new and exciting things in the Java world. Java EE 6 is finally here! (Phew!~), Netbeans 6.8 RC 1 is out! (with support for Java EE 6 - you can create a session bean right in your war file - I kid you not!) and finally Java CDI (I think, JSR-299) is finally here too!.

I decide to play around with CDI implementation by JBoss (called Weld). There are other implementations out there notably CanDI by Caucho and OpenWebBeans by Apache.

Anyway, CDI allows you to do strong typing dependency injection without XML (of course, XML is still there just in case you need it). Weld can be downloaded here [http://seamframework.org/Download]. A full tutorial by JBoss teamcan be found here [http://docs.jboss.org/webbeans/reference/current/en-US/html/index.html]. Note that the tutorial was created about a year ago [on the internet scale, that is the equivalent of the time between the Triasic era and the French Revolution], so some things are not up to date. A better approach is to learn stuff off the examples in weld zip file.

Here's an example of CDI:

With CDI, we can create Java Beans with a particular scope. In this example we have a Singleton scope. This means that there will be a single instance of SomeService for the whole application.


@Singleton
public class SomeService{
public String doSomething(String parameters){
//do something here
return result;
}
}


To access the service, we can just inject it to a class


public class Client{
@Inject SomeService someService;

public void run(){
//use someService
}
}



Note that we do not need to invoke any constructor or factory of SomeService in Client. The lifeCycle of SomeService is managed directly by Weld.

Anyone who uses Spring before knows that Spring can also do much of the same thing. Its just that Weld can do all this while being strongly typed and xml-less (Maybe Spring does make XML optional these days, I have not checked)

Now the big finale, one use case of Spring that I find fascinating is Message Driven POJO (MDP). So, I wanted to create one using Weld.

OK, since I don't have much time, I 'cheated' a bit by using ActiveMQ libraries and by making my MDP works only with ActiveMQ... but hey, it works >:) [Maybe I should call it Message Driven ActiveMQ Producer/Consumer instead ;) ]

I based my implemetation on this [http://developers-blog.org/blog/default/2008/10/28/A-simple-ActiveMQ-example] (Thanks Gisbert) .

After much toiling (my first implemetation uses Spring libraries... a pile of fun that turn out to be), I manage to create an MDP using Weld.

An MDP looks like this:


@Consumer
public class Processor {

public void processRequest(RunnableMessage runnable){
runnable.run();
}

public void doSomething(String string){
System.out.println("Received string="+string);
}
}


The Consumer annotation indicates that this object is ready to receive messages. The messages are in fact POJOs themselves, so when a message arrives, depending on the type of the message (or rather the type of the payload of the message), a method within the Processor object is chosen.

To send a message, I just do this:


RunnableMessage r = new RunnableMessage(); //r here is just another POJO
activeMQService.sendMessage(r);


And processRequest will be invoked.
If I do:


activeMQService.sendMessage("If you type google into google, you will break the internet");


Then I will invoke the method doSomething instead.
Cool eh :)

Anyway, the source code with all its dependencies are here [http://www.freedrive.com/file/1045164,weldmessage.zip]. To run this, you need to download ActiiveMQ
[http://activemq.apache.org/download.html] and run it. (Unzip the file and run the executable in the bin directory). Next, just run the example.

Have fun!

Monday, November 30, 2009

Will JavaFX die?

Will JavaFX die? I really hope so because it will teach the next RIA wannabe to not dump another scripting language to the masses and hope, with the sincerest of hope, that GUI designers will become coders over night. How on God blue Earth does an RIA does not have a visual editor? (And BTW, no matter how good you are,... wishing that a text editor somehow, through the magic of Christmas, becomes a "visual editor" will not make it so .. you hear me Exadel!) . JavaFX need 2 concrete things to survive: 1) An Android runtime 2) A visual (you know, like Flex Builder visual, not XEmacs visual) editor

Sunday, November 22, 2009

Upgrading (kids and adults)


It was a fine weekend to do a seminar + upgrading. Kids upgrading was load of fun. Most of them work hard for the upgrading and it shows. It's quite a revelation to see how much these kids grow over the years.

The seminar was a success. So many people attend that we had to work with limited space but it was worth it.

Congratulations to all!
Posted by Picasa

Tuesday, November 17, 2009

Adempiere references in Plain Old Java


Right now, I'm learning Adempiere and finding ways on how to hack it apart (and put it together again). I'll be "reporting" my findings on this blog on how things are done and how some of these concepts can actually be used in Java in general.

One thing that interests me in Adempiere is the Rapid Application Development feature, especially when building rich CRUD based stuff. Adempiere has this concept of "everything must have metadata". By manipulating this metadata, CRUD based application can easily be done.

In the general Java world, metadata manipulation used to create CRUD based apps is not new. Frameworks such as OpenXava (who claim to have beaten RoR development record time - apparently that article is not accessible anymore) is attracting much attention. One thing Adempiere does differently is by qualifiying relationships between Domain Objects (of course in Adempiere, the Domain Objects are Relational Database Tables since Adempiere uses direct / semi-direct SQL access). Disclaimer - I'm not an OpenXava expert, so if OpenXava does these stuff too, please do tell.

Imagine if we can port this to the Java world in general

[If you are not familiar with the concept of Reference in Adempiere, I would like to redirect you to my good friend, Red1's, tutorial ]

In Adempiere you can qualify a reference (a link from one table to another table). For example you can say that a reference is "Searchable". When the reference is rendered, you would see a "search box" that is linked to data from the reference table. You can type away a search term and the reference table will be searched.

How can we do this in Java in general?

To demonstrate this, we'll look at an example: Imagine that I have 3 entities, User (plain old User - ok, maybe not so old :) ) , PurchaseRecord (a record of a purchase made by the user) and Product (the actual product the user purchase)


Using JPA or Hibernate I could have codes representing the entities as:

@Entity
public class User{
@OneToMany
private Set purchaseRecords;
}

@Entity
public class PurchaseRecord{
private Product product;
private int number;
private Date purchaseDate;
}

@Entity
public class Product{
private String name;
private String unitPrice;
}

If I'm using plain old CRUD generator , I would create a User list. Clicking on a User from the list would give me the details of that particular user and a list of PurchaseRecords. That list is presented as is. If I'm lucky, the CRUD generator will allow me to page or sort the data. One thing I do not have is a quick access to a particular record and the subsequent Product attached to that Record. But, imagine if I can do this:

@Entity
public class User{
@OneToMany
@Display(qualifier="PurchaseRecord.product.name")
@Searchable(by="PurchaseRecord.product.name")
@DefaultFilter(qualifier="PurchaseRecord.purchaseDate=DateQualifier.TODAY")
private Set purchaseRecords;

}

Automatically, when I click on a user, I would still see a list (but this time a list of names of products, which is more palatable) and also a text box, a dropdown list and a button.

The textbox represents a search term box. You can search your PurchaseRecord by its name. Enter your search term and click on the button. The dropdown list represents filters. By default, PurchaseRecord will be filtered by date=TODAY (only today's entry is displayed). The user can always choose any other available filters.

Of course I'm just imagining stuff here and I'm sure there are some gaps that need to be filled in (for example, does having a @Display tag violates MVC) but the concept of Reference in Adempiere is really powerful. Hopefully someone could bring this concept to the JPA/Hibernate world.

Sunday, November 8, 2009

What is wrong with Malaysian IT scene

Before reading this, please see the disclaimers at the bottom.


What is wrong wth the Malaysian IT scene can be dully observed from one of the most significant ICT event here in this country called the MSC Malaysia International Advisory Panel (or IAP) meeting. Here's the website of said event: http://iap-portal.msc.com.my/ .Surf the website and you'll see what I mean.

1)It's the the people, stupid

Browsing through the IAP website, we have the impression that it is just a business event. Nothing "techie" about it. In fact, asking around, it seems that the Malaysian tech communities are blissfully unaware of such event is going on right now under our collective hairy noses in PICC this week.

How on earth can the most important part of the tech. industry (i.e. the tech. people) are not even informed, heck, are not even welcomed to the biggest MSC event this year?!

Is it just me or is MSC a place where techies are regarded as second class citizens compared to quote unquote businessmen? How on earth can MDeC justify limiting their allocation for tech. employees under their pre-seed and iconity grant to only RM 1500 per month (irregardless of qualifications or experiences)? BTW, just to put things in perspective, the government of Malaysia recently declared that families earning RM 3000 or less per month and are living in cities are called the urban poor. If two techies, a boy and a gal, working for a preseed or iconity recipient companies decide get married, they superchalafragilisticexpiallodociously become the urban poor. And MDeC lament about the lack of talents in ICT, who wants to work hard during their University days and end up being declared poor!

Have these guys never learn?!

Build a strong community and business will come. That's the lesson of Silicon Valley that has somehow escape the collective brains of our policy makers. Silicon Valley started with the universities in the area. These universities have been building tech communities and when the electronic/transistor revolution came into the picture BAMM!!, the magic happens. But it started with communities. Not businesses.

The MSC brand has been a failure because it was attached to companies. MSC companies are known today as companies that do not pay EPF, do not give salary on time, try to treat their employees as slaves (gee, I wonder where they learn that from) by asking them to do extra hours and not getting paid for it. Companies are soulless money making machines. They would cut corners and take advantage of any loophole just to get another dime on their balance sheet. This can be seen by companies opening up "ghost branches" in MSC status area (such as Cyberjaya) just to escape paying taxes.

Communities on the other hand live and die by the spirit of its people. They rely on people being truthful, honest and willing to sacrifice. And yet, MDeC is blind to these sacrifices. In fact, some of our community leaders are so pissed poor, they can't even afford to buy LRT tickets. Some have to beg for jobs and some got so upset they left the country for good (good for them, bad for Malaysia). Those who bite their lips and stay are riddled with redtapes and unfulfilled promises that its not even funny anymore.

If MDeC would have spent as much on building the soulless MSC companies as they would on building communities, we would have gone further by now!

2) The locals are just as good

Looking at the talks and the programs listed on the website, I was really wondering "Gee, I can do that talk too. Heck, I can even do it better since I know the local context".

I mean gosh!, it says "international" but are the locals too stoopeed to advise MSC and how to go about doing things? Isn't Dr. Mahathir's main message to the world is that we want to be strong, but we will do it OUR WAY! Somehow that message, that twitt, does not reach MDeC.

Are our collective brains still clogged with the imperialist white-men fetish that we can't even see how much our own people have grown over the years?. Somehow, just because you're white, no matter how stupid , incompetent or evil minded you are, you are always correct. "Yes sir Mr. Balmer sir, you can rob my country and kick my butt to boot. It's ok because you're an American and you're the CEO of Microsoft"

Stop this stupid nonsense! I can give more relevant advices to MSC and I'll do it for free (heck, I even said it outloud here and here) and yet, just because my butt is the wrong color, no one gives a crap!

3) So much more

I have so much more to rant but tears are running through my eyes watching how much my beloved country is wasting yet again an oppurtunity to turn things around. I really hope our future leaders would have enough insight to consider my rant. Hopefully, things will get better. We have no other choice, we either get better... or die ...

DISCLAIMERS

If you are an MDeC employee, please do not think of my rant as an attack on you personally. I do think that people in MDeC are also individuals (and thus part of the community) who choose to work with MDeC when they can pour their talent somewhere else (and probably get better pay). Heck, I know a few good people in MDeC who were courted by oversea companies and yet they decline the offer for the love of the country. If anything, they are more into it then us developers. I believe that people in MDeC are heroes but some of the policies are real time-wasters.

Sunday, September 27, 2009

Why hate design patterns?















Here we go again. First and foremost, I know that every one and their uncle :) is writig a response to Joel's "Duct tape programmer" post. Is it just me or from time to time Joel just spew some controversial stuff just to measure his influence on the world. Anyway I'll bite...

Now I'm not going to bite the whole thing (obviously, some people who are more capable than I am are already replying), I just want to say this: what's up with all these "design pattern haters" out there?! Joel associate design patterns with astronout architect... really now? (or maybe he's just associating design patterns meetups with astronout architect ... I can't really tell).

Here's a quote from the GOF book:

"A design pattern systematically names, motivates, and explains a general design that addresses a recurring design problem in object-oriented systems. It describes the problem, the solution, when to apply the solution, and its consequences. It also gives implementation hints and examples. The solution is a general arrangement of objects and classes that solve the problem. The solution is customized and implemented to solve the problem in a particular context"

Notice the words names, motivates, explains and describes in the book. These words refer to the action of communication. And frankly, at least for me, design patterns are first and foremost a tool for communication. Sure just like everything else in this frekin' world, design patterns can and have been abused... but do you tell your junior programmer who tests every setters and getters that he should never ever write unit tests anymore while he shall live so help him God? No, you teach and coach. The same goes with design patterns, you have to (suprise suprise) teach people to use them properly.

Of course there is also the " lets us just cobbled some code together and if we see a design pattern fits somewhere, we just intergrate one in the next refactoring exercise" camp. My question is... why?

If you know that you need to traverse a collection of stuff in Java and do different things to different objects depending on its type... why not just use the visitor pattern straight away? Sure, you can kick off some cobbled together something and then decide to refactor to the visitor pattern later, but what if the programmer that did the first solution left the company and a new programmer is hired and you are stuck having to explain what has been done. SUre, that's a boatload of fun... or rather, you can just say that you use the visitor pattern... which you, the last programmer and the current programmer already understand. Now that facilitates communication and saves a whole lot of time.


In the end it is neither technology (COM, or CORBA) nor methodology (agile or design pattern or "duct taping") that is going to win the battle, but rather, its people. The more good people you have, either they are duct tape programmers or not, you will win. I think Joel knows this already. He talked about this in one of his old article. To get enough good people, you need good teachers. Now, duct tape programmer or not, if you cannot pass down your art, then you are just as useless as a used duct tape.

Cybermerdeka in finally online!


Finally, my Cybermerdeka talk is online. The slides are available here

Sunday, August 23, 2009

CRUD vs. HATEOS

Of late there has been a few blog post on HATEOS vs. CRUD as the underlying architecture (if I can say that) for RESTful services. I think it was started by Arnon's post [http://www.rgoarchitects.com/nblog/2009/06/23/CRUDIsBadForREST.aspx]. I know infoq has a summary somewhere but I couldn't find it right now. [Please read Arnon's post for background on HATEOS vs. CRUD]

Here's my contribution on the whole thing.

First of all, we should know that what Arnon suggested was not "CRUD is evil and should rot in garbage landfil somewhere ... " or anything near that. [So the CRUD proponents should not get so worked up about it]. He is suggesting that CRUD is OK but you can do better. Especially if you need control - I.E. if the business process that you run is super critical, like some baby seal is going to be devoured by Bernie Maddox if you don't execute things in order, than HATEOS is the way to go.

In fact, HATEOS is just that : RESTful workflow

Note to self: investigate if HATEOS can replace BPEL just like REST replaces SOAP

Now, I believe that HATEOS is superior to plain old CRUD because of one thing:

Long Running Transaction (LRT)

LRT is a way to do transaction in a long running processes (typically, a transaction that involves people somewhere should be considered long running). In LRT, due to time constraint, it is impossible to lock an object (a database row, a resource, etc.) for the whole transaction. ACIDity is assured only on single operations but not the whole transaction. What happen when failure occurs? Well, you run another ACID operation to undo transaction.


Quoting wikipedia : "Long-running transactions are computer database transactions that avoid locks on non-local resources, use compensation to handle failures, potentially aggregate smaller ACID transactions (also referred to as atomic transactions), and typically use a coordinator to complete or abort the transaction. In contrast to rollback in ACID transactions, compensation restores the original state, or an equivalent, and is business-specific. The compensating action for making a hotel reservation is canceling that reservation, possibly with a penalty."


Example:

Given an e-commerce business process:

If the user cancel the order mid-way:




... We might need to fire another business process to compensate the original business process.



Now, here is where HATEOS really shines: Note that the compensation business process in this example is going to be fired by say, a call center receiving the user's cancellation request whereas the "Item has arrive" activity is probably going to be fired by some delivery service.

When the call center request the state of the business process, we will send an xml object and also includes a link to cancel the order.

When the delivery service request the state of business process, we will send an xml object and also includes a link to indicate that delivery is completed.

With plain old CRUD on the other hand, well, you will not know what API to invoke and what are our options. Heck, user might even invoke things that they should not.

Also note that, each activity within the business process actually has a corresponding "compensation" activity. This compensation activity will certainly undo the real business process activity. A link to the compensation activity is always available at each business process activity and can be invoked if needed. Unlike plain old CRUD where the user has to figure out at each stage of the business process what to do in case things go wrong, in HATEOS the user do not have to figure out what to do in case of exception: just invoke the compensation URL and all should go well.

Monday, June 22, 2009

To MDEC: Java should be a national agenda

















I had a meeting with MDEC a few weeks before OSCONF and they reveal some startling statistics: Apparently 50.6 % of MSC companies are in need... no... are dying to find good Java programmers. So much so, they don't mind going to Indonesia, the Philippines and many other places, to recruit programmers there (offshore). These companies are willing to train them and
pay them a handsome fee just so that they can have decent Java programmers.

Now, 50.6 % is a big number. It's bigger than the need for .Net, for Ruby, for Phyton,, for PHP, for SAP.

Heck, it's bigger than .Net, Ruby, Phyton, PHP and SAP COMBINED!

In other words, most (and that's a big "most") of the projects within MSC now are Java based.

Now here's a short reality check, what if we (as a nation) do not provide our MSC companies with these much needed Java programmers? Do you think the jobs will switch to PHP? No way
Jose. What will happen is that jobs are going to go away. In this case, it'll be roughly 50% of the jobs. I've read somewhere that we want to outdo China as the second largest outsourcing destination... well, if 50% of the jobs here are going to Indonesia... good luck with that.

So what should we do. Here's a few sugestion to MDEC:

1) Take over Java education in Malaysia and don't leave it to Sun

... Heck, don't even leave it to Oracle. In my experience, Oracle is sooo not interested in small markets (where most of the jobs dwindle) They care for big multi-million dollar accounts but Oracle is almost invisible in smaller arenas. The fact that Oracle is going to buy over Sun (and thus become the steward of Java) will mean less resources will be dedicated towards Java education (and it was already bad under Sun).

OK, I know a few people in Microsoft and the Ruby/Phyton/PHP group are so going to whack me on this but listen up: MDEC has to take over Java education, not because MDEC is favouring Java over other platforms or languages, not because MDEC is some Sun/Oracle/Java/Obama hugger. No! but because it makes business sense to do so. If MDEC is not doing this, good bye 50 or so % of MSC jobs. Besides, if you are a Ruby/Phyton/PHP developer, these language s run well on the JVM too so this call make sense to all (well, almost all :P )

2) Revamp the Java sylabus

Sun's objective in Java education is to ram a dead horse down the programmers throat... and that dead horse is called "applet programming". Ask any university student who has studied Java and they will equate Java to ugly applets.

Gosh! stop it already!. Applet is dead, get over it Sun... wait a minute, they did. That is why they introduce JavaFX. So, what is with this rubbing of people's face with applet anyway? because
people are lazy ... especially to update sylabus.

We need to revamp the sylabus. Sun will not do it for us. MDeC has to do it (On a side note, I'm more than willing to volunteer my time to revamp the Java sylabus).

In my opinion, to teach basic Java and OOP, Java ME should be a better platform. First off, I can just imagine how students feel if the "Pong" game they created can run on their own phones. It's
something to show off about, it's cool, it's something to twitt about...

Game is a perfect environment to teach OOP. Objects become natural (in form of sprite and what not).

Next, come basic networking. Heck, ask them to create a twitter client. That'll be cool too eh?. Next come bluetooth, GPS and what not. Mesh that up with Google Map and voila, Java becomes cool again!

Another point about revamping the sylabus is this: stop "protecting" the students. I know lecturers who say "We can't teach them JavaEE. It's just too complex, the students will become demotivated"... puhleeezzz.

The truth is, JavaEE is intimidating to the lecturers, not the students. JavaEE (Servlet 3, JSF 2, EJB 3.1, basic security, messaging... heck, even SOA) should be taught to final year students because if you do not know basic ORM you're practically useless as a Java programmer.

If the lecturers are inadequate in terms of experience and knowledge, we need to bring in the professionals into the universities. And thus my third point....

3) Bring in Java pros into the universities

During that meeting with MDEC, I can really feel the dire need by the companies to get good Java programmers. Now, if these companies are willing to travel in Indonesia to train people there, I'm sure they are more than willing to contribute to our local universities.

Sure, these Java pros might not have a PhD and, I guess, according to univerisities, they are somehow "muggles" and "has no right to take a podium at our distinguished ivory towers".

Here's what I have to say to that: Bulls**t!

Knowledge is knowledge. If it comes not from a research work but rather from the grudge of waking up at 3 in the morning debugging a JBOSS classloader, it is still knowledge worth propagating, worth teaching. And thus these Java pros need to be integrated into universities despite their lack of a PhDs.

4) MDeC needs to work closely with the universities

... on how to teach Java. Work closely with the council of Dean of IT faculties. Get them to commit on Java BIG TIME!. Bring Neal Gafter and Josh Bloch here to teach our lecturers on the intricacies of Java. Have an unconference where any lecturer can propose his approach to teach Java. (Heck, Microsoft did it for Windows, now MDeC has to do it for Java... remember the 50.6% )


It is not too late to act if we act now... I mean like now, this very second. To my friends in MDeC, please push for this. Not for Sun, IBM or Oracle but the sake of the nation.

Tuesday, June 9, 2009

Did we get MVC wrong?

Every computer science major and their iguanas have heard of the MVC pattern. It's being used by everyone from Sun to Microsoft.

Here's a diagram showing how MVC is suppose to work (shamelessly copied from wikipedia)


Now quoting from Wikipedia's entry on MVC [http://en.wikipedia.org/wiki/Model-view-controller] "Successful use of the pattern (i.e. MVC) isolates business logic from user interface considerations, resulting in an application where it is easier to modify either the visual appearance of the application or the underlying business rules without affecting the other."

Now here's what Reenskaug has to say about MVC (BTW, Trygve M. H. Reenskaug is the inventor of MVC) [http://heim.ifi.uio.no/~trygver/themes/mvc/mvc-index.html] and I quote "The essential purpose of MVC is to bridge the gap between the human user's mental model and the digital model that exists in the computer. The ideal MVC solution supports the user illusion of seeing and manipulating the domain information directly. The structure is useful if the user needs to see the same model element simultaneously in different contexts and/or from different viewpoints."

Wait a minute, that's different: The inventor of MVC emphasises the ability of MVC to give different views of the same data, while the wikipedia entry somehow talks about isolating (i.e. modularising - is there such a word?) application. Those two things are not the same!

The rub is, if you allow me to repeate: MVC was not created to modularise application, repeate after me. It was not for isolation people! It was created to give different views of the same big gianourmous data (c.f. Reenskaug's definition).

Sure, things are seperated into model, view and controller but that is just a consequences and not the main goal of MVC.

Confusing the goal of MVC with some other goals is actually detrimental to software development. Let us see how.

A typical MVC flow is like this:

User input --> Controller --> Update model--> View, observing the model has changed, updates itself

A typical non-MVC flow would be like this:

User input --> Controller --> (Update model and Update view)

The non-MVC is the model followed by say a typical Java Swing application, JSF and Struts. The problem is that the view is really inactive. The vision of multiple views being in sync with the huge data in the back-end becomes more difficult. Say, for example I want to add a new field in the view. The field already exist in the database, just a matter of displaying it. With MVC, I just query the model (from the view) when the view is "waken up" by the observation event. I need to change the view and that's that. With non-MVC approach, I have to update both the view and the controller to get the same effect.

The problem lies in the fact that, even in the non-MVC approach, my code is isolated and compartmentalised, if I stick with the definition given by wikipedia, I would therefore have the impression of doing MVC without actually doing it. Whereas with MVC, I'm reaping the benefit of MVC and at the same time getting my modularity, its like having my cake and eat it too.

Given how fast interface technology (RIA, Flex, JavaFX, Silverlight, your-hoot-n-nanny-of-the-day) is evolving, having multiple, insync views of a large data is inevitable. You would probably need to cater for, at least, the web and the mobile audience. Having a real MVC framework would help enormously... if and only if MVC is done correctly.

Friday, June 5, 2009

Scala Actor + Message Driven Bean (MDB) using JMS

 

What I wanted to do is to integrate Scala Actor and MDBs. The reason to do so is because Scala actors, as good as they are, are :

1) Not transactional

2) Cannot send message through  a network

This leads me to investigate what Java EE has to offer: Java Messaging Service.

Now in many implementation of JMS that I see, it will always end up in some Message Driven Bean (an EJB). So that is what I’m going to do. An actor will send a message in an MDB and the MDB replies back.

To use JMS with Scala actors, we need to use Spring. Spring offers a utility to create Message Driven Pojos (meaning, any Java object can be transformed into a message receiving object) Since Scala actors are actually Java objects on steroid, I figure that we can use Spring to equip plain old Scala actors with message (as in JMS message) receiving capability. This receiving actor will be called a “wormhole actor” as it bridge the JMS world and the Scala world.

OK, let us start: First we need to create a Spring xml file. This file contains several beans:

This bean helps us to find the JNDI engine of our Java EE server where the MDB resides.

    <bean id="myJndiTemplate" class="org.springframework.jndi.JndiTemplate" scope="singleton">
        <property name="environment">
            <map>
                <entry key="java.naming.factory.initial" value="com.sun.appserv.naming.S1ASCtxFactory"/>
                <entry key="java.naming.provider.url" value="iiop://127.0.0.1:3700"/>
            </map>
        </property>
    </bean>

This bean defines the queue factory

    <bean id="jmsQueueFactory"
               class="org.springframework.jndi.JndiObjectFactoryBean"
                abstract="false" lazy-init="default" autowire="default"
                dependency-check="default">
        <property name="jndiName">
            <value>jms/QueueFactory</value>
        </property>
        <property name="resourceRef">
            <value>false</value>
        </property>
        <property name="jndiTemplate" ref="myJndiTemplate"/>
    </bean>

These beans define the request and the response queue respectively:

    <bean id="jmsRequestQueue"
                class="org.springframework.jndi.JndiObjectFactoryBean"
                abstract="false" lazy-init="default" autowire="default"
                dependency-check="default">
        <property name="jndiName">
            <value>jms/RequestQueue</value>
        </property>
        <property name="resourceRef">
            <value>false</value>
        </property>
        <property name="jndiTemplate" ref="myJndiTemplate"/>
    </bean>

     <bean id="jmsResponseQueue"
                class="org.springframework.jndi.JndiObjectFactoryBean"
                abstract="false" lazy-init="default" autowire="default"
                dependency-check="default">
        <property name="jndiName">
            <value>jms/ResponseQueue</value>
        </property>
        <property name="resourceRef">
            <value>false</value>
        </property>
        <property name="jndiTemplate" ref="myJndiTemplate"/>
    </bean>

We then customise Spring’s JmsTemplate with the beans configured above. Note that we will use JmsTemplate to send JMS messages later:   

<bean id="jmsTemplate"
        class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="jmsQueueFactory"  />
        <property name="defaultDestination" ref="jmsRequestQueue"/>
    </bean>

Last but not least, we create a Message Driven Pojo which is the WormholeActor. Note that the WormholeActor is listening to the reponse queue.


    <bean id="messageListener" class="org.azrul.osconf.jmsActors.WormholeActor" />

    <bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="jmsQueueFactory"/>
        <property name="destination" ref="jmsResponseQueue"/>
        <property name="messageListener" ref="messageListener" />
    </bean>

Next, we create a WormholeActor class in Scala

class WormholeActor extends Actor with MessageListener{
    def act:Unit = {
        loop
        {
            react
            {
                case msg:String =>
                    val context  = new ClassPathXmlApplicationContext(Array[String]("/org/azrul/osconf/jmsActors/client-context.xml"));
                    val jmsTemplate = context.getBean("jmsTemplate").asInstanceOf[JmsTemplate];

                    jmsTemplate.send(new MessageCreator() {
                            def createMessage(session:Session):Message={
                                val message =  session.createMapMessage;
                                message.setString("MESSAGE", msg);
                                return message;
                            }
                        });
            }
        }
    }

    def onMessage(message:Message):Unit={
        val responseMsg = message.asInstanceOf[MapMessage];
        println("-------From Listener------");
        println(responseMsg.getString("MESSAGE"));
    }
}

Basically it has two primary functions: act that reacts to Scala actor messages and onMessage that reacts to JMS messages. Note that when we receive a Scala message, we automatically send it to the JMS world (via our request queue created through our Spring config.)

Here is the MDB:

@MessageDriven(mappedName = "jms/RequestQueue", activationConfig = {
    @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
public class MyMDBQueueBean implements MessageListener {

    public MyMDBQueueBean() {
    }

    public void onMessage(Message message) {
        try {
            MapMessage requestMsg = (MapMessage) message;
            System.out.println("-------From MDB------");
            System.out.println(requestMsg.getString("MESSAGE"));
            System.out.println("----------------------");

            Context ctx = new InitialContext();
            ConnectionFactory connectionFactory = (ConnectionFactory) ctx.lookup("jms/QueueFactory");
            Queue queue = (Queue) ctx.lookup("jms/ResponseQueue");
            javax.jms.Connection connection = connectionFactory.createConnection();
            javax.jms.Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            MessageProducer producer = session.createProducer(queue);
            MapMessage responseMsg = session.createMapMessage();

            responseMsg.setString("MESSAGE","READ:"+requestMsg.getString("MESSAGE"));
            producer.send(responseMsg);

        } catch (NamingException ex) {
            Logger.getLogger(MyMDBQueueBean.class.getName()).log(Level.SEVERE, null, ex);
        } catch (JMSException ex) {
            Logger.getLogger(MyMDBQueueBean.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

The MDB listens to the request queue and forward any message to the response queue. Of course in your application, you may want to do some business logic between request and response. In our case, we just do this:

 

System.out.println("-------From MDB------");
System.out.println(requestMsg.getString("MESSAGE"));
System.out.println("----------------------");

 

To bootstrap it all, we need a Scala main function that will send a message to the wormhole actor:

object Main {

main(args : Array[String]) : Unit =
    {
        var wormholeActor = new WormholeActor;
        wormholeActor.start
        wormholeActor ! "I’m John Connor and if you’re listening to this you are the RESISTANCE!"

    }
}

Next, just run the MDB and run the Main object.

Note:Use Netbeans to easily create an MDB . Follow this tutorial under the topic Creating the NewMessage Message-Driven Bean

Complete source code for Actor (password: qwerty)

Dependencies:

Wednesday, June 3, 2009

OSCONF 2009: Awesomeness just got a new name!!

As if the world’s total awesomeness converged for 4 days , OSCONF was totally awesome (more awesome then some conf that starts with Tech and end with Ed). The community rocks!!

Ubuntu guys rocks!!

PHP guys (Joomla guys too) rocks!!

Sun guys rocks (although not as much, yeah yeah, I know, the Oracle thingy is probably in their mind)

Python guys rock soliidd!!

BSD guys rocks and are horny too (no no, not the other kind of horny :)) )

ADempiere guys manage to maintain their cool :P

And best of all, the lightning talks really really rock!! with total awesomeness that rocks can have :))

Everyone just plain awesome !! Yeah, everyone! Even the OpenSUSE guys. :))

Please please please make this a yearly event

Anyway, I delivered my Scala talk too. Here’s the slide

http://www.scribd.com/doc/16094125/azrulosconfkickingbuttenterprisescala

 

I’ve also done a lightning talk called Cyber Merdeka (Cyber Sovereignty)

http://www.scribd.com/doc/16094325/Cyber-Merdeka-Cyber-Sovereignity

 

I’ll make the video available if I can get it from MDeC

 

 

Me and Anthony Baxter of Google

Thursday, February 19, 2009

Unintentional user created content

A few years ago, I stumbled upon a dialog featuring Sun Microsystems' Johnathan Shwartz and a few other names (sorry too lazy to look it up).
In the dialog, one of the participants ask this question:

"Would you write a book for someone for free"

If you ask me, then my answer is no. Then come the next question.

"What about a paragraph... for free"

Well, probably,

"What about a word, just one word"

Sure.

Well, that is what Google (and Microsoft and Yahoo etc.) is doing. Google is asking all of us to write a "book". A few words a person.
This book contains the combined knowledge of all of us... well at least it contains to combined "intention" from all of us. My question is this,
are we aware that we are creating content for Google? Some of us do, most don't. This is waht I call "unintentional user created content"

Imagine now, if we have a video cam that will take movie of every aspect of our lives. Couple that video cam with a sound recorder and you can
express yourself whenever you feel like it. It will also capture your interaction with people around you. Couple that with a GPS receiver and
your location, your image, your interaction will automatically be your blog: an autoblog if you prefer.

No more messing around with computers and no more having to type things. All you have to do is ... welll ... nothing. Everything becomes a blog.
(Of course there are time when you want to shut off such device.) Now, of course all these are voluntary. Now before you dismiss this as some
fantasy I cooked up, just watch your next season American Idol. You'll see that people LOVE to put their live online. (And also, the hordes of
idiotic videos on youtube substantiate this also).

I do belive that unintentional user created content is the future. Today, we do have youtube and blogspots and twitter and whatnot, but these
"intentional" web 2.0 stuff are small fry compared to what is coming.