Author Archive

Seriously, No BullFluff

Friday, October 5th, 2007

Last week’s No Fluff Just Stuff symposium was undoubtedly the best Java event I’ve attended thus far, and the icing on the cake was Brian Sletten’s talk on “Beyond Cute-sy Mashups”. It was worth showing up for that alone. It’s not very often that it happens, but I’m stoked.

Below is my newly updated ‘Bleeding Edge Learning Curve Road Map’:

No Fluff Just Stuff

Friday, September 28th, 2007

The day started curiously as I was waiting for the 57, where I came across a quaint wannabe bus driver from Somalia. Naturally, I asked him why he had opted for life over here in Canada. “Here the supermarkets don’t sell bullets side by side with the vegetables”, was his honest reply. I never did get his name, but he did manage to leave an impression.

Anyhow, arriving at the square dusky-coloured Delta hotel, Barbie presented me with my name tag for this year’s No Fluff Just Stuff Western Canada Software Symposium. I inquired if it wasn’t necessary to register, at which she bluntly retaliated, “Are you lying about having paid? Well, you look like a honest guy, but nice of you to ask!”. Charming.

Scott Davis kicked off the show, and before we knew it, he had bewildered us Java techies with some Groovy magic. As his finale, he had Grails spooning off a fully-CRUD enabled web app in a split-second jiffy. Admittedly Grails does hit that sweet spot, which no doubt will have me succumbing to its allure, yet one growing pet peeve I have with it is that it does come with shackles of its own. For one, it imposes its own build tool, namely gant. But since, for better or for worse, most of us use maven as our build tool of choice, i would cast an early warning to the coders behind Grails - choice is key.

Thus, and surprisingly so, the much talked about shiny new toy didn’t earn my first merit, instead the honour went to a talk on Agile testing strategies. Jared, a likable confectionery-throwing speaker, not only talked a good talk, he also walked the walk. Test Driven Development (TDD) is a notion that has been much paraded about on the Agile front, yet until now I have remained skeptical. Until now, I didn’t fully take on board what its potential benefits could be. Enlightened, I now realize that by using TDD this has the knock on effect of it driving the design, hence driving the developer in keeping the code testable, which in turn keeps it simple, modular, and loosely-coupled. Genius.

And with that, I will finish off Day 1 with the quote of the day:
“I can’t fix stupid” ~Jared Richardson’s take on dumb developers.

Sweet Online Reference Tool

Thursday, June 7th, 2007

Got API

Unit Test Your Web Security

Thursday, May 31st, 2007

Web-based business applications require stringent security measures. Within a secure website, a user must be authenticated by the system and for each different user role a predetermined set of authorization rights must be imposed. This isn’t anything new, and luckily, there exists an open source Java security framework, known as Acegi, which makes the job of keeping those hackers at bay a relatively straightforward one.

Acegi is a powerful, flexible security solution for the Java enterprise application. Working in tandem with its best friend, Spring, it provides applications with comprehensive authentication and authorization capabilities.

Integrating Acegi into your Spring enabled web application is generally an easy, although perhaps sometimes tedious, process of adding a bunch of XML wiring into your Spring context. And after you add that little extra touch of custom configuration for your specific web application, you are good to go.

Or are you? How do you know the thing actually works? And, more importantly, how can you be sure that it will continue to work for every project build? Here’s a JUnit test that shows you how.


package com.twopaths.test.core.security;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletException;

import org.acegisecurity.Authentication;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.ui.webapp.AuthenticationProcessingFilter;
import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockFilterConfig;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext;
import
  org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.ContextLoaderListener;

