Saturday, May 28, 2011

Ant mail task issue in Mac

Last week I get stuck again when using the Ant mail task, based on the document from Ant site, the mail task requires the following 2 jar files:
 - mail.jar from JavaMail API 
 - activation.jar from  JAF API

I already downloaded and copied them into /usr/share/ant/lib folder, but still I got the error.
After google a while, I realized that Mac missed another jar file in its ant package, this time it is ant-javamail.jar! So when I just copied the ant-javamail.jar from the downloaded ant package into /usr/share/ant/lib folder, then every thing worked perfectly.

In summary, to make the mail task work in Mac, you need 3 jar files:
 - mail.jar
 - activation.jar
 - ant-javamail.jar

Ant target to send email example (using gmail smtp server):
<target name="sendmail" description="send email">
        <mail mailhost="smtp.gmail.com"
                  mailport="25"
                  user="${your.gmail.account}"
                  password="${your.gmail.password}"
                  ssl="true"
                from="${your.email.address}"
                tolist="${mail.recipient}"
              subject="Results of nightly build">
          <message>This is a test email</message>
       </mail>
</target>

Ant scp and sshexec task issues in Mac

Last week when I tried to run my ant target using scp and sshexec task in my macbook pro, I got the following issues:

1) scp task issue
Problem: failed to create task or type scp
Cause: the class org.apache.tools.ant.taskdefs.optional.ssh.Scp was not found.
        This looks like one of Ant's optional components.
Action: Check that the appropriate optional JAR exists in
        -/usr/share/ant/lib
        -/Users/steve/.ant/lib
        -a directory added on the command line with the -lib argument

Do not panic, this is a common problem.
The commonest cause is a missing JAR.

2) sshexec task issue
Problem: failed to create task or type sshexec
Cause: the class org.apache.tools.ant.taskdefs.optional.ssh.SSHExec was not found.
        This looks like one of Ant's optional components.
Action: Check that the appropriate optional JAR exists in
        -/usr/share/ant/lib
        -/Users/steve/.ant/lib
        -a directory added on the command line with the -lib argument

Do not panic, this is a common problem.
The commonest cause is a missing JAR.

I already download the jsch-0.1.44.jar from Jcraft,  and copied the jar file into folder /usr/share/ant/lib, and I also tried to put the jar file into different folder as the error suggested, but no help.
Finally I found this article:, it mentioned that in Mac, the ant-jsch.jar is missing! 
and when I look at the /usr/share/ant/lib folder, yes there is no ant-jsch.jar file!  So I downloaded the ant 1.8.2 from ant website, unpack it, and copy it into the /usr/share/ant/lib folder, it just works!

In summary, to make the ant scp and sshexec task work in Mac, you need to do 2 things:
  1. Install ant-jsch.jar file: download the ant package from ant website, then copy the ant-jsch.jar into /usr/shar/ant/lib folder
  2. Go to Jcraft website, download the latest version of jsch jar file, copy it into /usr/share/ant/lib

Saturday, May 21, 2011

Handling incoming call interruption in BlackBerry audio player

Last week I spent two days to fix an issue of blackberry audio player: the audio stream need to pause the player during incoming call interruption, and resume when call is finished.
At the beginning, I feel it is easy to fix, because I fixed this kind of issue many times before for blackberry platform.
So I just program based on my old experiences, but it did not working.

My Mistake
At first I use BlackBerry API PhoneListener to register the call interruption event. But it did not work, I found some issues:
- If you use PhoneListener, the application will prompt use to agree to use Phone API, which is annoying.
- When you delete the application, you have to restart the phone.
- The application can get the incoming call event via callIncoming() method, but some time the application get exception;
- The application get the call end event via callDisconnected() method, but when you call MMAPI player play() method, it always throws MediaException.
  It seems the application the the event earlier than the voice call app release the resource.
- I found the Phone already stop the media player before it send the incoming call event the the application, so you have to use a workaround to deal with this issue.
I tried the different workarounds, but none of them working, it seems the PhoneListener solution is not reliable, and even not working. I don't remember why it works before.
maybe because of current phone is 5.0 while before are 4.3 or 4.6? Actually I don't know.

