Monday, August 15, 2011

Time cost for creating a HashSet from an ArrayList

I ran this simple test to get a "feel":
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Random;

public class Test {
 public static void main(String... args) {
  List<String> bigList = new ArrayList<String>();
  List<String> smallList = new ArrayList<String>();

  Random random = new Random();

  // builds a 10000 items list made of items
  // with string values generated from random
  // numbers between 1000000 and 1999999
  // this list has a higher chance to have duplicates
  for (int i = 0; i < 10000; i++)
   smallList.add(String.valueOf(random.nextInt(1000000) + 1000000));

  // builds a 1000000 items list made of items
  // with string values generated from random
  // numbers between 1000000 and 1999999
  for (int i = 0; i < 1000000; i++)
   bigList.add(String.valueOf(random.nextInt(1000000) + 1000000));

  int tests = 100;
  
  double smallListTransformationsTotalTime = 0;
  
  for (int i = 0; i < tests; i++) {
   long start = System.currentTimeMillis();
   new HashSet<String>(smallList);
   long end = System.currentTimeMillis() - start;
   smallListTransformationsTotalTime += end;
  }  
  System.out.println("Small list transformation average: " + (smallListTransformationsTotalTime / tests));
  
  double bigListTransformationsTotalTime = 0;
  
  for (int i = 0; i < tests; i++) {
   long start = System.currentTimeMillis();
   new HashSet<String>(bigList);
   long end = System.currentTimeMillis() - start;   
   bigListTransformationsTotalTime += end;
  }
  System.out.println("Big list transformation average: " + (bigListTransformationsTotalTime / tests));  
 }
}
Running this (100 tests) on my computer (i7 quad core using eclipse) yielded the following:

  • Small list transformation averaged 0.81ms 
  • Big list transformation averaged 196.31ms

Wednesday, April 27, 2011

Better late than never

Just a shout out to my dear friend and colleague Shai Raiten for getting his MVP award for the third year in a row.

Shai is an exceptionally gifted professional, engaged in software development, consulting and lecturing on a daily basis. He is also funny as hell and fun to be around... what more can you ask for? :)

So, Mazal tov!!!

P.S See this post for the "official announcement"

Saturday, April 23, 2011

Funky behavior of CSS Universal selector in Google Chrome Developer tools

Although its the middle of the night and I'm in an intense work / implementation session for one of the startups I work with (zbang.it) I had to pause for this.

I was on the brink of loosing my sanity because of this weird problem where styles were merged with each other, when inspecting elements in Google Chrome developer tools (v10.0.648.205).

First, here is the style sheet (or some of it), please note the CSS Universal selector at the beginning:
*
{
    vertical-align: baseline;
    font-weight: inherit;
    font-family: inherit;
    font-style: inherit;
    font-size: 100%;
    border: 0 none;
    outline: 0;
    padding: 0;
    margin: 0;
}

body
{
    font-family: Calibari, Arial;
    font-size: 12px;
}

div.ui-layout-east
{
    width: 250px;
    float: right;
}

div.ui-innerLayout-north
{
    height: 70px;
}

.
.
. 
more css down here
Here is how it looked while inspecting div.ui-layout-east on Google Chrome developer tools:


Take a good look at the highlighted height: 70px, its jumped up from div.ui-innerLayout-north, don't believe me? I didn't believe myself at first, so I added a super noticeable style to div.ui-innerLayout-north, like so:
*
{
    vertical-align: baseline;
    font-weight: inherit;
    font-family: inherit;
    font-style: inherit;
    font-size: 100%;
    border: 0 none;
    outline: 0;
    padding: 0;
    margin: 0;
}

body
{
    font-family: Calibari, Arial;
    font-size: 12px;
}

div.ui-layout-east
{
    width: 250px;
    float: right;
}

div.ui-innerLayout-north
{
    height: 70px;
    border: 3px dashed red;
}

.
.
. 
more css down here
And, lo and behold


It jumped right up again!!!

At first I thought that I had a css syntax error somewhere but by way of elimination and after a long while I found out that this behavior happens only when the universal selector is the first style on the style sheet, and if its location changes:
body
{
    font-family: Calibari, Arial;
    font-size: 12px;
}

