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