Git: “git pull” vs “git pull -rebase”, a cleaner way to pull

I have been using GIT for my personal projects for a while and I absolutely “LOVE IT”. One of the many reasons is that, I could simply create a project and just do a “git init” to have a full fledged  version control for my code! I did not have to setup of any servers, nor I had to have a “network” connection to do things. Another one is that I could simply put my project in the Dropbox and could work on the project from different machines without having to worry about setting up anything else and still have my version control.

As I worked on my personal projects, I was the only one committing to the repo and things were simple. I could have a feature branch, do merges etc and history of the project would be clean.
Recently I started using GIT on a project that involved more than 2 developers working and often committed changes to the same branch and the history started looking ‘dirty’.

Here is an example.

I am going to setup a simple project called ‘GitExamples’.

$ mkdir GitExamples
$ cd GitExamples
$ git init
$ git checkout -b test

Now to mimic two different users I am going to create two different clones. Just to make things clear I am going to create two directories UserARepo and UserBRepo and clone the repo.

$ mkdir ~/UserARepo
$ mkdir ~/UserBRepo

Let’s setup UserA’s repo

$ cd ~/UserARepo
$ git clone ~/GitExamples
$ git config user.name 'UserA'

Now. UserB

$ cd ~/UserBRepo
$ git clone ~/GitExamples
$ git config user.name 'UserB'

This sets up my playground.
When I am in UserARepo and do a commit I should see “UserA” and likewise for B.

Let me make a quick change from UserA’s repo


$ cd ~/UserARepo
$ echo 'First Text' > UserA.txt
$ git add UserA.txt
$ git commit -m "User A's First commit"

Here is how my history looks:

I am going to push this change up to the remote master repo

$ git push

Let’s say UserA makes another change

$ echo 'Added Some good stuff' >> UserA.txt
$ git commit -am 'UserA Added some content'
$ git push

Things are simple and clean so far,
Here is my working tree:

Let’s jump to UserB to mix things up a bit.

$ cd ~UserBRepo/GitExamples
$ echo "B's First text">UserB.txt
$ git add UserB.txt
$ git commit -m "User B's Fist commit"

If I just did a simple push at this time, it should error out as the HEAD in remote has moved on by few commit pushed by User A.

$ git push
To /home/manijshrestha/deletethis/GitExamples/
 ! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to '/home/manijshrestha/deletethis/GitExamples/'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again. See the
'Note about fast-forwards' section of 'git push --help' for details.

Here is a better view of how things are

As you can see the ‘master’ in remote has gone its own way since I pulled from it.

Let’s do a pull and then push our changes.

$ git pull
Merge made by recursive.
 UserA.txt | 2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

Here is how it looks

Here you see the working tree represents what happened but this looks ‘dirty’ with merges, specially since both users worked on different files, it could look cleaner, follow on.

$ git push

From UserA’s side lets do a pull so both users are at the same base.

Lets run through same scenario this time but we will use “–rebase” while doing a pull and you will see how the tree will look a lot cleaner.

So, I am going to do two commits from UserA’s repo

$ echo 'Some more good stuff' >> UserA.txt
$ git commit -am 'User A added good stuff'
$ echo 'Even more good stuff' >> UserA.txt
$ git commit -am 'User A added more good stuff'
$ git push

Going back to UserB’s repo, we will make some change and commit

$ echo "Some good stuff" >> UserB.txt
$ git commit -am "User B added good stuff"
$ echo "Yet Some good stuff" >> UserB.txt
$ git commit -am "User B added yet more"

Unlike before we will do a pull with –rebase flag.
What it does is that, it will get the changes from remote then “re-apply” the changes the user made locally, so things don’t look deviated.

$ git pull --rebase
First, rewinding head to replay your work on top of it...
Applying: User B added good stuff
Applying: User B added yet more

Git just told us what it did, and here is how the tree looks:

You can see the working tree now looks a lot cleaner.

So we have a one straight branch rather than merges etc.