*
{
    vertical-align: baseline;
    font-weight: inherit;
    font-family: inherit;
    font-style: inherit;
    font-size: 100%;
    border: 0 none;
    outline: 0;
    padding: 0;
    margin: 0;
}

div.ui-layout-east
{
    width: 250px;
    float: right;
}

div.ui-innerLayout-north
{
    height: 70px;
    border: 3px dashed red;
}

.
.
. 
more css down here
The universe goes to being expected again:


By the way this does not affect the actual HTML in the browser, only the display in developer tools.

Wasted a little over an hour of my life, hope it saves you one.

Thursday, April 21, 2011

Yet Another Facebook Search

Hi,

Check out this website:

http://www.yetanotherfacebooksearch.com

Which helps you search facebook for people, groups and pages. You will also get relevant results about a person and his friends, outside of facebook. This facebook search doesn't requires you to login as well.

Saturday, April 2, 2011

A simple AppEngine Guice Module (Part 1)

This post is about a simple Guice AppEngine module I've written, which I find very useful, hence, I decided to share it.

The code is available here

The module will get your AppEngine project started quickly, here is a typical bootstrap (GuiceServletContextListener) code for a simple app:
package com.codeark.appengine;

import com.codeark.appengine.objectify.ObjectifyModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.servlet.GuiceServletContextListener;

public class Bootstrap extends GuiceServletContextListener {

 @Override
 protected Injector getInjector() {

  Module aeModule = 
   AppEngineModule.build().withDatastoreService()
    .withUrlFetchService().withMemcacheService().withMailService();

  Module myModule = new MyOtherModule();
  
  return Guice.createInjector(aeModule, myModule);
 }
}
The module's Fluent Interface API(which I like so much) exposes a single static build() method which returns an instance of the module. You can then configure which services AppEngine should initialize using the .With*Service() methods.

later you can do:
class Classy {
 @Inject
 public Classy(MemcacheService service, MailService mail) {
 ...
 }
}
There are several other goodies included in the source, which I will discuss in later posts: A simple abstraction over UrlFetchService and an Objectify module.

Sunday, October 31, 2010

null is null ?

Here is a funny error message on Internet Explorer:


:-)

Friday, October 8, 2010

How does a dog shortens your notebook's battery life?

A few months ago I purchased a new battery for my laptop and was quite disappointed that within a short period of time, I experienced a severe drop in battery life. As days went by, I noticed that my laptop's fan is doing overtime, even on a power saver plan, so I've decided to open up the patient and see whats going on.

I was not that surprised to find a nice chunk of my dog's hair and dust piled up between the heat sink and the cooling fan. As a result, heat wasn't getting transferred properly and thus the computer kept the cooling fan in "overdrive" all the time and as a result, battery life plummeted.

Here is how it looked before cleaning (apologize for the slight blur in the pictures):



And after I cleaned it up:


Here is my dog, her name is Layla:



And finally, I want to express my sincere thanks to insidemylaptop.com for their guide on how to disassemble an HP 530 notebook, It's an old model, I know, but it still carries me :-)

Friday, September 24, 2010

Has my cables provider's billing system been compromised?

My cable provider (internet and telephony infrastructure) in Israel is a company called HOT. I get my invoices from their service into my mail, and this morning I got this email:


This email's title is in hebrew, translated it says: "A notification about a change in billing service username" (roughly) the sender seems to be HOT but in fact it is not, as you can see, the red arrow points to the real underlying email address: "newsletter@em-sender1.com", this is how it looks normally (green arrow):


Normally, links in emails coming from HOT billing service lead to https://mybills.hot.net.il/something, e.g (green arrow):


However, in the suspicious email the links looks very... err... suspicious :)
(red arrow again)


So this email is either a very unwise attempt to use some external email sending service or, and I stress the OR, it means someone is trying a phishing move. I find it hard to believe someone would try such a specific phishing email on a random bank of emails...

My only logical conjecture is: the sender had access to a list of HOT customers (business customer in my case), which is a very scary conjecture, one that I hope will be proven wrong...


