Tropical Software Observations

09 November 2009

Posted by Teo Choong Ping

at 4:00 PM

1 comments

Labels:

Get Started with Redis and Groovy with JRedis

  1. Once you got Redis up and running you need to grab a copy of JRedis.
  2. Using GroovyConsole, run this command to include the JRedis jar: "grailsConsole -cp jredis-core-all.jar"
  3. Execute this sample code:


import org.jredis.*
import org.jredis.ri.alphazero.*
import org.jredis.ri.alphazero.support.*


def redis = new JRedisClient();
redis.set("test", "Hello world")
def result = redis.get("test")
assert DefaultCodec.toStr( redis.get("test") ) == "Hello world"

02 November 2009

Posted by Teo Choong Ping

at 4:59 PM

2 comments

Grails eh-cache plugin note

Just a couple of notes to those thinking of using eh-cache for caching their Grails apps.

  1. Latest version install from command line 0.2 (dist-ehcache)
  2. Out of the box, the taglib is missing, see this Nabble thread
  3. Out of the box, def get(Serializable key, boolean isCacheDistributed) is missing, you have to DIY here.
  4. You can view the cache status by http://localhost:8080/cacheStatus if this is not obvious to you.

09 October 2009

Posted by Teo Choong Ping

at 9:13 AM

1 comments

Labels:

iPhone-sdk Tips: Prevent scrolling and bouncing of UIWebView

You may have a situation where you do not want the UIWebView to bounce or scroll when a user touches the view. There are 2 ways to do just that.

1. Embed Javascript function in the page itself

document.onload = function(){ document.ontouchmove = function(e){ e.preventDefault(); } };

2. Set AllowsRubberBanding to NO


[(UIScrollView*)[webview.subviews objectAtIndex:0] setAllowsRubberBanding:NO];

(Discussion here)

27 August 2009

Posted by Teo Choong Ping

at 1:29 PM

0 comments

Labels: , , , ,

Install Apache-Passenger (mod_rails) on Ubuntu 9.04 in 10 steps

A very quick guide on installing Passenger (mod_rails) on a clean install of Ubuntu jaunty 9.04.

  1. apt-get install build-essentials
  2. apt-get ruby apt-get ruby-dev
  3. gem install rubygems-update
  4. cd /var/lib/gems/1.8/rubygems-update-1.3.x/
  5. ruby setup.rb or bin/update_rubygems
  6. gem update --system
  7. gem update
  8. gem install passenger
  9. apt-get install libopenssl-ruby1.8 apache2-prefork-dev libaprutil1 libaprutil1-dev
  10. passenger-install-apache2-module
At the end of the installation, you will be prompted to add a few lines to your apache conf -- copy and paste the lines to /etc/apache2/apache2.conf and you are ready to deploy Rails apps immediately.

For the rest of the setup and configuration see here. Hope this helps someone out there.

04 August 2009

Posted by Irregular Zero

at 4:28 PM

0 comments

Labels: , ,

Groovy Tutorial for MongoDB