New solution
After I googled and I found a really simple solution: handle the DEVICE_AVAILABLE and DEVICE_UNAVAILABLE event in the playerListener. Based on this article:
The DEVICE_UNAVAILABLE event occurs when there is an incoming call. The DEVICE_AVAILABLE event occurs when the call is ended.
So all you need to do is pause the player in DEVICE_UNAVAILABLE, and resume when DEVICE_AVAILABLE event comes.
Code snippet like this:
playerUpdate(Player player, String event, Object eventData) 
{
    ...

    if(event == PlayerListener.DEVICE_UNAVAILABLE)
    {
        if(player.getState() == Player.STARTED)
        {
              player.stop();
              bPausedByIncomingCall = true;
        } 
    }
    else if(event == PlayerListener.DEVICE_AVAILABLE)
    { 
        if(bPausedByIncomingCall)
        {
            player.start();
            bPausedByIncomingCall = false;
        }

    }

   ...
}
The solution is very easy and it really works. I tested it when the DEVICE_UNAVAILABLE event comes, the player is still playing, which means the event is sent before the incoming call interruption.

Retrospection
I checked the MMAPI API and Blackberry API document, I found this event is not new (Blackberry support this since 4.0!), but I did not notice this until now. Why I did not notice these two events before? I did not find them in the books, nor I did not heard from them from previous colleagues. This is my another blind spot and it exposed my ignorance of MMAPI. This issue tells me: sometime your old experience is unreliable; you still need to empty your mind, like Andy Hunt said: always have beginner's mind!

Saturday, May 7, 2011

Functional programming in OO languages

Yesterday I watch the presentation: Functional Programming: A Pragmatic Introduction in Infoq.com. Jim Duey explains functional programming through Java code samples. He covers 3 parts:
  •  high order functions
  •  laziness
  •  composing
I am more interested in the first part - high order functions. Jim shows 3 important functions:
      reduce, filter and map.
Comparing with the java code, Jim describes how these 3 methods can help us reduce the duplicated boilerplate java code: like loop, iteration. He even emphasizes that these 3 methods - reduce, filter and map can reduce 90% of the loop code!  
Copied from his slide, the benefits of the high order functions are:
  •   Allows common code structures to reused 
  •   Abstracts away details 
  •   Isolates the essential parts of the code 
  •   Allows easier unit testing
  •   Lets you think at a higher level 
  •   Allows easy parallelism
If you don't want to watch the video, then I found this article is really great to explain the map, filter and reduce method, also gives Java implementation.
As a java developer, the implementation code is not new to me, mostly the template method pattern is used. Actually I already saw the similar benefit in Spring framework: it is so amazing the JdbcTemplate can removed lots of the JDBC boilerplate code! But I did not aware that it shares the same idea with the function programming.
Since I learned that high order functions are so important, so I decide to investigate more and see how to implement them in other OO languages beside Java.

Javascript
Joel has a nice article about function programming using javascript: Can Your Programming Language Do This?

Groovy
I checked the Groovy API and recalled what I learned before, so I found the equivalent methods for reduce, filter and map in Collection API are:
   reduce  => inject()
   filter  => findAll()
   map     => collect()

Groovy functional programming link

Ruby
Groovy is very similar with Ruby, especially when I learned Groovy, I suspect if Groovy copies some concept from Ruby, since the collection API is so similar.
      reduce  => reduce(), inject()
      map     => map(), collect()
      filter    => select(), find_all()

This article is really great to explain them more in Ruby

Other resources
Why functional programming matters

Conclusion
- To use functional programming, it would be better to use the language that support functional programming in first class. I have to say Java implementation is too ugly, Groovy and Ruby are much better.
- Changing mindset to functional programming is hard but really important. Functional programming is another way of programming to elevate your abstraction layer.

Next Action
To pursue the way of Functional Programming, you need to pick up a new Functional Programming language ASAP, since I learned LISP through SICP, so Clojure would be my next choice.