UPDATE:


Further investigation reveals that em-sender*.com might be connected to a company called inwise.com. Hmmm... this mail might be legit after all...

Friday, September 17, 2010

Wednesday, September 8, 2010

Using Facebook Javascript SDK in your Blogger blog (Like button example)

Before you go any further you must read (and implement) my post about open graph:

Teach your Blogger Blog to speak Facebook's open graph protocol

Open your blogger design interface and goto edit html and find the body opening tag (search page for <body). In another browser window open this reference url on facebook's developers site: http://developers.facebook.com/docs/reference/javascript/ copy the code there and paste it right after the body tag in your blogger template. The code snippet you just pasted should contain the following text: appId: 'your app id' (if it doesn't then facebook might have changed something and this post might not be relevant anymore). 

If you properly followed the previous post (teach your blogger...) then you should have a Page on facebook for your blog by now, Go to it. We need the ID of that page, we can copy it from the address bar of our browser:


See the yellow marked number thats the ID of the page, copy it and paste it instead of your app id text (leave the single quotes in tact) in the code snippet we copy pasted from facebook. Save the template! :)

Time to add a like button to each post but first, make sure the Expand widget template checkbox is checked in your template editor:


I've decided to place the like button beneath the title of each post and at the end of it, the exact position in the template depends on your blogger's template, when you locate the desired spot, paste the following code in it:
<!-- facebook local post like button -->
     <b:if cond='data:post.link'>
       <fb:like expr:href='data:post.link' layout='button_count' show_faces='false' width='200'/>
     <b:else/>
        <b:if cond='data:post.url'>
       <fb:like expr:href='data:post.url' layout='button_count' show_faces='false' width='200'/>
        <b:else/>
       <fb:like expr:href='data:url' layout='button_count' show_faces='false' width='200'/>
        </b:if>
     </b:if>
<!-- facebook local post like button -->
And that should be it. If everything went right you should now see a like button on your blog, try it... and please try my button too ;-)

Using Blogger data tags inside script tags

Template will look like this:
<script type='javascript'>
var url='<data:blog.url/>';
</script>
And the rendered result will look like this:
<script type="javascript">
var url='http://blog.yanivkessler.com/';
</script>

Concatenating text in blogger data tags

I was messing around with my blogger template, testing the best way to integrate a facebook Like button into posts (this due to numerous demands to see how its done properly and not in a side bar).

One of the methods I tested required me to generate different ids for different posts and the most logical way to do so would be to use to post id somehow. I searched the reference on blogger support but couldn't find any example, so I looked inside some templates and I found an example. So in the template we type this:
<span expr:id='&quot;myId&quot; + data:post.id'></span>
Please note that I have to use encoded quotes to surround the text and concatenate using the plus sign. This html will be rendered as a result by blogger engine:
<span id='myId8712387612387612'></span>

Monday, July 12, 2010

Teach your Blogger Blog to speak Facebook's open graph protocol

In your blog's control panel goto the Design tab and select Edit HTML. Find a tag called "<head>" (ctrl+f if you can't find it quickly) and add this code right after it:
<!-- Facebook open graph --> 

<b:if cond='data:blog.pageType == &quot;item&quot;'>
    <meta expr:content='&quot;the post: &quot; + data:blog.pageName' property='og:title'/> 
    <meta content='article' property='og:type'/> 
</b:if>

<b:if cond='data:blog.pageType == &quot;archive&quot;'>
    <meta expr:content='data:blog.pageName + &quot; posts&quot;' property='og:title'/> 
    <meta content='article' property='og:type'/> 
    <meta expr:content='data:blog.pageTitle' property='og:description'/> 
</b:if>

<b:if cond='data:blog.pageType == &quot;index&quot;'>
    <meta content='the blog' property='og:title'/> 
    <meta content='blog' property='og:type'/> 
    <meta content='Put your helmet on!' property='og:description'/> 
</b:if>

