JavaME: Google Static Maps API

Whether you need a map for your location based application or just for fun, you can use the easiest way ever: Google Static Maps API. In this post, we are going to see how you can get a Map as an Image from a latitude and longitude point. The latitude and longitude can be obtained using Location API which we won’t discuss in this post.


When writing this post, I realized there is some license restrictions in the use of Google Static Maps API in mobile Apps… I am posting it anyway just for research purposes, but I must warn you about this restriction:

 


http://code.google.com/intl/en/apis/maps/faq.html#mapsformobile

Google Static Maps API Quick Review


 

This API lets you get an Image based on a URL and several parameters you can pass in to obtain a personalized map. You can play with the zoom, type of map, size of the image (width, height), markers at locations of the map, etc. There is a limit you have to keep in mind, the use of the API is subject to a query limit of 1000 unique (different) image requests per viewer per day, which is a lot of images… but if you need more, there is also a Premium license. For more information:

http://code.google.com/intl/en/apis/maps/documentation/staticmaps/

OK, what we do is the following:

  • Create a method that receives a latitude and longitude point and the size of the image as parameters.
  • Request the map image using the URL: http://maps.googleapis.com/maps/api/staticmap, and adding some parameters.
  • Create an Image object and return it, so we can show it on screen.


Hands on Lab

Following is the method we were talking about. It has parameters for the latitude and longitude, and also for the width and height of the image we are requesting. The latitude and longitude can be retrieved using Location API, and the width and height can be retrieved using the Canvas class.

public Image getMap(double lat, double lon, int width, int height) 
throws IOException 
{
    String url = "http://maps.google.com/maps/api/staticmap";
    url += "?zoom=15&size=" + width + "x" + height;
    url += "&maptype=roadmap";
    url += "&markers=color:red|label:A|" + lat + "," + lon;
    url += "&sensor=true";

    HttpConnection http = (HttpConnection) Connector.open(url);
    InputStream in = null;
    byte[] imgBytes = null;
    try {
        http.setRequestMethod(HttpConnection.GET);
        in = http.openInputStream();

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int n = 0;
        while ((n = in.read(buffer)) != -1) {
            bos.write(buffer, 0, n);
        }
        imgBytes = bos.toByteArray();
    } finally {
        if (in != null) {
            in.close();
        }
        http.close();
    }
    Image img = Image.createImage(imgBytes, 0, imgBytes.length);

    return img;
}

As you may see, it is pretty simple to get the image of the map. The retrieving is pure HTTP request.

Next you can find an image retrieved by Google Static Maps from a location in my home town.

OK, you just saw how simply it would be if no restriction exists… What do you think about that restriction? It’s kind of confusing, isn’t it?

Anyway, we are going to need to find another way to show maps on our mobile apps.


Reference:
Google Static Maps API and JavaME from our
JCG partner Alexis Lopez at the
Java and ME blog.

Source : http://www.javacodegeeks.com/2012/05/javame-google-static-maps-api.html

Complete Guide To Deploy Java Web Application in Amazon Ec2 using Eclipse

Hi readers,
Today I’m going to show you how to deploy simple java web application in amazon ec2 using Eclipse IDE.

Before we begin we need some required things,
OK, lets start, here we go….

Step 1
  • First you have to install the AWS toolkit for eclipse plugin. Simply go to Help–> Eclipse Market Place –> Search Amazon
  • You will get the AWS toolkit for eclipse .
  • Click Install
  • It will show the corresponding packages and after agree the license will install it. Just a simple procedure.


Step 2
  • Windows –> Preferences –> select AWS Toolkit and Fill the fields according to your amazon ec2 account
  • Give your name to Account Name (Not Necessary), but give exact value to Access Key ID and Secret Access Key according to your amazon acc.
  • In the optional configuration (Expand it) give account id (exact value) to that field.


Step 3
  • Windows –> Show view –> Other –> Select AWS toolkit view (Select all views) –> OK
  • Now you can see the perspective view of aws.


Step 4
  • Now the configuration part is over.
  • Lets create a Amazon ec2 server. To do that File –> New –> Other –> Server –> server –> select amazon ec2 or amazon elastic server tomcat version 6 (you can either choose tomcat version 7)
  • Fill the fields and Finish. (Hope you have some basic understand about eclipse)                                       