So If i do a push here is how things look.

Will share some move git love in the future…

Mahalo,

Advertisements

Working with Camera on Android SDK

I wanted to write a quick custom camera android app.
Before we start to write your custom camera app, here are the things we have to aware of.
1. Detect and access Camera
2. Create a preview class
3. Build a preview layout
4. Setup Listeners for Capture
5. Capture and Save files

Lets Start…
Detecting and access Camera
In the Android project, we will have to add Camera permission and feature.
Add following lines in the Manifest.xml

<manifest> 
 <application>
 .....
 </application>
 <uses-feature android:name="android.hardware.camera" />
 <uses-permission android:name="android.permission.CAMERA" />
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
</manifest>

This will get the Camera permission for the application.
(we are asking for permission to write to external storage so we can save image there)
Devices running android 2.3 or higher, we can access specific camera as devices could have more than 1 camera. In this example we will use the back facing camera.

Create a preview class
We create a preview class that simply extends “SurfaceView” which will allow us to show what the ‘camera’ sees.
Also, in order to capture the callback events for creating and destroying the view, which are needed for assigning the camera preview input, we will implement “SurfaceHolder.Callback” interface.

Here is the code for preview class

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {

	private SurfaceHolder mSurfaceHolder;
	private Camera mCamera;

	//Constructor that obtains context and camera
	public CameraPreview(Context context, Camera camera) {
		super(context);
		this.mCamera = camera;
		
		this.mSurfaceHolder = this.getHolder();
		this.mSurfaceHolder.addCallback(this); // we get notified when underlying surface is created and destroyed
		this.mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); //this is a deprecated method, is not requierd after 3.0
	}

	@Override
	public void surfaceCreated(SurfaceHolder surfaceHolder) {
		try {
            mCamera.setPreviewDisplay(surfaceHolder);
            mCamera.startPreview();
        } catch (IOException e) {
          // left blank for now
        }

	}
	
	@Override
	public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
		mCamera.stopPreview();
		mCamera.release();
	}

	@Override
	public void surfaceChanged(SurfaceHolder surfaceHolder, int format,
			int width, int height) {
		// start preview with new settings
		try {
			mCamera.setPreviewDisplay(surfaceHolder);
			mCamera.startPreview();
		} catch (Exception e) {
			// intentionally left blank for a test
		}
	}
	
}

Build a preview layout
Let’s create a Layout where the preview is displayed and the user can click on a button to take a picture.
Change the content of the “main.xml” under the layout directory in your android app.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
  <FrameLayout
    android:id="@+id/camera_preview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1"
    />

  <Button
    android:id="@+id/button_capture"
    android:text="Capture"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    />
</LinearLayout>

Now, lets wire up the Camera Activity

public class DVCameraActivity extends Activity {
	
	private Camera mCamera;
	private CameraPreview mCameraPreview;
    
	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        mCamera = getCameraInstance();
        mCameraPreview = new CameraPreview(this, mCamera);
        
        FrameLayout preview = (FrameLayout) findViewById(id.camera_preview);
        preview.addView(mCameraPreview);
        
    }

    /**
     * Helper method to access the camera returns null if
     * it cannot get the camera or does not exist
     * @return
     */
	private Camera getCameraInstance() {
		Camera camera = null;

		try {
			camera = Camera.open();
		} catch (Exception e) {
			// cannot get camera or does not exist
		}
		return camera;
	}
}

At this point if you run your application, you will see what the camera sees.
To make something meaningful, lets add listener to capture the image.

Setup Listeners for Capture
In order for us to take the picture, we will have to setup the listeners.
Lets make a inner class inside the Activity we created above,

PictureCallback mPicture = new PictureCallback() {

		@Override
		public void onPictureTaken(byte[] data, Camera camera) {
			 File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
		        if (pictureFile == null){
		            return;
		        }

		        try {
		            FileOutputStream fos = new FileOutputStream(pictureFile);
		            fos.write(data);
		            fos.close();
		        } catch (FileNotFoundException e) {

		        } catch (IOException e) {
		        
		        }
			
		}
		
	};