Java Tutorial (http://www.mongodb.org/display/DOCS/Java+Tutorial)

Since Groovy is based on Java, you can make use of the Java driver for MongoDB as well as go through the tutorial shown above. The code can be used as-is or modified to look more groovy.

Create a groovy file (mongo.groovy) and place the Java driver in the same directory. Edit it so the code looks like:

this.class.classLoader.rootLoader.addURL(new File("mongo-0.6.jar").toURL())

import com.mongodb.*

DBAddress address = new DBAddress("localhost", "mydb")
Mongo db = new Mongo(address)
db.authenticate('testUser', 'testPassword')

DBCollection coll = db.getCollection("testCollection")

BasicDBObject doc = new BasicDBObject()
doc.put("name", "MongoDB")
doc.put("type", "database")
doc.put("count", 1)

BasicDBObject info = new BasicDBObject()
info.put("x", 203)
info.put("y", 102)
doc.put("info", info)

coll.insert(doc)

for(i in 1..100) {
coll.insert(new BasicDBObject().append("i", i))
}

println coll.getCount()

DBCursor cursor = coll.find()
while(cursor.hasNext()) {
println cursor.next()
}

You can see it's just a rehash of part of the Java tutorial, the output will be a count of the number of inserted objects followed by the objects themselves.

The first line of code loads the jar file, this is useful if you're not looking to put the jar in a classpath or one of groovy's configured library paths like '~/.groovy/lib'.

Running the script is accomplished by 'groovy mongo.groovy' in the terminal. You can also type in 'groovyConsole' to load the console then opening the script and running inside it.

Installing MongoDB on Ubuntu 9.04 Jaunty Jackalope

For the installation, I decided to build MongoDB (http://www.mongodb.org/) from source. The documentation regarding this is thorough and getting it running was a cinch. A Javascript engine called Spider Monkey is used and you need to build it with UTF8 support.

The documents referred to:
http://www.mongodb.org/display/DOCS/Building
http://www.mongodb.org/display/DOCS/Building+Spider+Monkey
http://www.mongodb.org/display/DOCS/Building+for+Linux

The all-in-one command line version:
Dependencies:
sudo apt-get install curl tcsh git-core scons g++
sudo apt-get install libpcre++-dev libboost-dev libmozjs-dev

Spider Monkey installation:
curl -O ftp://ftp.mozilla.org/pub/mozilla.org/js/js-1.7.0.tar.gz
tar zxvf js-1.7.0.tar.gz
cd js/src
export CFLAGS="-DJS_C_STRINGS_ARE_UTF8"
make -f Makefile.ref
sudo JS_DIST=/usr make -f Makefile.ref export

MongoDB installation:
git clone git://github.com/mongodb/mongo.git
scons all
sudo scons --prefix=/opt/mongo install

Finishing up:
add /opt/mongo/bin to your path
create a /data/db directory structure and chown it to your user or add read-write permission.
http://www.howtogeek.com/howto/ubuntu/how-to-add-a-program-to-the-ubuntu-startup-list-after-login/
System -> Preferences -> Startup Applications -> Startup Programs
click add, click browse and select /opt/mongo/bin/mongod
add run to the end of the line so that it reads '/opt/mongo/bin/mongod run'
enter name and comment then save

And you're done. mongodb will start up with no authentication as default at localhost:27017, the web information interface is at localhost:28017. You can use mongo to enter the interactive shell, similar to mysql's shell client.

Some links to get you started:
http://www.mongodb.org/display/DOCS/Overview+-+The+MongoDB+Interactive+Shell
http://www.mongodb.org/display/DOCS/File+Based+Configuration
http://www.mongodb.org/display/DOCS/Command+Line+Parameters
http://www.mongodb.org/display/DOCS/Security+and+Authentication
http://www.mongodb.org/display/DOCS/Manual

28 April 2009

Posted by Bacchus D

at 4:57 PM

0 comments

Labels: , ,

Grails and PartyTime Training in China


We've just returned from a trip to Guangzhou where we spent two days working with our partners, Well United, on Groovy, Grails, and PartyTime. It turned out to be a larger group than expected but the more the merrier!

It was a lot to cover in two days but even though the time allotted for the training session was rather short, it went very well and the Well United team picked everything up quickly.  The C#, PHP, and Java developers seemed enthusiastic about Grails and we hope to be working together on projects sometime soon.

Many thanks to our gracious hosts in Guangzhou and Hong Kong. We enjoyed the Macanese and Cantonese food and hope to be back soon!


18 April 2009

Posted by Teo Choong Ping

at 11:23 AM

1 comments

Labels: ,

Install Groovy 1.6.1 on Windows -- A guide for the non-Java developer

* This is a quick guide on installing the latest Groovy 1.6.1 in Windows for non-Java developers.

1. Download and install Java SDK 1.6.x. Get the latest installer from Sun here. If this is your first time downloading Java, you are going to be confused with the various JDK 6 Updates packages -- JDK 6 Update with JavaFX SDK, JDK Update with Java EE, JDK Update with NetBeans 6.5.x. If unsure just look for the package without any of those extras -- Java 6 Update 13.

2. Download Groovy 1.6.1 installer from Groovy site. We will just use the Windows installer.

3. Double click on the Groovy installer and follow the wizard steps.


4. Use the defaults settings -- create GROOVY_HOME, add to PATH and add to System environment.


5. Make sure you have set JAVA_HOME environment. Right click on "My Computer", select "Properties". Click on the "Advance" tab and then click on the "Environment Variables" at the bottom of the window.



6. Add JAVA_HOME to User Variables. Click "Add" and enter the name as JAVA_HOME and value set to the full path to your Java JDK directory, e.g., C:\Program Files\Java\jdk1.6.0_13.


7. Continue with the Groovy installation wizard -- click next and use the defaults settings for native launcher and use all the Additional Modules.

8. Once finished, you should be able to see a new Groovy menu in Program list.


9. Lets give it a try. Select "Start GroovyConsole" to run GroovyConsole. If all goes well, you should be able to see the GroovyConsole up.

10. There are 2 useful keyboard shortcuts to know for GroovyConsole:

  • Cntrl+Enter = Run the groovy code
  • Ctrl+w = Clear console output

20 March 2009

Posted by Teo Choong Ping

at 9:40 AM

0 comments

Labels: ,

Grails and Rails: Domain Classes and Web Services

Let's take a brief look at the differences between Grails and Rails in term of persisting domain classes and creating web services. Both Grails and Rails are MVC frameworks and are very similar in terms of code syntax.

1. Domain Class Persistence

In Grails:



class Person {
String firstName
String lastName
String email
Date birthDate
Address address

static constraint = {
firstName(blank:false)
lastName(blank:false)
email(blank:false, email:true) // check if it's really e-mail
}
}

class Address {
String street
String city
String country
Person person

static belongsTo = Person
}



In Rails, attributes can be inferred from the database table's structure:

class Person <>
# Expects database schema to have a table "person"
# with columns first_name, last_name, email, birth_date

validates_presence_of :first_name, :last_name, :email
end

class Address <> has_one :address
belongs_to :person
end


2. Making a service class available as a web service

In Grails, inside a controller closure:


def listAllPeople = {
def pplList = Person.list() // or by query Person.findByLastName("Hewitts")
render pplList as XML
// render pplList as JSON
}



In Rails, inside a controller block:


def listAllPeople
@pplList = Person.all # or by query Person.find_by_last_name("Hewitts")
render :xml => @pplList
# render :json => pplList
end


Note:
1. Grails will auto-generate the database schema and update the schema when more domain fields are added to the class. It's also possible to go in the reverse direction if you prefer starting with an existing schema.
2. Rails expects the database schema to be pre-created and to conform to camel case naming conventions.
3. Grails has the notion of service classes which are commonly used for business logic and can be use in a controller as a web service end point.

18 March 2009

Posted by Bacchus D

at 4:26 PM

3 comments

Labels:

VMware ESXi For Cheapskates

I've finally had it with Xen. We've been using it for QA and infrastructure hosts for a couple of years now (after a brief, bizarre detour with Solaris containers) with pretty good results. But after discovering Xen support had been dropped from the latest version of Ubuntu, I tried out KVM only to discover that its client tools are currently dribbly pieces of poo. I'm sure there's a clever way to compile your own kernel with the Xen patches to create some sort of frankenstein hypervisor, but really all I want is just the thinnest layer possible on top of bare metal in order to run some Linux VMs. Not really all that much to ask for.


Most of the software we use at Favorite Medium is open source so I, too, was surprised when my search led me to VMware. They recently made ESXi, the smaller and somewhat crippled cousin of ESX, free so I decided to try installing it on a $600 machine that formerly ran Xen in another life. This host is known around our office as 'pike' and is named after Rob Pike for no particular reason.

After burning the ISO image to a disk and booting up pike, I immediately ran into problems. First it was the ethernet card. Apparently ESXi has a fairly limited HCL and our crappy D-Link NIC was not on it. A quick trip to the local IT graveyard and I was back in the office with two replacements: an Intel PRO/100, and a Broadcom gigabit something or other. $12 each.

The Broadcom NIC worked perfectly but then the installer complained about the disk controller. Our super cheap Gigabyte motherboard (G31M-SL2, if you must know) uses a cruddy SATA controller that, again, isn't on the ESXi HCL. Note that if you're trying this on consumer-grade hardware you'll likely run into the same problem as well. Now the installer probably ought to handle the condition more gracefully but instead it just stops cold with an ominous "The installation has encountered a fatal error" message. Not to worry, a quick one line edit of a Python script fixed the problem. Check out the detailed procedure here.

Never thought I'd say this but...VMware, lovin' it!


17 March 2009

Posted by Irregular Zero

at 6:38 PM

1 comments

Labels:

Delegation for iphone-google-maps-component

The iphone-google-maps-component is a way for you to use Google Maps on the iPhone through the use of an extended UIWebView and an html file on a server somewhere that does the map loading.

The present code overrides the default delegate UIWebViewDelegate with its own, MapWebViewDelegate. You cannot use the setCenterWithLatLng to establish the starting location until the view has finished loading. With the override, the webViewDidFinishLoad delegate method is unavailable.

Going by this post, the following code changes will allow the use of both delegates.

MapWebView.h
1) Change protocol definition.
@protocol MapWebViewDelegate < UIWebViewDelegate >

MapWebView.m
2) Remove the synthesize line.
//@synthesize delegate;