<meta expr:content='data:blog.url' property='og:url'/> 
<!-- REPLACE THIS WITH YOUR OWN IMAGE -->
<meta content='http://3.bp.blogspot.com/_XnhytjnfyaU/TBI7ItnIPII/AAAAAAAABJY/SJRWM5RHDgI/S1600-R/header.png' property='og:image'/> 
<meta content='625752324' property='fb:admins'/> 
<meta expr:content='data:blog.title' property='og:site_name'/> 

<!-- Facebook open graph --> 
Here is a break down of whats going on here:
This code is specific for item (post) pages, it tells facebook that the title for this page should be The post: <post name here> and the graph object type is article (this tells facebook that the content is transient, see link to reference at the end of this post).
<b:if cond='data:blog.pageType == &quot;item&quot;'>
    <meta expr:content='&quot;the post: &quot; + data:blog.pageName' property='og:title'/> 
    <meta content='article' property='og:type'/> 
</b:if>
The result on the user's wall will look like this:

Next:
This code handles archive pages (like this one) and will tell facebook that the title should be <month year> posts e.g. December 2008 posts.
<b:if cond='data:blog.pageType == &quot;archive&quot;'>
    <meta expr:content='data:blog.pageName + &quot; posts&quot;' property='og:title'/> 
    <meta content='article' property='og:type'/> 
    <meta expr:content='data:blog.pageTitle' property='og:description'/> 
</b:if>
The result on the user's wall will look like this:

Next:
Code to handle data in our blog's index (homepage), this will tell facebook that the title is the blog and the type of the graph object is blog. I also specified a static description text: put your helmet!
<b:if cond='data:blog.pageType == &quot;index&quot;'>
    <meta content='the blog' property='og:title'/> 
    <meta content='blog' property='og:type'/> 
    <meta content='Put your helmet on!' property='og:description'/> 
</b:if>
The result on the user's wall will look like this:

Finally, we're telling facebook about some general stuff:
Here we wire the current page's url to the open graph protocol's url property:
<meta expr:content='data:blog.url' property='og:url'/> 
The image facebook uses all around when displaying our graph object on facebook (If you don't replace this with your own image, you'll get my blog header image):
<meta content='http://3.bp.blogspot.com/_XnhytjnfyaU/TBI7ItnIPII/AAAAAAAABJY/SJRWM5RHDgI/S1600-R/header.png' property='og:image'/>
The user id (or ids) of the facebook profiles that administer this page (see how to find your user id here):
<meta content='625752324' property='fb:admins'/> 
A title for the site:
<meta expr:content='data:blog.title' 
property='og:site_name'/> 
Basically in places where we want a dynamic blogger property we use expr:<attribute>='<blogger data expression>' instead of simple html attributes like context="My title".

If you want to see how Facebook reads your open graph protocol metadata you can use Facebook's URL Linter.

Here you'll find the Open Graph Protocol's reference.

For more information, please see my post on how to use Facebook Javascript SDK from your blog and properly add a "like" button to your posts.

Also, check out some cool blogger books on amazon: Search Amazon.com for blogger

Wednesday, June 23, 2010

Another parent child relationship pitfall (jdo)

Its a rookie's mistake but it stole an hour of my life, so at least I hope this will save someone else's time. I was making an experiment on AppEngine with big collections and I wrote these very simple parent and child classes to help in my test:
@PersistenceCapable
public class ParentWithBidiOwnedChildren {

 @Persistent(mappedBy="parent")
 private Set<ChildWithBidiOwningParent> children;

 public ParentWithBidiOwnedChildren() {
  children = new HashSet<ChildWithBidiOwningParent>();
 }

 @PrimaryKey
 @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
 public Key id;

 public void addNewChild() {
  children.add(new ChildWithBidiOwningParent(this));
 }

 public Set<ChildWithBidiOwningParent> getChildren() {
  return children;
 }
}
And child:
@PersistenceCapable
public class ChildWithBidiOwningParent { 
 
 @PrimaryKey 
 @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
 public Key id;
 
 @Persistent
 private final ParentWithBidiOwnedChildren parent;

 public ChildWithBidiOwningParent(ParentWithBidiOwnedChildren parent) {
  this.parent = parent;  
 }