It is using a helper method called, “getOutputMediaFile”, here is the code for that

/** Create a File for saving the image */
	private static File getOutputMediaFile(){

	    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
	              Environment.DIRECTORY_PICTURES), "MyCameraApp");

	    if (! mediaStorageDir.exists()){
	        if (! mediaStorageDir.mkdirs()){
	            Log.d("MyCameraApp", "failed to create directory");
	            return null;
	        }
	    }

	    // Create a media file name
	    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
	    File mediaFile;
	        mediaFile = new File(mediaStorageDir.getPath() + File.separator +
	        "IMG_"+ timeStamp + ".jpg");

	    return mediaFile;
	}

Let’s wire up the listener onCreate method

 //Adding listener
        Button captureButton = (Button) findViewById(id.button_capture);
        captureButton.setOnClickListener(
        		new View.OnClickListener() {
					
					@Override
					public void onClick(View v) {
						mCamera.takePicture(null, null, mPicture);
						
					}
				});

After you have all this wired, the application i ready to fire up some pictures.

Resources:
http://developer.android.com/guide/topics/media/camera.html
http://developer.android.com/guide/topics/media/camera.html#custom-camera

Oracle Coherence

I was trying to setup Oracle Coherence on my Ubuntu machine. I searched for some good examples online but no luck. So i decided to post my own. Here is my experience setting up Oracle Coherence on a linux distro.

1. Download Coherence
You can download the latest Oracle Coherence from their website. At the time of this writing the current version is 3.7 (http://www.oracle.com/technetwork/middleware/coherence/overview/index.html)

2. Setup COHERENCE_HOME
I have JAVA_HOME already setup. If not you would need to set that up first.
After that you would need to set up the following:

$ export COHERENCE_HOME=/home/YOU_LOCATION/coherence
$ export PATH=$PATH:$COHERENCE_HOME/bin

Note: You can put this on your .profile if you want to plan to preserve your variables, else you will have to export the variable on each terminal tabs.

3. Basic setup
Since I am trying this out on 1 machine, I will do a basic setup. For this, I will have a cache server and a cache factory process running. Coherence by default does multicast to find cluster members. It could be set up to be unicast, if you so choose. Learn more from the pdf link below in the notes section. (You can simply ignore the details for now)

4. Touch up the scripts
The coherence directory should have few scripts inside the ‘bin’ folder. I was getting “Bad substitution” error when I tried running the script out of the box, So, I decided to trim it down. Below is the condensed version of the script that made sense to me and cut out some fat.
One of the thing to point out is that I added “-Dtangosol.coherence.cluster=shrestha -Dtangosol.coherence.clusterport=8090” in the JAVA_OPTS which doesnt exist in the canned script

See the scripts below:

cache-server.sh

# specify the JVM heap size
MEMORY=512m

if [ -f $JAVA_HOME/bin/java ]; then
  JAVAEXEC=$JAVA_HOME/bin/java
else
  JAVAEXEC=java
fi

if [[ $1 == '-jmx' ]]; then
    JMXPROPERTIES="-Dcom.sun.management.jmxremote -Dtangosol.coherence.management=all -Dtangosol.coherence.management.remote=true"
    shift
fi

JAVA_OPTS="-Xms$MEMORY -Xmx$MEMORY $JMXPROPERTIES -Dtangosol.coherence.cluster=shrestha -Dtangosol.coherence.clusterport=8090"

$JAVAEXEC -server -showversion $JAVA_OPTS -cp $COHERENCE_HOME/lib/coherence.jar com.tangosol.net.DefaultCacheServer $1

coherence.sh

if [ -f $JAVA_HOME/bin/java ]; then
  JAVAEXEC=$JAVA_HOME/bin/java
else
  JAVAEXEC=java
fi

if [ $STORAGE_ENABLED == "true" ]; then
	echo "** Starting storage enabled console **"
else
	echo "** Starting storage disabled console **"
fi

JAVA_OPTS="-Xms$MEMORY -Xmx$MEMORY -Dtangosol.coherence.distributed.localstorage=$STORAGE_ENABLED $JMXPROPERTIES -Dtangosol.coherence.cluster=shrestha -Dtangosol.coherence.clusterport=8090"

$JAVAEXEC -server -showversion $JAVA_OPTS -cp $COHERENCE_HOME/lib/coherence.jar com.tangosol.net.CacheFactory $1

5. Running Coherence
If you got through here, you are ready to start your coherence.
Now, Lets start the server, simply run the “cache-server.sh”

$ ./cache-server.sh

You should see something like

... ... ...
Services
  (
  ClusterService{Name=Cluster, State=(SERVICE_STARTED, STATE_JOINED), Id=0, Version=3.7.1, OldestMemberId=1}
  InvocationService{Name=Management, State=(SERVICE_STARTED), Id=1, Version=3.1, OldestMemberId=1}
  PartitionedCache{Name=DistributedCache, State=(SERVICE_STARTED), LocalStorage=enabled, PartitionCount=257, BackupCount=1, AssignedPartitions=257, BackupPartitions=0}
  ReplicatedCache{Name=ReplicatedCache, State=(SERVICE_STARTED), Id=3, Version=3.0, OldestMemberId=1}
  Optimistic{Name=OptimisticCache, State=(SERVICE_STARTED), Id=4, Version=3.0, OldestMemberId=1}
  InvocationService{Name=InvocationService, State=(SERVICE_STARTED), Id=5, Version=3.1, OldestMemberId=1}
  )

Started DefaultCacheServer...

Now, lets start a coherence.sh

$ ./coherence.sh

if everything went right, you may see a shell “Map(?) :”

... ... ...
TcpRing{Connections=[1]}
IpMonitor{AddressListSize=0}

2011-10-18 23:14:10.951/2.581 Oracle Coherence GE 3.7.1.0 <D5> (thread=Invocation:Management, member=2): Service Management joined the cluster with senior service member 1

Map (?):

foo bar
Now its time to take it for a spin,
in the pompt type “cache Test” to create cache named “Test”

Map (?): cache Test
Map (Test):

Lets add a key value pair, for this, we do “foo” “bar”

Map Test): put foo bar