3) Replace with own methods, to hook into super.delegate.

- (id ) delegate {
return (id )super.delegate;
}

- (void) setDelegate :(id ) delegate {
super.delegate = delegate;
}


webViewDidFinishLoad should be accessible, as well as the other methods in the UIWebViewDelegate.

Another way of setting the starting location is through the loadMap method in MapWebView.h. The URL string can accept two more variables, latitude and longitude.

Change this:
NSString *urlStr = [NSString stringWithFormat:
@"http://www.wenear.com/iphone-test?width=%d&height=%d&zoom=%d",
width, height, DEFAULT_ZOOM_LEVEL];


To this:

NSString *urlStr = [NSString stringWithFormat:
@"http://www.wenear.com/iphone-test?width=%d&height=%d&latitude=%f&longitude=%f&zoom=%d",
width, height, location.coordinate.latitude, location.coordinate.longitude, DEFAULT_ZOOM_LEVEL];


Here, location is a CLLocation, part of the CoreLocation framework. The loadMap method is publicly defined in the interface and it accepts location as its variable. The call in didMoveToSuperview should be properly handled.

The latitude and longitude are doubles and can be hardcoded instead.

18 February 2009

Posted by Teo Choong Ping

at 3:06 PM

0 comments

Labels:

Hello Android