 public ParentWithBidiOwnedChildren getParent() {
  return parent;
 }
}
In Eclipse IDE when you hit ctrl+1 you can quickly create a member field from a constructor parameter:

Eclipse generates a final field which is recommended and desirable in most cases:

What happens next, when you try to persist a parent, you get an exception:

javax.jdo.JDOUserException: Class "com.codeark.appengine.bigcollections.ParentWithBidiOwnedChildren" has collection field "children" and this has no mapping in the table for the element class "com.codeark.appengine.bigcollections.ChildWithBidiOwningParent" owner field "parent"

Immediately I started looking for an error in my annotations, but the smoking gun was that auto generated final keyword, so here is the correct child code:
@PersistenceCapable
public class ChildWithBidiOwningParent { 
 
 @PrimaryKey 
 @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
 public Key id;
 
 @Persistent
 private ParentWithBidiOwnedChildren parent;

 public ChildWithBidiOwningParent(ParentWithBidiOwnedChildren parent) {
  this.parent = parent;  
 }

 public ParentWithBidiOwnedChildren getParent() {
  return parent;
 }
}
That was a very unpleasent hour for me :-)

Friday, June 11, 2010

Tuesday, June 8, 2010

Lightweight JDO Persistence Filter using Guice

Here is a very lightweight and simple PersistenceFilter for your Guice powered webapps:
@Singleton
public class PersistenceFilter implements Filter {

 private final Provider<PersistenceManager> pmp;

 @Inject
 public PersistenceFilter(Provider<PersistenceManager> pmp) {
  this.pmp = pmp;
 }

 @Override
 public void destroy() {
 }

 @Override
 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  PersistenceManager pm = pmp.get();
  try {
   chain.doFilter(request, response);
  } finally {
   pm.close();
  }
 }

 @Override
 public void init(FilterConfig arg0) throws ServletException {
 }
}
This is no replacement for warp-persist and the soon to come guice persistence support, but look how simple it is, I love it! :-)

So how does this work? the "magic" is done by using Guice scoping, basically PersistenceManager is tied to the Request scope and all we have to do is close it at the end of the request. I'm going to show this in the context of an AppEngine application (cuz thats what I'm working on right now), so here is our web.xml:
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
 version="2.5">

 <filter>
  <filter-name>guiceFilter</filter-name>
  <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
 </filter>

 <filter-mapping>
  <filter-name>guiceFilter</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>

 <listener>
  <listener-class>com.codeark.persistencefilterexample.Bootstrap</listener-class>
 </listener>