Verify the value is stored property

Map (Test): get foo
bar

If you want to try more, you can spin up another “coherence” process by running the “coherence.sh” in another terminal. You can work with same cache, you can add values in that and go back to previous shell and see the value is globally replicated.

PS: http://download.oracle.com/docs/cd/E18686_01/coh.37/e18692.pdf

Testing with Spock – quick start

I heard about “Spock” the testing framework earlier this year. When I watched a online screencast at the time, I was impressed! Few things that I liked about it was the “Simplicity” and “intuitiveness” it brings to the table.
I see it as “groovy” to groovy, as to groovy to java.(i.e. life made simpler)
To be honest, when I learnt about it earlier, I was little skeptic if this was going to be adopted well and gonna be there for a while. Recently I visited their portal and I was glad to see that it was “Highly Active”. So, here I am trying to give it a try.
Complete Source code could be found at my github, https://github.com/manijshrestha/SpockExample

I have a simple project set up using gradle.
In this example I am going to try to create a “InventoryManager” that manages inventory for a online store.

Here is my Manager code:

package com.manijshrestha.spockexample

import com.manijshrestha.spockexample.exception.OutOfStockException
import com.manijshrestha.spockexample.exception.NotEnoughInventoryException

class InventoryManager{
	
    private def items =[:]
	
	def getCountOfInventory(item){
		items.get(item)
		}
	
	def gotTotalInventoryCount(){
		def sum = 0
		items.each{sum += it.value}
		return sum
	}
	
	def checkout(String item, int qty){
		def availQty = items.get(item)
		if(availQty <= 0)
			throw new OutOfStockException()
		if(qty > availQty)
			throw new NotEnoughInventoryException()
		
			items.put(item, availQty - qty)	
	}
}