Found this very insightful diagram of how Android SDK churns out Dalvik .dex files from Android java files here.

09 February 2009

Posted by Irregular Zero

at 6:04 PM

0 comments

XML and the Copyright symbol, ©

For anyone parsing an XML file and wondering what in the world an org.xml.sax.SAXParseException: Invalid byte 1 of 1-byte UTF-8 sequence error message is, check to see whether the XML file has any special characters like the copyright symbol, ©. The default encoding of UTF-8 will choke on these.

Solved my woes by changing the encoding to <?xml version="1.0" encoding="iso-8859-1"?> to get the character to display correctly. You can also filter it out or replace the symbol with its character reference.

30 January 2009

Posted by Teo Choong Ping

at 3:41 PM

1 comments

Labels: ,

Injecting Grails Service class via Spring

A quick note on how to inject Service objects -- or for that matter any object -- via Spring.

Grails has always been able to support the injection of objects via Spring whether using XML or Spring DSL. A good scenario of using Spring DSL is to swap implementations easily.

In our project, Party Time, we use a lot of services. Most of these services implement Java interfaces and may be changed in the future. To be flexible in the changing of these service implementation, we auto-wire the services via Spring DSL.

For example, we have a Service class, LocalCDNService that implements the ICDNProvider interface. We configure the implementation by specifying in grails-app/conf/spring/resources.groovy:


beans = {
cdnProvider(LocalCDNService)
}


And from then onwards we can refer to the service object within our Grails controllers, taglibs, or services by simply declaring:


class ExampleController {
def cdnProvider
...
}


Contrast this to the common way of autowiring services by declaring:


class ExampleController {
def localCdnService
}


If we were to change CDN provider from LocalCDNService to AWSCDNService, we would probably need to change many classes. However if you were to use the Spring DSL way, you just need to change grails-app/conf/spring/resources.groovy:


beans = {
cdnProvider(AWSCDNService)
}


Hopefully this will shed more light to those new to using Spring within Grails.

20 January 2009

Posted by Teo Choong Ping

at 9:24 PM

4 comments

Labels:

Sun Tech Days 2009, Singapore 20 January

Just finished the first day of Sun Tech Days 2009 -- in summary I give it 4 stars out of 5.

Arrived early and saw a huge crowd of people queuing up for registration. The registration process was efficient -- I got my badge, orange goodie bag, and was quickly shown the way to the foyer. I'll be frank, I was expecting a light breakfast. No breakfast, only coffee and tea. Well as long as they serve coffee I am happy.

The welcoming ceremony started at around 9:10 am. Man, it was hilarious to see the big guys dressed as some Chinese gods. Check out some pictures and video in Arun's blog.

We were given a small Chinese rattle drum on the way into the hall. It's cool to use those small drums instead of clapping. This drum rattling event was supposed to be in Singapore's Book of Records for largest number of developers drumming away. Well whatever floats their boat.

Next thing I remember is seeing Mr Jeff Jackson taking on the stage to coordinate a few demo sessions. Between the sessions I remember lots of mentions of Glassfish, social networking, Google, YouTube, Ruby, OpenSolaris, etc.

Notable demos in the technology showcase:

  1. Mr Arun Gupta demoing Glassfish Prelude -- nice to see Felix container there. Which reminds me, I need to check with the folks at Qi4J. It's been a while since I've dabbled with OSGi stuff.
  2. jMaki demo -- yawn yawn.
  3. Simon Ritter's Wii controller hack -- very cool stuff. I hope he will put the projects and code that he used for the Wii hack in his blog soon.
  4. Somebody got lucky and went home with a Toshiba laptop. I am still jealous.

Next I went on to the JavaFX: The New Platform for Rich Internet Applications track session. Well I had my doubts about JavaFX before but not after this session. Man I'm going to pull out my favorite book on animation and graphics -- Foundation Actionscript 3.0 Animation:Making Things Move and try some exercises with JavaFX. The Wow factor is definitively there but I'm also wondering aloud if this could be another one of those J2ME feel-good-sessions: you know everyone feels really excited to see the rallying around J2ME in McNealy's days as the next platform to bring computing power to everyone's palm, and people end up jumping in droves to Android and iPhone development. Anyway -- a big applause to the demo, it was smooth and very entertaining. Especially when the sharks swim away!

After that I went on to the DTrace: Bridging the Observability Gap for Java and Scripting Applications. DTrace is one of those technologies that I follow closely but could not grasp fully at the same time. It's like a myth that -- that until I really see it as really really cool, I have to keep my mouth shut in telling others about it.

Peter Karlsson was the speaker and though he had some hiccups with his demo, I really wished he didn't give up. He should've probably stuck his fingers on the console, fixed the problems and continued calmly. But I guess keeping calm is easier said and than done when you are running out of time. I enjoyed it anyway but since I will be attending the 9400 – Exposing the Depths of Java Applications with DTrace I thought I will have my chance to know DTrace better later.

Then we are let out for a 15 minute break. I had another cup of coffee and some cakes. Nice. Next to my lab session on DTrace.