</web-app>
Its an ordinary, run of the mill Guice powered webapp web.xml config file (see this post if you're using wicket, and why...)

The Bootstrap listener looks like this:
public final class Bootstrap extends GuiceServletContextListener {

 @Override
 protected Injector getInjector() {
  return buildInjector();
 }

 public Injector buildInjector() {  
  Injector infrastructure = Guice.createInjector(    
    new AppEngineModule(), 
    new PersistenceModule(), 
    new WebModule());

  return infrastructure;
 }
}
AppEngineModule handles the bindings of GAE specific services:
public class AppEngineModule extends AbstractModule {
 
 private static final PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory("transactions-optional");
  
 public AppEngineModule() {  
 }

 @Override
 protected void configure() {
 }
 
 @Provides
 PersistenceManagerFactory providesPersistenceManagerFactory() {
  return pmf;
 }

 @Provides
 UserService providesUserService() {
  return UserServiceFactory.getUserService();
 }
 
 @Inject
 @Provides
 @SessionScoped
 User providesCurrentUser(UserService userService) {
  return userService.getCurrentUser();
 }
}
Please note the providesPersistenceManagerFactory() which localizes the use of static state to this module only. Additionally, diverging from the main topic of this post, take a look at providesCurrentUser(UserService userService) which simply allows you to Inject the current Google Account User (if one is logged in this session) anywhere in your code, its really handy.

Now comes the PersistenceModule:
public class PersistenceModule extends AbstractModule {
 
 public PersistenceModule() {  
 }

 @Override
 protected void configure() {
  bind(PersistenceManager.class).toProvider(PersistenceManagerProvider.class).in(RequestScoped.class);
  bind(DataService.class).to(DataServiceImpl.class); 
 } 
}
The most important line here is the first one where we bind PersistenceManager to the request scope. The provider follows:
public class PersistenceManagerProvider implements Provider<PersistenceManager> {

 private final PersistenceManagerFactory pmf;

 @Inject
 public PersistenceManagerProvider(PersistenceManagerFactory pmf) {
  this.pmf = pmf;  
 }

 @Override
 public PersistenceManager get() {
  return pmf.getPersistenceManager();
 }
}
I could have used a @Provides method in PersistenceModule instead, but that would force me to inject PersistenceManagerFactory into PersistenceModule and I like to avoid module injection where possible.

Last but not least, WebModule:
public class WebModule extends ServletModule {
 
 @Override
 protected void configureServlets() {
  filter("/*").through(PersistenceFilter.class);  
  serve("/test").with(TestServlet.class);  
 }   
}
It is important that PersistenceFilter will precede any other filters or servlets that need persistence (see Dispatch order in Guice documentation) otherwise you might end up with a closed persistence manager.

Finally, our test servlet which uses persistence via DataService:
@Singleton
public class TestServlet extends HttpServlet {

 private final DataService dataService;
 private final Provider<User> currentUser;

 @Inject
 public TestServlet(DataService dataService, Provider<User> currentUser) {
  this.dataService = dataService;
  this.currentUser = currentUser;
 }

 public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {

  resp.setContentType("text/plain");

  User current = currentUser.get();

  if (current == null) {
   resp.getWriter().println("You are not signed in to your google account, but Hello, world! anyways :-)");
  } else {
   resp.getWriter().println(String.format("Hello, %s", current.getNickname()));
   //records user and ip in datastore
   dataService.persist(new MyEntity(current, req.getRemoteAddr()));
  }
 }
}
The DataService implementation looks like this:
public final class DataServiceImpl implements DataService {
 
 private Provider<PersistenceManager> pmp;
 
 @Inject
 public DataServiceImpl(Provider<PersistenceManager> pmp) { 
  this.pmp = pmp; 
 }
 
 @Override
 public <T> T persist(T instance) {
  return pmp.get().makePersistent(instance);
 }

 @Override
 public void delete(Object instance) {
  pmp.get().deletePersistent(instance);
 } 
}
To summarize:
  1. PersistenceManager is bound to a Request Scope, each request has its own PersistenceManager instance.
  2. The PersistenceFilter is configured at the beginning of the request dispatch chain, its main role is to close the PersistenceManager at the end of each request.
  3. Data Aware classes like DataServiceImpl use PersistenceManager by means of a Guice Provider (direct injection of PersistenceManager will impose a scope restriction on when we can instantiate classes that use it, so I think its best to avoid it)
As explained at the beginning of the post, this implementation is good for prototyping and small projects, for large / complex projects I'd go with a more solid, tested and much more capable framework (like warp-persist and guice-persist when it comes out)

The source is available in the form of an eclipse project here:


You will need Google AppEngine Eclipse plugin to make it work.

Tuesday, June 1, 2010

Writing unit tests for Guice and Wicket

There are excellent frameworks out there for bringing the Guice power into your JUnit tests, like AtUnit or GuiceBerry, however, for the sake of simplicity, this post builds upon a simple Test Runner class described in another post written in 2008 by Gili Tzabari about Guice and JUnit4 integration.

Here is a very simple MyGuiceTestRunner implementation:
public class MyGuiceTestRunner extends GuiceTestRunner {
 public MyGuiceTestRunner(Class<?> classToRun) throws InitializationError {
  super(classToRun, new WebModule(), new MyModule(), new HibernateModule());
 }
}
And here is an abstract wicket test to ease our work later:
@RunWith(MyGuiceTestRunner.class)
public class AbstractWicketTest {
 
 private final WicketTester wicketTester;
 
 protected final WicketTester getWicketTester() {
  return wicketTester;
 }

 public AbstractWicketTest(Injector injector) {
  wicketTester = new WicketTester();
  WebApplication app = wicketTester.getApplication();
  app.addComponentInstantiationListener(new GuiceComponentInjector(app, injector));
 }
}
Some points of intrest in this implementation:
  • Class is annotated with @RunWith, this tells JUnit to use MyGuiceTestRunner to run this test (and subclasses too).
  • In the constructor we create a WicketTester which in turn will create a dummy wicket web application for us (BaseWicketTester.DummyWebApplication is the exact type). If we need a custom application we could simply use other WicketTester constructors that take an Application instance and use it instead of the inner dummy one.
  • Once a WicketTester instance was created, we add attach a GuiceComponentInjector just like we would in a normal guicey wicket web application.
In a typical test subclass of AbstractWicketTest we get a reference to the injector using constructor injection (remember this test is injectable because it is being run by MyGuiceTestRunner):
public class SampleWicketTest extends AbstractWicketTest {
 
 @Inject
 public SampleWicketTest(Injector injector) {
  super(injector);
 }

 @Test
 public void test() {
  WicketTester wicketTester = getWicketTester();
  wicketTester.startPage(TestPage.class);
  wicketTester.assertRenderedPage(TestPage.class);
  wicketTester.assertLabel("meow", "Testing 1 2 3");
 }
}
For the sake of completeness, here is the code for the test page itself (html markup omitted):
public class TestPage extends WebPage { 
 
 @Inject private IService service;
 
 public TestPage() {
  add(new Label("meow", "Testing 1 2 3"));
  service.doSomething();
 } 
}
Thats it, you are now free to write Guice powered tests for your Guicey Wicket pages.

Enjoy :-)