Step 5
  • Now create a Dynamic Web project. File –> New –> Other -> Web –> Dynamic Web Project
  • Give whatever name you like.
  • Choose AWS Ec2 or Elastic runtime as a target runtime.
  • Click Finish



Step 6
  • Now create a servlet and Finish
  • Change the doGet() in servlet (Only for demo. This is where your code goesssss)



Step 7
  • Right click Servlet –> Run as –> Run On server –> Select the server you above create and Finish.


Step 8
  • Eclipse will automatically open the web page that you created. (Or in server tab right click the server and select amazon web service –> running)


Thats it…..
Just a simple procedure but you can expand this in your war… its up to you.


Source : http://www.javacodegeeks.com/2012/05/complete-guide-to-deploy-java-web.html

Building security into a development team

Getting application developers to understand and take responsibility for software security is difficult. Bootstrapping an Appsec program requires that you get the team up to speed quickly on security risks and what problems they need to look for, how to find and fix and prevent these problems, what tools to use, and convince them that they need to take security seriously. One way to do this is to train everyone on the development team on software security.

But at RSA 2011, Caleb Sima’s presentation
Don’t Teach Developers Security challenged the idea that training application developers on software security will make a meaningful difference. He points out (rightly) that you can’t teach most developers anything useful about secure software development in a few hours (which as much Appsec training as most developers will get anyways). At best training like this is a long-term investment that will only pay off with reinforcement and experience – the first step on a long road.

Most developers (he suggests as many as 90 out of 100) won’t take a strong interest in software security regardless. They are there to build stuff, that’s what they get paid for, that’s what they care about and that’s what they do best. Customers love them and managers (like me) love them too because they deliver, and that’s what we want them spending their time doing. We don’t want or need them to become AppSec experts. Only a few senior, experienced developers will “get” software security and understand or care about all of the details, and in most cases this is enough. The rest of the team can focus on
writing good defensive code and using the right frameworks and libraries properly.

Caleb Sima recommends starting an Appsec program by working with QA. Get an application security assessment: a pen test or a scan to identify security vulnerabilities in the app. Identify the top 2 security issues found. Then train the test team on these issues, what they look like, how to test for them, what tools to use. It’s not practical to expect a software tester to become a pen testing expert, but they can definitely learn how to effectively test for specific security issues. When they find security problems they enter them as bugs like any other bug, and then it’s up to development to fix the bugs.

Get some wins this way first. Then extend security into the development team. Assign one person as a security controller for each application: a senior developer who understands the code and who has the technical skills and experience to take on security problems. Give them extra Appsec training and the chance to play a leadership role. It’s their job to assess technical risks for security issues. They decide on what tools the team will use to test for security problems, recommend libraries and frameworks for the team to use, and help the rest of the team to write secure code.

What worked for us

Looking back on what worked for our Appsec program, we learned similar lessons and took some of the same steps.

While we were still in startup, I asked one of our senior developers to run an internal security assessment and make sure that our app was built in a secure way. I gave him extra time to learn about secure development and Appsec, and gave him a chance to take on a leadership role for the team. When we brought expert consultants in to do additional assessments (a secure design review and code review and pen testing) he took the lead on working with them and made sure that he understood what they were doing and what they found and what we needed to do about it. He selected a static analysis tool and got people to use it. He ensured that our framework code was secure and used properly, and he reviewed the rest of the team’s code for security and reliability problems. Security wasn’t his entire job, but it was an important part of what he did. When he eventually left the team, another senior developer took on this role.

Most development teams have at least 1 developer who the rest of the team respects and looks to for help on how to use the language and platform correctly. Someone who cares about how to write good code and who is willing to help others with tough coding problems and troubleshooting. Who handles the heavy lifting on frameworks or performance engineering work. This is the developer that you need to take on your core security work. Someone who likes to learn about technical stuff and who picks new things up quickly, who understands and likes hard technical stuff (like crypto and session management), who makes sure that things get done right.

Without knowing it we ended up following a model similar to Adobe’s “
security ninja” program, although on a micro-scale. Most developers on the team are white belts or yellow belts with some training in secure software development and defensive programming. Our security lead is the black belt, with deeper technical experience and extra training and responsibility for leading software security for the application. Although we depended on external consultants for the initial assessments and to help us lay out a secure development roadmap, we have been able to take responsibility for secure development into the development team. Security is a part of what they do and how they design and build software today.