And here is a simple test class used to test this code:

package com.manijshrestha.spockexample

import spock.lang.Specification
import com.manijshrestha.spockexample.InventoryManager
import com.manijshrestha.spockexample.exception.OutOfStockException
import com.manijshrestha.spockexample.exception.NotEnoughInventoryException

/**
 * Created by IntelliJ IDEA.
 * User: manijshrestha
 * Date: 10/12/11
 * Time: 11:10 PM
 * To change this template use File | Settings | File Templates.
 */
class InventoryManagerTest extends Specification{
	
	def inventoryManager = new InventoryManager()
	
	def "count of items in inventory"(){
		when:
			inventoryManager.items = ["cd": 3]
		then:
		    inventoryManager.getCountOfInventory("cd") == 3
	}
	
	def "total count of all inventories"(){
		when:
			inventoryManager.items = ["laptop": 10, "cellphone": 5, "tablet":5]
		
		then:
			inventoryManager.gotTotalInventoryCount() == 20
	}
	
	def "throw exception when trying to checkout item out of stock"(){
		when:
			inventoryManager.items = ["droidx": 0]
			inventoryManager.checkout("droidx", 1) // trying to buy droidx
		then:
			thrown(OutOfStockException)
	}
	
	def "throw exception when trying to checkout more qty than avail"(){
		when:
			inventoryManager.items = ["led tv": 2]
			inventoryManager.checkout("led tv", 3)
		then:
			thrown(NotEnoughInventoryException)
	}
	
	def "reduces correct number of items"(){
		when:
			inventoryManager.items=["dvd" : 10]
			inventoryManager.checkout("dvd", 7)
		then:
			inventoryManager.items.dvd == 3
	}

}

Few things I would like to point out here, the method names are Strings, which makes it a nice and readable test case rather than a camel cased or underscore delimited method names.
These tests I think are more readable and simple to understand. Well, I do have a very simple example here but with its power, I think writing complex test will still be simpler compared to regular jUnit tests.

Installing Nepali/Devnagari Font in Android

Update: If you do not want to mess with ADB Follow the steps from my new post about Yet another way to Install Nepali/Devnagari font on Android devices.

One of the issues with Android is that it doesn’t come with Nepali / Devanagari font by default. When I visit websites with Nepali font or have posting on Facebook with Nepali text, it shows up as boxes. Similar to image below.

It started to be more annoying as I would get emails in Nepali font, and I would have to check it on a computer.
So after tinkering around, I am happy to report that I have a solution.
This is how I solved it:
Download the Font (DroidSansFallback.ttf) on your SDCard:
DroidSansFallback.ttf

Using ADB (You may be able to use some “Explorer app” with root access. adb is simple if you have Android SDK installed)

go to the device console:

$ ./adb shell
#

Mount your phone drive so you can have write access to system folder

# mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system

Now, Simply copy over the font from your sdcard to “/system/fonts”.
(font might be already existing on the device, you can just overwrite it.)

# cp /mnt/sdcard/DroidSansFallback.ttf /system/fonts

(Note: DroidSansFallback.ttf is stored on the root of the sdcard.)
Thats it, now reboot your device and your device should render Nepali font with no issues 🙂

Hope this helps!

Waking up to CoffeeScript

Just clicking around on github today ran into some files with “.coffee” extension. First I thought someone wanted to be funny with the ‘name’ as they might be drinking way too much coffee while sitting in front of a computer, coding. Checking the contents of the file things looked interesting.
I turned to our best friend ‘google’ and found out about coffee script!
I am not sure if I will be using it in any of my project any time soon, but I thought I should just start with a little ‘Hello World’.

You can find more info on their website, http://jashkenas.github.com/coffee-script/