public class AcegiSecurityTest
  extends AbstractTransactionalDataSourceSpringContextTests {

  private static final String SECURITY_CONTEXT_CLASSPATH =
    "classpath:/com/twopaths/test/core/security-context.xml";

  private static final String TEST_USERNAME = "test";
  private static final String TEST_PASSWORD = "test";

  private MockServletContext servletContext;
  private MockFilterConfig mockConfig;
  private FilterChain mockFilterChain;
  private Filter authenticationFilter;

  @Override
  protected String[] getConfigLocations() {
    return new String[] {SECURITY_CONTEXT_CLASSPATH};
  }

  @Override
  protected void onSetUpInTransaction() throws Exception {
    // Insert user dummy data
    jdbcTemplate.execute("insert into end_user values(1, 'ROLE_USR', '" +
      TEST_USERNAME + "', '" +
      TEST_PASSWORD + "', 'true')");
  }

  @Override
  protected void onSetUpBeforeTransaction() throws Exception {
    // Init servlet context mock
    servletContext = new MockServletContext("");
    servletContext.addInitParameter(
      ContextLoader.CONFIG_LOCATION_PARAM,
      SECURITY_CONTEXT_CLASSPATH);

    // Init servlet context listener
    ServletContextListener contextListener = new ContextLoaderListener();
    ServletContextEvent event = new ServletContextEvent(servletContext);
    contextListener.contextInitialized(event);

    // Init filter config and filter chain mocks
    mockConfig = new MockFilterConfig(servletContext);
    mockFilterChain = new MockFilterChain();

    // Init authentication filter
    authenticationFilter = (Filter)
      this.getApplicationContext().getBean("authenticationProcessingFilter");
    authenticationFilter.init(mockConfig);
  }

  public void testThatTestUserLogsInOk() throws Exception {
    // Build mock request
    MockHttpServletRequest request =
      new MockHttpServletRequest("POST", "/j_acegi_security_check");
    request.setParameter(
      AuthenticationProcessingFilter.ACEGI_SECURITY_FORM_USERNAME_KEY,
      TEST_USERNAME);
    request.setParameter(
      AuthenticationProcessingFilter.ACEGI_SECURITY_FORM_PASSWORD_KEY,
      TEST_PASSWORD);

    // Build mock response
    MockHttpServletResponse response = new MockHttpServletResponse();

    // Run authentication filter
    authenticationFilter.doFilter(request, response, mockFilterChain);

    // Get authentication instance
    Authentication authentication =
      SecurityContextHolder.getContext().getAuthentication();

    // Verify authentication instance
    assertNotNull(authentication);
    assertEquals(TEST_USERNAME, authentication.getName());

    // Verify response redirected URL
    assertEquals("/home", response.getRedirectedUrl());
  }

}

Automating Asynchronous Jobs with Java 5 and Spring

Friday, May 25th, 2007

<< The Spiel >>

Java 5 brings a new arsenal of weaponry when it comes to creating highly scalable concurrent applications. The JVM has been improved to allow classes to take advantage of hardware-level concurrency support, and a rich set of new concurrency classes has been provided to make it easier to develop thread-safe, well-tested, high-performance concurrent applications.

The following code example makes full use of these new features and leverages the power of Spring to fully automate an asynchronous job to run periodically for a given duration (or forever if required). There is also a couple of extra goodies in the bag. Not only do jobs get kicked off, we also get a result back when they finish. And if the unimaginable happens and the job hangs, no problem, a timeout will occur, thus ensuring that no threads are left hanging around to hinder our application’s robustness.

<< The Brains >>

package com.twopaths.core.asynchronous;

import static java.util.concurrent.TimeUnit.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class AsynchronousProcessor<T>
    implements Runnable, ApplicationContextAware {

  protected final Log logger = LogFactory.getLog(this.getClass());

  protected static boolean started = false;

  private ScheduledFuture handle;

  // Specifies which bean in spring to instantiate as a new job
  // Default is job
  private String jobBean = "job";

  // Specified initial delay before kicking off the first job
  // Default is 1 second
  private int initialDelay = 1;

  // Specifies the delay between finishing and starting a new job
  // Default is 10 seconds
  private int delay = 10;

  // Specifies how long to wait for a job to complete before timing out
  // Default is 60 seconds
  private int timeout = 60;

  // Specifies how long job will keep running
  // Default is 1 hour. Set to zero to run forever.
  private int duration = 60 * 60;

  protected final ScheduledExecutorService scheduler =
      Executors.newScheduledThreadPool(1);
  protected final ExecutorService THREADPOOL =
      Executors.newCachedThreadPool();

  private ApplicationContext applicationContext;

  public void setApplicationContext(ApplicationContext applicationContext)
      throws BeansException {
    this.applicationContext = applicationContext;
  }

  public AsynchronousProcessor() {
    this.start();
  }

  protected synchronized void start() {
    if (!this.started) { // Ensures that it only starts up once
      this.started = true;
      final ScheduledFuture handle =
        scheduler.scheduleWithFixedDelay(this, this.getInitialDelay(),
        this.getDelay(), SECONDS);
      if (this.getDuration() > 0) {
        scheduler.schedule(new Runnable() {
          public void run() {handle.cancel(true);}
        }, this.getDuration(), SECONDS);
      }
      this.setHandle(handle);
    }
  }

  public void run() {
    try {
      Callable<T> job =
        (Callable<T>) applicationContext.getBean(this.getJobBean());
      T result = this.call(job, this.getTimeout());
      this.logger.info(result);
    } catch (Exception e) {
      this.logger.error("Exception occured when running job", e);
    }
  }

  protected <T> T call(Callable<T> c, long timeout)
      throws InterruptedException, ExecutionException, TimeoutException {
    FutureTask<T> t = new FutureTask<T>(c);
    THREADPOOL.execute(t);
    T result = t.get(timeout, SECONDS);
    return result;
  }

  public void destroy() {
    if ((this.getHandle() != null) && (!this.getHandle().isCancelled())) {
      this.getHandle().cancel(true);
    }
  }

  public String getJobBean() {
    return jobBean;
  }
  public void setJobBean(String jobBean) {
    this.jobBean = jobBean;
  }

  public ScheduledFuture getHandle() {
    return handle;
  }
  protected void setHandle(ScheduledFuture handle) {
    this.handle = handle;
  }

  public int getDelay() {
    return delay;
  }
  public void setDelay(int delay) {
    this.delay = delay;
  }

  public int getInitialDelay() {
    return initialDelay;
  }
  public void setInitialDelay(int initialDelay) {
    this.initialDelay = initialDelay;
  }

  public int getTimeout() {
    return timeout;
  }
  public void setTimeout(int timeout) {
    this.timeout = timeout;
  }

  public int getDuration() {
    return duration;
  }
  public void setDuration(int duration) {
    this.duration = duration;
  }

}