This model works and it scales. If as a manager you look at security as an important and fundamental technical problem that needs to be solved (rather than a pain-in-the-ass that needs to be gotten over), then you will find that your senior technical people will take it seriously. And if your best technical people take security seriously, then the rest of the team will too.



Source : http://www.javacodegeeks.com/2012/05/building-security-into-development-team.html

Troubleshooting Play Framework 2 apps on Openshift

Troubleshooting Openshift


 

With the
do-it-yourself application type you really get a lot of freedom to support almost any framework or server that can be built and run on a linux box. But you do have to make your homework, and do some research. 

So in this article I’ll show you a couple of tips I learnt playing around with
Openshift and
Play Framework


Comments are more than welcome, so I hope you can also provide me some more tips to help us all get our apps running on the cloud. 

Providing native support for play framework application
 
Right now, the solution we found for
deploying Play 2.0 apps on openshift is quite handy, but we could make it a little better..

The problem is that we have to compile the app locally (issuing
play stage) and then push 30 MB of libraries to Openshift. The ideal thing, and that’s what we did with the
Play 1.x quickstart and with the latest version of
Openshift module for Play Framework 1.x, would be to just upload our sources and then let Openshift download and install Play, compile our app, and start it. 

Unfortunately we’ve ran with some memory constraints (seems like compiling Play 2 apps is a bit memory demanding) that eventually raised some issues. We are trying to work them out, but perhaps, with this tips, you could help has troubleshoot it. 

With the
opensourcing of Openshift and the new
Origin livecd we have more tools available for us to further investigate what’s going on, I just didn’t have time yet to start playing with it. 

So, enought chatter, and let’s get our hands dirty. 

Houston, we have a problem
 
All right, you’ve just read
this guide or followed our steps on the
Play Framework webinar using this
Play 2.0 quickstart (in fact, some of this tips will help trouble shoot any app running on Openshift) and something went wrong. 

First of all, have a look at the logs. Just issue
rhc app tail -a myapp -l mylogin@openshift.com -p mysecretpass

Leave that window open, it will become quite handy later. 

Then we’ll ssh into our remote machine. Just issue:
rhc app show -a myapp -l mylogin@openshift.com -p mysecretpass

and you’ll get something like
Application Info
================
contacts
    Framework: diy-0.1
     Creation: 2012-04-19T14:20:16-04:00
         UUID: 0b542570e41b42e5ac2a255c316871bc
      Git URL: ssh://0b542570e41b42e5ac2a255c316871bc@myapp-mylogin.rhcloud.com/~/git/myapp.git/
   Public URL: http://myapp-mylogin.rhcloud.com/

 Embedded: 
      None

Take the part after the ssh of the Git URL stuff, and log into you openshift machine:
ssh 96e487d1d4a042f8833efc696604f1e7@myapp-mylogin.rhcloud.com