Wednesday, May 26, 2010

Wicket and Guice integration: an alternate route...

This post details a slightly different way of integrating Apache Wicket and Google Guice.

Many posts, reference docs and demos I've seen on the Internet so far, do not employ one of my most favorite features in Guice: the ServletModule to configure Wicket's filter. I really like this feature because I really don't like configuration files and the Web Descriptor (a.k.a web.xml) file is one of the most disliked of them all :) but Thanks to Guice this file's annoyance goes almost unnoticed.

So just to make it clear, the purpose of this integration is to bypass wicket's filter configuration in web.xml and put it in code instead.

Before we start here are several links to posts and reference docs about Wicket and Guice integration that are more common (but do use web.xml to config wicket):

Wicket Guice GuiceWebApplicationFactory javadoc
Alastair Maw’s blog - Wicket gets guicy
Wicket examples - Guice
Atomic Gamer dev blog - Wicket, Guice and Warp-Persist

We start with the web.xml file:
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
 version="2.5">

 <filter>
  <filter-name>guiceFilter</filter-name>
  <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
 </filter>

 <filter-mapping>
  <filter-name>guiceFilter</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>

 <listener>
  <listener-class>com.codeark.wicketguicealt.Bootstrap</listener-class>
 </listener> 
</web-app>
This web.xml only configures Guice filter and a GuiceServletContextListener as per the instructions here.

The Bootstrap class loads our modules:
public final class Bootstrap extends GuiceServletContextListener { 
 @Override
 protected Injector getInjector() {  
  return Guice.createInjector(new MyModule(), new WebModule());
 } 
}
The binding and configuration of Wicket happens in WebModule (a subclass of ServletModule):
public class WebModule extends ServletModule {
 
 @Override
 protected void configureServlets() {
  bind(WebApplication.class).toProvider(WicketGuiceAppProvider.class);
  
  // avoids "Error initializing WicketFilter - you have no <filter-mapping> element..." 
  // IllegalArgumentException
  Map<String, String> params = new HashMap<String, String>();  
  params.put(WicketFilter.FILTER_MAPPING_PARAM, "/*");
  
  filter("/*").through(WicketGuiceFilter.class, params);
 }
} 
In the first line of configureServlets() we bind WebApplication to a provider, this provider will be our real application factory and will do all the work instead of GuiceWebApplicationFactory.

The GuiceWebApplicationFactory implementation requires that the injector will be stashed in the Servlet Context or that modules will be listed in the web.xml in an init-param like this:
<init-param>
        <param-name>module</param-name>
        <param-value>com.company.MyModule,com.company.MyOtherModule</param-value>