<< The Slave >>

package com.twopaths.core.asynchronous;

import java.util.concurrent.Callable;

public class HelloWorldJob<T> implements Callable<T> {

  private String message = "Hello World"; // default

  public String getMessage() {
    return message;
  }
  public void setMessage(String message) {
    this.message = message;
  }

  public T call() {
    return (T) message;
  }

}

<< The Glue >>

<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns=”http://www.springframework.org/schema/beans”>

  <bean id=”job”
  class=”com.twopaths.core.asynchronous.HelloWorldJob”
  scope=”prototype”/>

  <bean id=”asynchronousProcessor”
  class=”com.twopaths.core.asynchronous.AsynchronousProcessor”
  destroy-method=”destroy”/>

</beans>

Hibernate Tip of the Day - Is it a feature or a bug?

Thursday, May 10th, 2007

Annotations have undoubtedly been a breath of fresh air since coming onto the Java scene, but here’s one big slap in the face which you can’t help but feel is totally unwarranted.

I’m talking about mixing your field and method annotations in Hibernate. This really bares its ugly head when annotating relationships.

Let’s have a look-see at the following code snippet:

@Entity
public class Book {

@Id
@GeneratedValue
private Long id;
private Publisher publisher;

public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}

@ManyToOne
public Publisher getPublisher() {
return publisher;
}
public void setPublisher(Publisher publisher) {
this.publisher = publisher;
}
}

So what does Hibernate think of my code? Like a friend who you come to depend on just as they give you the slip and leave you in the lurch, it spits out this exiguous exception:

org.hibernate.MappingException: Could not determine type for: Publisher,
for columns: [org.hibernate.mapping.Column(publisher)]

The real conundrum though, is it a feature or a bug?

Unbelievably, Emmanuel Bernard, the project lead for Hibernate Annotations, states that this is a feature.

Well, Emmanuel, this is one feature (a.k.a. a mighty kick in the cojones) which we could all certainly do without.

It’s Not All About The Loonie

Friday, March 16th, 2007

Come one day last December, an illustrious day in the UK (i.e. rainy and miserable), I had my first heart warming conversation with Trevor, our PM at 2Paths. I had just come back from traveling for 12 months around the globe. Some might say I wasn’t in the mood to talk shop, but my mood much improved by the time our phone conversation had ended. It was my first work prospect since arriving back. It proved to be the first and the only one I was interested in, as a month or so down the line, I confidently got on a flight over to Vancouver and eagerly started my new job in the quirky neighbourhood of Gastown, where the 2Paths offices are located at.

The question remains (trust me, I get asked this a lot!), why did I pick Vancouver over anywhere else, and in all intents and purposes why 2Paths? The simple answer to both is that I got a good vibe. That’s the kind of person I am, or which I found myself becoming after my year’s travel. Motivated by instinct, and happiest when surrounded by people who share my mentality. At 2Paths, I have become accustomed to certain buzzwords, such as “thought leadership” and “agile development”. The difference here is that they signify something. More than that, it’s what we strive for.

Bottom line? I may not be making as much money as my tech buddies in London, but I’m having heaps of fun doing what I love, in a place I’m fast growing to love :)