Installing CoffeeScript
I am on Ubuntu, so, here are steps on how to install CoffeeScript on Ubuntu.
At the time of this writing, the latest version of coffeescript is 1.1.2.
CoffeeScript depends on “Node.js”, so we have to install Node.js first.(0.4.12 is the latest version at the time of writing)

Let’s Install the Node.js

$ wget http://nodejs.org/dist/node-v0.4.12.tar.gz
$ tar xzvf node-v0.4.12.tar.gz

At this point you should have nodejs ready to be configured.
Let’s configure it next

$ cd node-v0.4.12/
$ ./configure  --without-ssl
$ make

(Note: I had issues with ssl so I had to configured it without ssl, you may try without the flag)

Congratulations, you have successfully configured node.js!

Now, Lets Move on to CoffeeScript

Download the latest CoffeeScript and set up by following the steps below:

$ wget --no-check-certificate --trust-server-names     http://github.com/jashkenas/coffee-script/tarball/1.1.2

$ tar xzvf 1.1.2

Once you are done with above steps, you should have a directory something like, ‘jashkenas-coffee-script-1a652a9’

Lets take it for a test drive

$ cd jashkenas-coffee-script-1a652a9
$ bin/coffee --version

You should see an output similar to below:
CoffeeScript version 1.1.2

Create a file and call it “test.coffee” (in same location are you at right now)

alert 'Hello World!'

$
Let’s Compile, to compile a coffee script you simply type the following:

$ bin/coffee -c test.coffee 

You should see a file called ‘test.js’ with content

(function() {
  alert('Hello World!');
}).call(this);

We have successfully written a first “CoffeeScript” Code!
There are tons of examples on their site, we can give it a try at some point.

Reference: http://net.tutsplus.com/tutorials/javascript-ajax/rocking-out-with-coffeescript/

Building a Native (kind of) Android App using Grails, HTML 5, CSS, Javescript hosted on CloudFoundry

Been very busy with personal life lately and haven’t had time to do much of interesting stuff specifically on CloudFoundry, Grails and Android.
Here is my attempt to build an android application entirely based on HTML 5, CSS and JS. Ever since I found out that LinkedIn built their Mobile app based on those technologies instead of pure native application. I have been very interested in trying it out myself.
I truly am a believer in CloudFoundry! I think it is going to change how “Cloud” service is provided (PaaS). (Wanted to blog about CloudFoundry Micro but my machine doesn’t Support VT 😦 so may be will get to blog about it sometime later…)

Let’s Jump on to our today’s topic.
Here is my vision:
1. Build a Grails application that is hosted on cloudfoundry. This will serve as a mobile website. I will be using jQuery Mobile.

2. Build a Native looking app using PhoneGap that will interface to the grails web application hosted on cloudfoundry.

About the application:

We will build an android application that will give events that are going on around you given your location. We will be using YQL to get the data. You can learn more about YQL at http://developer.yahoo.com/yql/

Since I want it to be a good size blog entry and not to long, This will be part I of the application.
By the end of this blog I should have.
1. Grails App optimized for mobile hosted on Cloudfoundry
2. Android App based on PhoneGap that will serve as an interface to the Grails App built above.

Let’s Start with the first part:

Building Grails App and hosting it on CFoundry:

I am going to build it from the ground up. I may skip few things, but, if you just want to know how this is done, you can read my old blog post about building a grails app on Cfoundry here.

Creating Grails app and installing the CFoundry plugin:

  $ grails create-app FindEventsGA
  $ grails install-plugin cloud-foundry

(Note: Refer to the link above to set up your Cloudfoundry account in Config.groovy)

Setting up jQuery Mobile Test page:
If you followed me till here you should have a standard grails app all ready to go.
Now, Lets wire up the jQuery Mobile. At the time of this writing, jQuery Mobile Beta 3 was the latest.
Now Navigate to your “index.gsp” in your “views” folder and replace the current content with the following content.

 