Here is a summary of the LAB-9400: Exposing the Depths of Java Applications with DTrace session:
  1. Peter Karlsson and Joey Shen are conducting this session
  2. Many didn't come with their laptop and I'm not sure what they got out from this since the session is pretty code intensive
  3. Of those with laptops I'm the only one with Mac so the bootable USB of OpenSolaris won't work on me. Oh well at least I have DTrace built in on my Mac OSX 10.5.6. heh
  4. The lab slides are about 200+ pages -- we were told that it would take about 8 hours to cover them all. We have like about 2 hours. :-O
  5. The depth of DTrace is overwhelming -- I barely understand the D language: probe, predicate, and action scripting.
  6. While Peter was talking about the introduction of DTrace, I did a quick search on "Mac OSX dtrace dtracetoolkit", I realize that my mac already have most of the DTraceToolkit available. Try "ls /usr/bin/*.d"
  7. Later I got a good grasp at how DTrace and D language works -- I began to open up the D scripts on my Mac to see the gory details of the scripts.
  8. Too bad Java 6 on Mac doesn't support DTrace yet. (Apple tends to bump up Java guys)
  9. DTrace is more than a super steroid debugger -- you can turn it into all kinds of monitoring instrumentation. (Need to google for an anti-keylogger D script)
  10. This session is way too short and too brief. If Peter and Joey are reading this, may I suggest to you guys this: pick a topic short enough to fit into 1.5 hours. Stop telling me about all the cool stuff I can do with DTrace. I know that already, or else I wouldn't be sitting there in the first place. Show me how to "X-Ray" my Java apps!
  11. At the end of this session, I am reminded of the saying, "the teacher only shows you the door, you have to go in yourself". Well thanks, I will be writing about D scripts shortly.

Next, maybe I had too much coffee, was palpitating. By now it's already 4.30pm, I had another coffee in this very short break.

On my next session track, I have the choice of going to:
  1. MySQL: The Database for Web 2.0
  2. Java SE 6 Update 10: Simplified Java Deployment
  3. Thriving on OpenSolaris
I chose the OpenSolaris session because I wanted to see some OpenSolaris 2008.11 in action. Here are my thoughts of that session:
  1. I was late a bit and didn't get the speaker's name. I got the overall impression that he is floating the on clouds with OpenSolaris here.
  2. Way too much time playing with Compiz on the Gnome desktop. C'mon guys, it's Compiz -- lets move on already!
  3. And seriously, somebody should tell the crowd that OpenSolaris is using the Gnome desktop -- we're developers, we will get it even if you need to explain such things as X11, desktop client and Unix stuff like that.
  4. The ZFS part was not impressive. I have seen better webminar videos on this. yawn
  5. The DTrace part was a waste of time. He should've probably skipped it altogether or summed it up in a one paragraph or politely pointed to some online resource.
  6. The speaker fumbled way too often on the command line. Stop using "clear", use "ctrl+l" to clear the screen. (hold on, is OpenSolaris using Bash by default?)
5.45pm, rushed to the Groovy and Grails session track. Boy, I have something serious to say about this.
  1. I was expecting to see some experts sum up to us the latest JRuby progress in this session.
  2. Why the heck is the description of the track about JRuby on Rails yet titled as Groovy and Grails? If I knew it was really on Groovy and Grails I would have skipped it and gone to the Porting Open Source Packages to OpenSolaris session.
  3. Mr Chuk Munn Lee, Sir, I don't think you did your homework on Grails. I sort of tuned out when I heard Mr Chuk said that Grails doesn't support many-to-many relationship. I thought I heard wrong, but he followed by explaining how you need to tweak some mappings to get that feature.
  4. The example on Groovy was too shallow and the Grails part was not good. I think the audience would appreciate what Grails is all about by starting the introduction to domain modeling and GORM instead of starting with "How many of you have programmed taglibs in JSP before?"
  5. Mr Arun Gupta was 3 seats away on my left -- he looked tuned out too. (Lol)
On my way out, I handed in my feedback form and was surprised to get a nice flap-over-bag. It's basically a small soft messenger bag. I'm happy to find the latest OpenSolaris 2008.11 inside. See the other goodies I got today below.

09 January 2009

Posted by Teo Choong Ping

at 5:59 PM

0 comments

Labels: , , ,

Consume RSS Feeds easily with Groovy and Rome

This is what I did to start consuming RSS feeds with Groovy within 20 minutes!

1. Download Rome.
2. Download Rome Fetcher.
3. Download JDOM is you haven't done so.
4. Extract rome-x.jar, rom-fetcher-x.jar and jdom.jar to a tmp directory -- I placed them in lib/.
5. Start your Groovy console with the classpath set to the jar files, like this:
$ groovyConsole -cp lib/rome-1.0RC1.jar:lib/rome-fetcher-0.9.jar:lib/jdom.jar
6. Use the code below:


import com.sun.syndication.fetcher.*
import com.sun.syndication.fetcher.impl.*
import com.sun.syndication.feed.synd.SyndFeed


FeedFetcherCache feedInfoCache = HashMapFeedInfoCache.getInstance();
FeedFetcher feedFetcher = new HttpURLFeedFetcher(feedInfoCache);
SyndFeed feed = feedFetcher.retrieveFeed(new URL("http://feeds.digg.com/digg/topic/programming/popular.rss"));


feed.entries.each {
println " -> ${it} "
}

println " == ${feed.entries?.size()}"


7. Finally, start reading the below docs:

Testing Grails Service class

Testing Grails service classes is easy if the service does not call any domain persistence methods. Meaning if your service class does cause some domain object to persist to database, it's going to be painful to try to mock the calls and check the result. And I'm not even sure if it's worth it to try.

The problem is that grails-testing newbies like me will want to try to do unit testing for services. In short, don't do that unless your service classes are simple and easy. (Keep this in mind when you start your project -- you won't see this unless you've experienced the pain before).

The best way that I found so far is to make service tests into integration tests. This mean putting service tests into the "integration" folder under the test directory. For more explanation on the difference between Unit Testing and Integration Testing in Grails, go here.

Testing Service classes is easy once you understand that it is:

  • it is an integration test -- will talk to the database
  • it is slow -- probably because of the data connection overhead
  • will persist data to database -- make sure your test environment database settings don't point to a production database
A typical service test looks like this:
class FooServiceTests extends GroovyTestCase {

def fooService

void setUp() {
fooService = new FooService // *1
fooService.otherService = new OtherService() // *2
}


void testServiceCall() {
def user = new User(name:"Test", email:"test@name.com")
user.save(flush:true) // *3
fooService.doSomething(user) // *4
assertEquals user.result, "expected result"
}

}
A couple of helpful points as indicated by the numbers above:
  1. You have to initialize the service class yourself, there is no DI.
  2. If the service has other service classes inside it, initialize and assign it manually
  3. Remember to always flush to persist to the database immediately -- else you might get weird things like no "id" for the supposedly saved domain object.
  4. In integration mode, fooService will act like a "headless" Grails app

I hope this is helpful to you -- I may not be right, so feedback and corrections are welcomed.

05 January 2009

Posted by Irregular Zero

at 5:51 PM

0 comments

Google Friend Connect & Facebook Connect

Google Friend Connect

A Google, Yahoo!, AIM or OpenID account can easily be used for third party authentication.

You start it off by logging into your Google account and going to http://www.google.com/friendconnect/.
  • From there, click on 'Set up a new site' and enter your site name and url.
  • You'll be given two files, canvas.html and rpc_relay.html, to copy onto your web site.
  • The last step is testing for those two files.
After that, it's a matter of choosing the gadgets you wish to add, customizing it, and then copying the code generated into one of your site pages. The code is normal HTML and Javascript.

From the current gadgets available, you can add on to your site to make it more 'sociable', like knowing the site members, adding in a chat box and reviewing/rating stuff.

You can create your own custom gadgets from these sites:
http://code.google.com/apis/gadgets/
http://code.google.com/apis/opensocial/

Facebook Connect

Only a Facebook account can be used for authentication with Facebook Connect.

Login into your Facebook account and follow the instructions located here:
http://wiki.developers.facebook.com/index.php/Trying_Out_Facebook_Connect

The main page for developers for Facebook Connect is http://developers.facebook.com/connect.php.

Facebook uses it's own Facebook Markup Language (FBML), in contrast to normal HTML, to facilitate creation of all Facebook applications. Facebook Connect is therefore embedded into user pages using FBML.

Facebook Connect is more of an expansion of Facebook onto other sites, depending on the application, it allows for data on a user site to be displayed back in Facebook.

HOW TO: Add Facebook Connect to Your Blog in 8 Minutes