(If you are lazy like me, go on and vote for
an easier way to ssh into openshift

It’s also a good idea to open another command window, ssh into openshift, and run something like “top” or “watch -n 2 free -m” to keep an eye on memory usage. 

Troubleshooting Play
 
You know the old motto, “write once, run everywhere”… well it just
“should” work, but just in case you could try compiling your app with the same JDK version as the one running on openshift. 

Just run
java -version
java version "1.6.0_22"
OpenJDK Runtime Environment (IcedTea6 1.10.6) (rhel-1.43.1.10.6.el6_2-i386)
OpenJDK Server VM (build 20.0-b11, mixed mode)

And install the same jdk version on your box. Then compile your app and redeploy (you can use the convenience script
openshift_deploy

If that doesn’t work, try to do the whole process manually on Openshift. You should do something like this:
# download play
cd ${OPENSHIFT_DATA_DIR} 
curl -o play-2.0.1.zip http://download.playframework.org/releases/play-2.0.1.zip
unzip play-2.0.1.zip
cd ${OPENSHIFT_REPO_DIR}

#stop app
.openshift/action_hooks/stop

#clean everything - watch for errors, if it fails retry a couple more times
${OPENSHIFT_DATA_DIR}play-2.0.1/play clean 

if you get something like:
/var/lib/stickshift/0b542570e41b42e5ac2a255c316871bc/myapp/data/play-2.0.1/framework/build: line 11: 27439 Killed 

It means it failed miserably (that’s the memory problem I told you about) 

And it’s such a bad tempered error that you’ll also loose you command prompt. Just blindily type “reset” and hit enter, you’ll get your prompt back. 

And then just try again… 

You might also get this message:
This project uses Play 2.0!
Update the Play sbt-plugin version to 2.0.1 (usually in project/plugins.sbt)

That means you created the app with Play 2.0 and you are now trying to compile it with a different version. 

Just update project/plugins.sbt file or download the appropiate version. 

Now compile and stage your app.
#compile everything - watch for errors, if it fails retry a couple more times
${OPENSHIFT_DATA_DIR}play-2.0.1/play compile

#stage - watch for errors, if it fails retry a couple more times
${OPENSHIFT_DATA_DIR}play-2.0.1/play stage

Then run it (don’t be shy and have a look at the
action hooks scripts on the quickstart repo).
target/start -Dhttp.port=8080 -Dhttp.address=${OPENSHIFT_INTERNAL_IP} -Dconfig.resource=openshift.conf


If everything works ok, just stop it with ctrl-c, and then run:
.openshift/action_hooks/start

You should see your app starting in the console with the logs files 

Now you can log out from the ssh session with ctrl-d, and issue:
rhc app restart -a myapp -l mylogin@openshift.com -p mysecretpass

and you should see something like
Stopping play application
Trying to kill proccess, attempt number 1
kill -SIGTERM 19128
/var/lib/stickshift/0b542570e41b42e5ac2a255c316871bc/openbafici/repo/target/start "-DapplyEvolutions.default=true" -Dhttp.port=8080 -Dhttp.address=127.11.189.129 -Dconfig.resource=openshift.conf
Play server process ID is 21226
[info] play - Application started (Prod)
[info] play - Listening for HTTP on port 8080...


I hope this tips will become useful. As I told, I’m looking forward to start playing with the Openshift Origin livecd, and then I’ll tell you about. 

In the meantime I’ll leave you with the company of the good old Openshift Rocket Bear, I know you miss him too, so why not
get him back?


Source : http://www.javacodegeeks.com/2012/05/troubleshooting-play-framework-2-apps.html

Java Memcached on Mac OS X

Introduction

In this article I will explain how you can:

  1. Install and Configure Memcached on Mac OS X
  2. Use Memcached in your Java Application

I won’t go in too much detail about the benefits of using a distributed cache in your applications, but let’s at least provide some use cases for applications that are running in the context of an enterprise portal, eXo Platform in my case –
surprising isn’t? And I will show this in another post.

We have many reasons to use a cache (distributed or not), in the context of enterprise portal, let’s take a look to some of these reasons:

  • A portal is used to aggregate data in a single page. These data could come from different sources : Web Services, Database, ERP, ….. and accessing the data in real time could be costly. So it will be quite interesting to cache the result of the call when possible.
  • If the portal is used to aggregate many data from many sources, it is sometime necessary to jump into another application to continue some operation. A distributed and shared cache could be used to manage some context between different applications running in different processes (JVM or even technologies)

These are two example where a shared cache could be interesting for your portal based applications, we can find many other reason.

Note that the Portlet API (JSR-286) contains already a cache mechanism that cache the HTML fragment, and that eXo Platform also provide a
low level cache, based on
JBoss Cache.

Installation and Configuration

Installing Memcached from sources

You can find some information about Memcached installation on the Memcached
Wiki. The following steps are the steps that I have used on my environment.

As far as I know, Memached is not available as package for Mac OS X. I am still on Snow Leopard (10.6.8), and I have installed XCode and all development tools. I have use the article "Installing memcached 1.4.1 on Mac OS X 10.6 Snow Leopard" from
wincent.com. For simplicity reason I have duplicate the content and updated to the latest releases.

1. Create a working directory :

$ mkdir memcachedbuild
$ cd memcachebuild

2.Install
libevent that is mandatory for memcached

$ curl -O http://www.monkey.org/~provos/libevent-1.4.14-stable.tar.gz
$ tar xzvf libevent-1.4.14-stable.tar.gz
$ cd libevent-1.4.14-stable
$ ./configure
$ make
$ make verify
$ sudo make install 

3. Install memcached

Go back to your install directory (
memcachedbuild)

$ curl -O http://memcached.googlecode.com/files/memcached-1.4.10.tar.gz
$ tar xzvf memcached-1.4.10.tar.gz
$ cd memcached-1.4.10
$ ./configure
$ make
$ make test
$ sudo make install 

You are now ready to use memcached that is available at /usr/local/bin/memcached

This allows you to avoid changing to the pre-installed memcached located in /usr/bin, if you want to replace it instead of having you own install, just run the configure command with the following parameter: ./configure –prefix=/usr

Starting and testing Memcached

Start the memcached server, using the following command line:

$ /usr/local/bin/memcached -d -p 11211

This command starts the memcached server as demon (-d parameter), on the TCP port 11211 (this is the default value). You can find more about the memcached command using man memcached.

It is possible to connect and test your server using a telnet connection. Once connected you can set and get object in the cache, take a look to the following paragraph.

$ telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to tgrall-server.
Escape character is '^]'.
set KEY 0 600 16
This is my value
STORED
get KEY
VALUE KEY 0 16
This is my value
END

The set command allows you to put a new value in the cache using the following syntax:

set <key> <flags> <expiration_time> <number_of_bytes> [noreply] \n\n

<value>
  • key : the key used to store the data in the cache
  • flags : a 32 bits unsigned integer that memcached stored with the data
  • expiration_time : expiration time in seconds, if you put 0 this means no delay
  • number_if_bytes : number of bytes in the data block
  • noreply : option to tell the server to not return any value
  • value : the value to store and associate to the key.

This is a short view of the documentation located in your source directory /memcachedbuild/memcached-1.4.10/doc/protocol.txt .

The get command allows you to access the value that is associated with the key.

You can check the version of memcahed you are running by calling the stats command in your telnet session.

Your memcached server is up and running, you can now start to use it inside your applications.

Simple Java Application with Memcached

The easiest way to use memcached from your Java applications is to use a client library. You can find many
client libraries. In this example I am using
spymemcached developped by the people from
Couchbase.

1. Adding SpyMemcached to your Maven project

Add the repository to you pom.xml (or you setting.xml)

<repository>
    <id>spy</id>
    <name>Spy Repository</name>
    <layout>default</layout>
    <url>http://files.couchbase.com/maven2/</url>
</repository>

then the dependency to your pom.xml

<dependency>
    <groupid>spy</groupid>
    <artifactid>spymemcached</artifactid>
    <version>2.7.3</version>
</dependency>

2. Use SpyMemcache client in your application

The following code is a simple Java class that allows you to enter the key and the value and set it in the cache.

package com.grallandco.blog;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Console;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.spy.memcached.AddrUtil;
import net.spy.memcached.MemcachedClient;

public class Test {

    public static void main(String[] args) {
       try {
           
           System.out.print("Enter the new key : ");
           BufferedReader reader = new BufferedReader( new InputStreamReader(System.in));
           String key = null;
           key = reader.readLine();
           
           System.out.print("Enter the new value : ");
           String value = null;
           value = reader.readLine();
           
            MemcachedClient cache = new MemcachedClient(AddrUtil.getAddresses("127.0.0.1:11211"));
            
            // read the object from memory
            System.out.println("Get Object before set :"+ cache.get(key)  );

            // set a new object            
            cache.set(key, 0, value );

            System.out.println("Get Object after set :"+ cache.get(key)  );
            

        } catch (IOException ex) {
            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
            System.exit(0);
        }

       
        System.exit(0);
       
    }
}

So when executing the application you will see something like :

Enter the new key : CITY
Enter the new value : Paris, France
2011-11-16 15:22:09.928 INFO net.spy.memcached.MemcachedConnection:  Added {QA sa=/127.0.0.1:11211, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0} to connect queue
2011-11-16 15:22:09.932 INFO net.spy.memcached.MemcachedConnection:  Connection state changed for sun.nio.ch.SelectionKeyImpl@5b40c281
Get Object before set :null
Get Object after set :Paris, France

You can also access the object from a Telnet session:

get CITY
VALUE CITY 0 13
Paris, France
END

You can use any Java class in your application, the only thing to do is to make this class serializable.

This is it for the first post about memcached and Java, I am currently working on a small example integrating Web Services call, Portlets and memcached.


Reference:
Installing Memcached on Mac OS X and using it in Java from our
JCG partner Tugdual Grall at the
Tug’s Blog blog.

Source : http://www.javacodegeeks.com/2012/05/java-memcached-on-mac-os-x.html

Android Broadcast Receiver – Change in flow since API 3.1

Prior to API 3.1 we could have a broadcast receiver which could have been invoked by an implicit intent even if the application to which it belonged was in stopped state.

But this posed a security threat. Hence Google made it mandatory that for any broadcast receiver to receive an intent, there should be an activity and the application should not be in stopped state. Here is the
link for further reading.

When an application is launched, it is in stopped state and hence it mandates the user to activate the application which has the broadcast receiver. If the application is force stopped by the user, then again the broadcast receiver fails to receive the intent. Hence apk having only broadcast receiver and developed on version prior to 3.1 will no longer work for later versions.

However one can make use of
FLAG_INCLUDE_STOPPED_PACKAGES to activate components in stopped application. This will not require creation of another activity in order to use the broadcast receiver.

Intent intent = new Intent("com.custom.intent"); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); 
this.sendBroadcast(intent);

The other way as I had mentioned earlier would be to write an activity which may or may not be a launcher activity.

 
PackageManager pm = getPackageManager(); 
Intent appStartIntent = 
pm.getLaunchIntentForPackage("com.your.broadcast.receiver.package");
if (null != appStartIntent)
{ 
     startActivity(appStartIntent);
}

If it is not a launcher app, then you need to mention the the category as
INFO in the intent-filter in the manifest file of the broadcast receiver.

 
<application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" 
        android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" <
       <activity
            android:name=".InvokedActivity"
            android:label="@string/app_name"<
            <intent-filter<
                <action android:name="android.intent.action.MAIN" /<                         
               <category android:name="android.intent.category.INFO" / <
<-- If the activity is a launcher then mention this instead 
             <category android:name="android.intent.category.LAUNCHER" /
                             < --<

             </intent-filter <
        </activity <
       <receiver android:name=".TestBroadCastReceiver" <
           <intent-filter <
           <action android:name="com.custom.intent" <
          </action <
        </intent-filter <
       </receiver <
<application <
    

Here is the code for BroadCastReceiver:

public class TestBroadCastReceiver extends BroadcastReceiver { 
 
    private static final String CUSTOM_INTENT = "com.custom.intent";
    
    public void onReceive(Context context, Intent intent) {
         if (intent.getAction().equals(CUSTOM_INTENT)) {
              //your code here 
         } 
    }
} 

The code for InvokedActivity:


 public class InvokedActivity extends Activity { 
      
       public void onCreate(Bundle b) { 
             super.onCreate(b); 
             /*Toast.makeText(this, "starting xyz receiver...blah blah :)", Toast.LENGTH_LONG) .show();*/
             finish();
      } 
}
  
  

Reference:
Broadcast receiver – a change in flow since API 3.1 from our
JCG partner Ashimita Adusumilli at the
My small world of Android blog.

Source : http://www.javacodegeeks.com/2012/05/android-broadcast-receiver-change-in.html

Binary websockets with Play 2.0 and Scala

In a recent
article I showed how you can use webrtc, canvas and websockets together to create a face detection application whose frontend runs completely in the browser, without the need for plugins. In that article I used a Jetty based backend to handle the image analysis using OpenCV through the JavaCV wrapper.

When I almost finished the article, I noticed that websockets is also supported from Play 2.0. I really like developping in Play and in Scala so as an experiment I rewrote the backend part from a Jetty/Java/JavaCV stack to a Play2.0/Scala/JavaCV stack. If you want to do this for yourself, make sure you start with the frontend code from
here. Since the frontend code hasn’t changed except the location where the websockets are listening.

Setting up the Play 2.0 environment

I’m not going to talk too much about how to start a Play 2.0/Scala project. you can find the details in some of my other posts should you need more information. What we do need to do, is setup the dependencies for JavaCV so that they can be used from Play 2. I’ve manually added them to my local ivy repository, so that I can reference them from the sbt configuration like any other dependency. For my example I created the following directory layout for the JavaCV libraries:

./play-2.0-RC2/repository/cache/javacv
./play-2.0-RC2/repository/cache/javacv/javacpp
./play-2.0-RC2/repository/cache/javacv/javacpp/ivy-2.3.1.xml
./play-2.0-RC2/repository/cache/javacv/javacpp/ivydata-2.3.1.properties
./play-2.0-RC2/repository/cache/javacv/javacv
./play-2.0-RC2/repository/cache/javacv/javacv/ivy-2.3.1.xml
./play-2.0-RC2/repository/cache/javacv/javacv/ivydata-2.3.1.properties
./play-2.0-RC2/repository/cache/javacv/javacv-macosx-x86_64
./play-2.0-RC2/repository/cache/javacv/javacv-macosx-x86_64/ivy-2.3.1.xml
./play-2.0-RC2/repository/cache/javacv/javacv-macosx-x86_64/ivydata-2.3.1.properties
./play-2.0-RC2/repository/local/javacv
./play-2.0-RC2/repository/local/javacv/javacpp
./play-2.0-RC2/repository/local/javacv/javacpp/2.3.1
./play-2.0-RC2/repository/local/javacv/javacpp/2.3.1/ivys
./play-2.0-RC2/repository/local/javacv/javacpp/2.3.1/ivys/ivy.xml
./play-2.0-RC2/repository/local/javacv/javacpp/2.3.1/jars
./play-2.0-RC2/repository/local/javacv/javacpp/2.3.1/jars/javacpp.jar
./play-2.0-RC2/repository/local/javacv/javacv
./play-2.0-RC2/repository/local/javacv/javacv/2.3.1
./play-2.0-RC2/repository/local/javacv/javacv/2.3.1/ivys
./play-2.0-RC2/repository/local/javacv/javacv/2.3.1/ivys/ivy.xml
./play-2.0-RC2/repository/local/javacv/javacv/2.3.1/jars
./play-2.0-RC2/repository/local/javacv/javacv/2.3.1/jars/javacv.jar
./play-2.0-RC2/repository/local/javacv/javacv-macosx-x86_64
./play-2.0-RC2/repository/local/javacv/javacv-macosx-x86_64/2.3.1
./play-2.0-RC2/repository/local/javacv/javacv-macosx-x86_64/2.3.1/ivys
./play-2.0-RC2/repository/local/javacv/javacv-macosx-x86_64/2.3.1/ivys/ivy.xml
./play-2.0-RC2/repository/local/javacv/javacv-macosx-x86_64/2.3.1/jars
./play-2.0-RC2/repository/local/javacv/javacv-macosx-x86_64/2.3.1/jars/javacv-macosx-x86_64.jar

As you can see from this listing, I just added the three javacv supplied jars to my local repository. I also added a minimal ivy.xml so that they can be used from ivy and sbt. This minimal ivy.xml looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="2.0" xmlns:m="http://ant.apache.org/ivy/maven">
    <info
        organisation="javacv"
        module="javacv-macosx-x86_64"
        revision="2.3.1"
        status="release">
        </info>

        <publications>
            <artifact type="jar"/>
        </publications>
</ivy-module>

With these files added to my repository I can setup the dependencies for the Play 2.0 project in the Build.scala file.

import sbt._
import Keys._
import PlayProject._

object ApplicationBuild extends Build {

    val appName         = "PlayWebsocketJavaCV"
    val appVersion      = "1.0-SNAPSHOT"

    val appDependencies = Seq(
      "javacv" % "javacv" % "2.3.1",
      "javacv" % "javacpp" % "2.3.1",
      "javacv" % "javacv-macosx-x86_64" % "2.3.1"
    )

    val main = PlayProject(appName, appVersion, appDependencies, mainLang = SCALA).settings(
      // Add your own project settings here      
    )
}

Now run "play update" and "play eclipsify" to update the dependencies and your Eclipse configuation (if you’re using Eclipse that is).

Configure websockets in Play

Using websockets in Play 2.0 is very easy. The first thing you need to do is add the URL to your routes configuration in the conf directory.

GET     /wsrequest                  controllers.Application.wsrequest

And, of course, you need to implement the action this route points to:

/**
 * Simple websocket listener configured in play 2. This uses a synchronous model, where
 * the same channel is used to send the response. For this usecase this is useful, if
 * we want async processing we could have used Akka actors together with play 2.0 async
 * support.
 */
def wsrequest = WebSocket.using[Array[Byte]] { request =>

  // Create the outbound value that is called for each
  val out = Enumerator.imperative[Array[Byte]]();

 val in = Iteratee.foreach[Array[Byte]](content => {
    out.push(FaceDetect.detect(content));
  })

  // tie the in and out values to each other
  (in, out)
}

In this code we configure an input channel (in), and an output channel (out) and connect them to the socket. Whenever the HTML5 client sends a request over the websocket our "in" method is called, and when we want to send something to the client we can use the "out" channel. The "in" channel needs to be defined as an Iteratee (more info see
these Play docs). What this does is, that for each input message we receive we run the specifici method. In this case we run the FaceDetect.detect operation (more on this later) and the result from this operation is pushed back to the client using the "out" channel. This "out" channel itself is defined as an Enumerator (see
these play docs). We can attach different listeners if we want to this enumerator, but in this case we don’t do anything with the message, just pass it along to the client.

Using JavaCV from scala

The last step is the code of the FaceDetect.detect function. The java version, see earlier mentioned
article, is very easily converted to a scala one.

package javacv

import com.googlecode.javacv.cpp.opencv_core._
import com.googlecode.javacv.cpp.opencv_imgproc._
import com.googlecode.javacv.cpp.opencv_highgui._
import com.googlecode.javacv.cpp.opencv_objdetect._
import com.googlecode.javacpp.BytePointer
import java.nio.ByteBuffer
import javax.imageio.ImageIO
import java.io.ByteArrayOutputStream
import scala.tools.nsc.io.VirtualFile

object FaceDetect {

 var CASCADE_FILE =PATH_TO_CASCADE_FILE;
   var minsize = 20;
 var group = 0;
 var scale = 1.1;

  def detect(imageData:Array[Byte]) : Array[Byte] = {

    // we need to wrap the input array, since BytePointer doesn't accept
    // a bytearray as input. It accepts a byte varargs, but Array[Byte]
    // doesn't convert automatically
    var wrappedData = ByteBuffer.wrap(imageData);
    var originalImage = cvDecodeImage(cvMat(1, imageData.length,CV_8UC1, new BytePointer(wrappedData)));

    // convert to grayscale for easy detection
    var grayImage = IplImage.create(originalImage.width(), originalImage.height(), IPL_DEPTH_8U, 1);
    cvCvtColor(originalImage, grayImage, CV_BGR2GRAY);

    // storage is needed to store information during detection
 var storage = CvMemStorage.create();

 // load and run the cascade
 var cascade = new CvHaarClassifierCascade(cvLoad(CASCADE_FILE));
 var faces = cvHaarDetectObjects(grayImage, cascade, storage, scale, group, minsize);

 // draw a rectangle for the detected faces
 for (i <- 0 until faces.total) {
   var r = new CvRect(cvGetSeqElem(faces, i));
   cvRectangle(originalImage, cvPoint(r.x, r.y),
     cvPoint(r.x + r.width(), r.y + r.height),
     CvScalar.YELLOW, 1, CV_AA, 0);
 }

 // convert to bytearray and return
 var bout = new ByteArrayOutputStream();
 var imgb = originalImage.getBufferedImage();
 ImageIO.write(imgb, "png", bout);

    bout.toByteArray()
  }
}

The only issue I ran into was with the BytePointer constructor. One of the signatures accepts a varargs of the type byte. In java this allows me to just supply this constructor with a byte[], in Scala however this doesn’t work. Luckily though, a BytePointer can also be created using a ByteBuffer. For the rest this is a one-to-one conversion of Java to Scala.

Running the code

And that’s almost it. By default play listens on port 9000, in the Jetty based example we had the server running on 9999 and listening to the root context. To work with our Play2/Scala based server we just need to point the browser to the correct websocket server url.

 ws = new WebSocket("ws://127.0.0.1:9000/wsrequest");

And now, when we run it, we use Play 2 as our server and run the JavaCV code using scal. And more importantly it still works:


Reference:
Binary websockets with Play 2.0 and Scala (and a bit op JavaCV/OpenCV) from our
JCG partner Jos Dirksen at the
Smart Java blog.

Source : http://www.javacodegeeks.com/2012/05/binary-websockets-with-play-20-and.html