<!DOCTYPE html> 
<html> 
<head> 
<title>Grails Mobile App on CloudFoundry</title> 
<meta name="viewport" content="width=device-width, initial-scale=1"> 
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0b3/jquery.mobile-1.0b3.min.css" />
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.3.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/mobile/1.0b3/jquery.mobile-1.0b3.min.js"></script>
</head> 
<body> 
<div data-role="page" id="dashboard">
	<div data-role="header">
		<h1>GrailsApp</h1>
	</div><!-- /header -->

	<div data-role="content">	
		<p>Hello From Grails Mobile App!</p>	
	</div><!-- /content -->
</div><!-- /page -->
</body>
</html>

Above HTML 5, will replace the standard Grails homepage.
In the Page above, it simply imports jQuery Mobile JS and CSS.
You can read more about them at jQuery Mobile page http://jquerymobile.com/applicatio

Now we are ready to publish the app.

Lets run the following command from the grails project directory and verify that it renders the page correctly.
(Note: If you are using Eclipse with Grails plugin or STS, you can simply press “Ctrl+Alt+Shit+G” –> This will give you grails command prompt where you can simply type “prod cf-push”)

$ grails prod cf-push

I set up my application to be hosted under “http://findevents.cloudfoundry.com/&#8221;
After the app has been published, We can get to it through a browser.
See an screen Shot below.

Since I have pushed the app up in the cloudfoundry “cloud”, I can navigate to it from my mobile browser.
Here is how it looks on the device.

We are half way done! – Building a native application
Now the web app is ready, Let’s set up the android application.

Create a new android project on Eclipse or any other IDE of your choice. (http://developer.android.com has tutorials if you are new to Android development.)

After you have a Android Project ready. We will go to PhoneGap and download their Jars.

Go to PhoneGap website and download their android tools.
http://www.phonegap.com/download-thankyou

Unzip the file and place following artifacts.

1. Get the Android “phonegap-1.0.0.jar” (or whatever version you get) from and “Android” directory in the zip and place it in your Project under “libs” folder. (Create the “libs” directory under your android project)

2. In your android project, create “www” folder under “assets” folder (assets folder should already be in your android project). Copy the “phonegap-1.0.0.js” found in the Android folder in the zip file into this www directory.

3. Copy the “xml” folder found in the Android folder inside the zip file into “res” folder in your android application.

Your Project should look similar to one below:

As we added the jar, let’s add it to the build path.
To do this, simply right click on the project and click on “Properties”.
Navigate to “Java Build Path”>”Libraries”. Click on “Add JARs…” and point to the phonegap jar.

Now, navigate to your Main Activity on your android Project and make following changes.

1. Extend the activity to “DroidGap” instead of “Activity”

2. add URL to your grails application.

 super.loadUrl("http://findevents.cloudfoundry.com");

Your class may look similar to the following:

import android.os.Bundle;

import com.phonegap.DroidGap;

public class FindEventsGADroidActivity extends DroidGap {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.loadUrl("http://findevents.cloudfoundry.com");
    }
}

Now let’s change the AndroidManifest.xml and we are ready for the show time.

Add following xml before the <application tag

<supports-screens 
	    android:largeScreens="true"
		android:normalScreens="true" 
		android:smallScreens="true"
		android:resizeable="true" 
		android:anyDensity="true" />

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 

Add android:configChanges="orientation|keyboardHidden" to the activity tag in AndroidManifest. (view image below)

Add a second activity below under you application tag in AndroidManifest. (view image below)

<activity android:name="com.phonegap.DroidGap" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden"> 
     <intent-filter> </intent-filter>
 </activity> 

Your Manifest should look something like below:

Learn more about PhoneGap at http://www.phonegap.com/start

We are done!

Show Time
Run your application and you should see the Grails app that will apear like a native application on your device.

See below for a screen shot of my application.

We have accomplished our goal for this post and are at a good stopping point.
We now have a grails app thats running on cloudfoundry appear as a native app on Android!

In the next post I will be working on gestures etc on grails app and will use YQL.
Most interestingly use device gps etc to find location. We will have to make some significant changes to the project. Hope you enjoyed this post.