</init-param>
I think both options contradicts the real notion of Guice: "Rather than using an external XML file for configuration, Guice modules are written using regular Java code. Java is familiar, works with your IDE, and survives refactoring" and therefor I opted not to use GuiceWebApplicationFactory. Here is the provider we will use:
public class WicketGuiceAppProvider implements Provider<WebApplication> {
 
 private final Injector injector;

 @Inject
 public WicketGuiceAppProvider(Injector injector) {
  this.injector = injector;  
 }
 
 @Override
 public WebApplication get() {
  WicketGuiceApp app = new WicketGuiceApp(injector);  
  return app;
 }
}
It would be awesome if we could call addComponentInstantiationListener(new GuiceComponentInjector(app, injector)) here instead of passing the injector in the constructor (on injecting it) but GuiceComponentInjector uses InjectorHolder in its constructor:
public GuiceComponentInjector(Application app, Injector injector)
{
 app.setMetaData(GuiceInjectorHolder.INJECTOR_KEY, new GuiceInjectorHolder(injector));
 InjectorHolder.setInjector(this);
}
and InjectorHolder has a dependency on the application instance being tied to the current thread (Application.get() uses ThreadLocal):
public static void setInjector(ConfigurableInjector newInjector)
{
 Application application = Application.get();
 application.setMetaData(INJECTOR_KEY, newInjector);
}
Consequently, we can only call addComponentInstantiationListener() after Application.set() is called and the best place to do so is in the init() method of our WebApplication implementation. we could use Application.set() ourselves (tried that and it works fine) but the scary warnings in the javadoc are scary :-), so here is our WicketGuiceApp class with its init() method:
public class WicketGuiceApp extends WebApplication {
 
 private transient Injector injector;
 
 public WicketGuiceApp(Injector injector) {
  this.injector = injector;  
 }
 
 @Override
 protected void init() {  
  addComponentInstantiationListener(new GuiceComponentInjector(this, injector));
 }

 @Override
 public Class<? extends Page> getHomePage() {
  return HomePage.class;
 }
}
Please note that I've marked the Injector as transient. Under the hood, GuiceComponentInjector will handle the Injector's reference serialization and deserialization.

Back to WebModule, the second important thing we do in configureServlets() is to configure the Wicket filter and filter mapping. We are using our own WicketFilter subclass called WicketGuiceFilter in order to utilize our provider and wire it into wicket's IWebApplicationFactory:
@Singleton
public class WicketGuiceFilter extends WicketFilter {

 @Inject private Provider<WebApplication> appsProvider;
 
 @Override
 protected IWebApplicationFactory getApplicationFactory() {
  return new IWebApplicationFactory() {   
   @Override
   public WebApplication createApplication(WicketFilter filter) {    
    return appsProvider.get();
   }
  };
 } 
}
The reason I chose to subclass WicketFilter instead of doing this inside configureServlets():
Map<String, String> params = new HashMap<String, String>();
 
 params.put(WicketFilter.APP_FACT_PARAM, WicketGuiceAppFactory.class.getName());
 filter("/*").through(WicketFilter.class, params);
Is that WicketFilter instantiates the factory via reflection and the prevents Guice from doing its work.

This concludes our integration, would love to hear any comments.

You can download just the full source of this post and web.xml here

OR

You can download a full eclipse dynamic web project with dependencies included, you will need to import it to your workspace and reconfigure a servlet container runtime (such as apache tomcat) before you can build.

OR

Get the above eclipse project via svn or simply browse the code for your convenience here:
https://www.codeark.com/svn/wicket.guice.alt/trunk
This repository is read only for anonymous access.

Thursday, May 13, 2010

HOWTO: Open a webpage programmatically in an android java application

Using an intent like this:

Intent intent = new Intent("android.intent.action.VIEW", Uri.parse("http://www.codeark.com"));

try {
 this.startActivity(intent);
} catch (ActivityNotFoundException ex) {
 // do something about the exception, or not ...
}


"this" is the Context.

more info here: Context.startActivity()