Thursday, 10 October 2013

Ubuntu - restarting your network

Don't forget that when you do this over an ssh/putty session then your connection will be dropped:

sudo ifdown -a
sudo ifup -a
sudo /etc/init.d/networking restart

Monday, 24 June 2013

Wordchain puzzle

Word Chains


Taken from http://codekata.pragprog.com/2007/01/kata_nineteen_w.html

Write a program that solves word-chain puzzles:

Find a chain of words start starting with one particular word and ending with another. Successive entries in the chain must all be real words, and each can differ from the previous word by just one letter. For example, you can get from "cat" to "dog" using the following chain.
 
    cat
    cot
    cog
    dog
 
The objective of this kata is to write a program that accepts start and end words and, using words from the dictionary, builds a word chain between them. Find the shortest word chain that solves each puzzle

You can turn lead into gold with the following chain:
     
    lead
    load
    goad
    gold
 
Try to capture the developer mindset and record how you to got to you solution.

Development process


How did I get to my solution ?  It's all about covergence.  I start out and see where it goes, see what ideas pop up as I go along, see what sticks etc.  My generate approach is as follows:

1) Write Tests - this gets me thinking about how should I represent the data, and helps drive the interface.
2) Start writing code
3) Get to a working solution (it's not always pretty at this point)
4) Refactor Refactor Refactor until I hit a universal truth ie. the code becomes so simple it must be true!

To solve a problem I generally have a series of insghts - by this I mean ideas which seems obviously the right thing to do and possibly are a deep truth of the solution.

Definitions:

distance - Given a "from" word and a "target" the distance is defined to be the number letters which would need to be changed in the "from" word to mutate it to the "target" word.  ie.  cat -> bot has a distance of 2

Here we go:


Write the unit tests - this brings the first decision - should I use List<String>'s or arrays [] to represent the dictionary? Choose [] as it makes the unit tests slightly more readable.

Thought - its going to be difficult testing with a large dictionary having to search through 1000's of words, multiple roots through the wordchain "space".


  • Insight 1: Allow the tests to define the dictionary.


Idea - find a word in the dictionary which has a distance of 1 from the current word, but also contains at least 1 letter contained in the "to" word.  ie. for the wordchain cat -> dog then cot is 1 from cat and 2 from dog.  The only downside is that this strategy will only work for some word chains...

   "cat", "cot", "cog", "dog"

coding.....

The code is getting fairly complictated - theres lots of edgecases.
Idea - I'll need to keep track of words I've tried which result in dead ends.  Can I exclude these ?  from future searched or can  I?

coding.....

What happens if I need to go to a word which has no letters in common with the target word?  This is starting to get too complicated.  What I have learned is that I some how need to keep track of what wordchains I've visited which have resulted in deadends.

Idea - I'm thinking that the most reliable solution would be to brute force this, ie. work out every possible word chain.  This will produce some long chains.  Some of the chains would be dead ends and these can be discounted. Visually a brute force approach would look like a word chain tree with branched coming of branches etc.


  • Insight 2: Think of the word chains as a tree to which we can prune dead branches.
  • Insight 3: Use self recursion
  • Insight 4: Use a stack to represent the branches


I'd need to model this tree as a Map<String, Stack<String>> with the key to the map being the root of the branch.

coding ...

This is looking better.  Can I get rid of the Map ?  I think I'm on the right track as the code is getting simpler.  The self recursion is looking good.

Amazing! - I've got something that works, my unit tests are passing.  The sef recursion involves passing a lot of things around which is not ideal, but this a break through.  I can now run refactor run my tests, refactor, run my tests etc. I can now drive hard at the solution and hopefully glean some more insights.

Time to bring in the full size dictionary.  As expected some very long chains are created 50+.  How can I reduce this ?  What about converging from either direction ?  ie dog -> cat and cat -> dog.  Interestingly coming from a different direction reduces the chain length.  The size seems to be dependent on the ordering of the dictionary.

Idea -> Generate a word chain which may contain 30 words.  Randomly shuffle the words then use this list to form the dictionary for another run and so on.  How many times would I need try.  This would by an interesting experiment - I could converge on a word chain by pure luck :)


  • Insight 5:  Backup the chain when the number of words in the chain exceeds some limit


In this way the algorithm will do the pruning for me.  1 line of code !!!
 
if ( stack.size() > maxDepth ) return false;  // prune checkout

Refactor refactor refactor...


I'm going to split the code up so that the algorithm is concentrated in once class to demonstrate the simplicity of the solution.  The recursive algorithm itself is defined in 10 lines of code.

enough.... :)

Here's my solution


public class WordchainImpl implements Wordchain {
    private String [] dict;
    private int depth;

    public WordchainImpl(String[] wordList, int depth) {
        this.dict = wordList;
        this.depth = depth;
    }

    public WordchainImpl(String[] wordList) {
        this(wordList, 10);
    }


    public String [] getChain( String from, String to ) {
        // check that from and to exists
        if ( ! ( dictHas(from) && dictHas(to) ) ) return new String[0];

        for ( int i=0; i < depth; i++ ) {
            Stack stack = new Stack<>();
            recurse( from, to, stack, i );
            if ( stack.size() != 1 ) return stack.toArray( new String[stack.size()] );
        }
        return new String[0];
    }

    private boolean recurse( String from, String to, Stack stack, int maxDepth ) {
        stack.push( from );
        if( stack.size() > maxDepth ) return false;  // prune
        if ( from.equals( to) ) return true;

        for ( String w: dict) {
            if ( w.length() == from.length() && dif( from, w ) == 1 && !stack.contains(w) ) {
                if ( recurse( w, to, stack, maxDepth ) ) return true;
                stack.pop();
            }
        }
        return false;
    }

    private int dif( String a, String b ) {
        int dif = 0;
        for ( int i=0; i< a.length(); i++ ) {
            if ( a.charAt(i) != b.charAt(i) ) dif++;
        }
        return dif;
    }

    private boolean dictHas(String word) {
        for ( String s: dict) {
            if ( s.equals( word ) ) return true;
        }
        return false;
    }
}

Build Instructions

git checkout https://github.com/coder36/wordchains.git
cd wordchains
mvn clean install
java -cp target/wordchain-1.0-SNAPSHOT.jar org.coder36.wordchain.FindMyWordchain

gold
goad
load
lead

Wednesday, 13 March 2013

BDD with Cucumber

Introduction

Behavioral Driven Development (BDD) in simple terms, allows business owners, developers and testers to collaboratively work together, bound by a "User Story".  User stories are documented in feature files using the gherkin language, along with "scenarios" which when exercised prove that the feature is ready for production.

This blog entry describes a typical setup which can realise the technical aspect of BDD, user stories and automated testing of "scenarios".  Cucumber was originally written in ruby but has been ported to other languages including java.  Here we will look at the Ruby implementation provided by CucumberCapybara and Rspec.


Ruby

Assuming your are working on windows, download a ruby installer from here and install.  Run:

gem install cucumber
gem install rspec
gem install capybara

Make sure that you run these commands from the "Command Prompt with Ruby and Rails".

At this point you should have a workable ruby environment.

IDE

Install the awesome Sublime Text 2.  This will form your gherkin development environment.  Sublime is an excellent editor, blisteringly fast and beautiful.  Start by installing the package manager:
http://wbond.net/sublime_packages/package_control

Using the package manager install:
RubyTest   (https://github.com/maltize/sublime-text-2-ruby-tests)

The following package is not available in the package manager, so needs to be installed by hand.  This provides feature file syntax highlighting:

cd c:/users/<user>/appdata/Roaming/Sublime Text 2/Packages
git clone http://github.com/npverni/cucumber-sublime2-bundle Cucumber

For more packages see http://wbond.net/sublime_packages/community





The following steps can all be done via Sublime without going near the command line.

Setup

Setup the cucumber directory structure:

demo/features
demo/features/step_definitions
demo/features/step_definitions/support


demo/features/search.feature:
 Feature: Search the internet for news
 In order to find news
 As an internet user
 I want to be able to search for news web sites

 Scenario: Search for news providers
 Given I am at http://www.google.co.uk
 And I enter bbc into the search bar
 When I hit search
 Then I will be presented with a list of hits including BBC - Homepage
 When I select the BBC - Homepage link
 Then I will be navigated to website with title BBC - Homepage

This feature file is written in the "Gherkin" language.   This serves as documentation, requirements and test acceptance criteria and  can be written by business owners.  See here for a fuller description of Cucumber.   

Next we will write the step definitions mapping on to each of the "Given ...". "When..." and "Then" in the feature file.

demo/features/step_definitions/step_defs.rb
 Given "I am at $url" do |url|  
      visit url  
 end  
   
 Given "I enter $text into the search bar" do |text|  
      fill_in 'gbqfq', :with => text   
 end  
   
 When "I hit search" do  
      click_button 'gbqfb'  
 end  
   
 Then "I will be presented with a list of hits including $text" do |text|  
      page.should have_content text   
 end       
   
 When "I select the $text link" do |text|  
      click_link text  
 end  
   
 Then "I will be navigated to website with title $title" do |title|  
      page.should have_xpath("//title", :text => title)  
 end  

The visitfill_inclick_button, click_link commands are from the Capybara DSL, and are used to drive a browser, via selenium. page.should  comes from Rspec It's all about driving the web page, then testing for content.  Notice that the step_defs are readable, and very obvious.

demo/features/step_definitions/support/env.rb
 require 'capybara'  
 require 'capybara/cucumber'  
 require 'capybara/rspec'  
   
 Before do  
      Capybara.register_driver :selenium do |app|  
       Capybara::Selenium::Driver.new(app, :browser => :chrome)  
      end  
   
      Capybara.current_driver = :selenium  
 end  

This is the glue which wires everything together and keeps the step_defs clean of clutter:  "Before" is a cucumber hook which runs immediately before the scenario starts executing.  We're using this to configure selenium to use the chrome driver.

Chromium driver

Download the latest Chromium Driver chromium driver and extract into C:/Windows.  Make sure that your chrome browser is up to date.

Testing

Now everything is set up, open a ruby window:
cd demo
cucumber

You should see the chrome browser open up, navigate to www.google.co.uk, enter bbc into the search panel, then navigate over to the bbc website. Here is the cucumber output:


You can also run the cucumber tests via Sublime - select Tools->Ruby Test->Run all Tests/Feature

Notes

I developed this tutorial on a particularly slow internet connection, and I noticed that occasionally, seleniun complained that the browser window was not available (this normally happened on the "Then I will be navigated to website with title BBC - Homepage"  step definition).  I suspect this was a timeout issue.   

I don't like the way selenium dumps output to the command line, interfering with the nicely formatted cucumber output.  There must be a way to stop this?

Monday, 4 February 2013

JBoss 7 logging tips


To fully embrace jboss 7, use the jboss logging mechanism to specify categories and handlers.  It's not the easiest thing to get working, so I've put together a few hints and tips.

1) Use slf4j-api.jar as the logging facade.  Update the dependencies in the pom.xml to exclude everything else.

Be thorough as the slightest presence of log4j or any other logger, overrides the jboss logging mechanism.  In practice the easiest way is to do this it to use Eclipse to view the pom.xml "Dependency Hierarchy" and exclude any other loggers.   

2) Make sure log4j.properties is not on the classpath of the deployment.  Jboss uses log4j.properties by default - I don't know why!

3) Once and handler has been added, restart the server.

4) If logging is still not working, add the following system property:
org.jboss.as.logging.per-deployment=false



Monday, 14 January 2013

Jboss 7, not triggering @PostConstruct

Whilst porting a JSF 2 project over to Jboss 7 I came up against a problem of the @PostConstruct not getting triggered within a @ManagedBean. 

So have:


@ManagedBean
@ViewScoped
public class MyController {

  public String inp;

  @PostConstruct
  public void init() {
    // do something
  }

  public void setInp( String inp ) {
    this.inp = inp;
  }

  public String getInp() {
    return inp;
  }
}


Solution - Add the following to the web.xml:


<context-param>
 <param-name> 
   com.sun.faces.injectionProvider</param-name>
 <param-value>
   com.sun.faces.vendor.WebContainerInjectionProvider    
 </param-value>
</context-param>

The Jboss provider also works:
org.jboss.web.jsf.integration.injection.JBossInjectionProvider



See here for a detailed discussion.

Monday, 17 December 2012

How to create a JSF 2 component

Java Server Pages (JSF) is an extensible JEE web framework.  In this blog post I will demonstrate how to create a simple JSF component.

When developing a JSF component one of the technical aim is to make it as simple and obvious as possible for a developer to use it.  A user of our component shouldn't have to worry about handling call backs, updating state etc.  With this in mind lets begin:


Step 1) Create the java component:  


public class TextToUpperComponent {

  private String input;
  private String output;

  public void convert() {
    output = input.toUpperCase();
  }

  + getters and setters
}

This contains the state and the call back method ( convert() ) to handle button presses.

Step 2) Create the JSF Manatged Bean:.

@ManagedBean
public class MyBean {

  private TextToUpperComponent a = new TextToUpperComponent();
  private TextToUpperComponent b = new TextToUpperComponent();
  private TextToUpperComponent c = new TextToUpperComponent();

  + getters and setters
}

What we've done here, is to make the TextToUpperComponent component a property of the ManagedBean (3 times).   Other listeners/callbacks can be defined to inspect these properties and apply business logic as required.


Step 3)  Define the component -  webapp/resources/texttoupper.xhtml:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:composite="http://java.sun.com/jsf/composite"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets">

  <composite:interface>
    <composite:attribute name="title" />
    <composite:attribute name="jcomponent" />
  </composite:interface>

  <composite:implementation>
    <h:form id="myform">
      <h:panelGrid>
        <h:outputLabel value="#{cc.attrs.title}: " for="word" />
        <h:inputText id="word" value="#{cc.attrs.jcomponent.input}" />
        <h:outputText value="#{cc.attrs.jcomponent.output}" />
        <h:commandButton value="To Upper">
          <f:ajax listener="#{cc.attrs.jcomponent.convert()}" execute="myform" render="myform"/>
        </h:commandButton>
        <br/>
      </h:panelGrid>
    </h:form>
  </composite:implementation>
</html>


As we're placing it under webapp/resources/coder36, the component namespace will be: xmlns:c="http://java.sun.com/jsf/composite/coder36".

A point to note is that once the JSF page is rendered, the components are completely independent of each other, so there is no need to worry about clashing id's etc.


Step 4)  Create index.xhtml Page

Don't forget to include the namespace: 


<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:p="http://primefaces.org/ui"
      xmlns:h="http://java.sun.com/jsf/html"      
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:c="http://java.sun.com/jsf/composite/coder36"
      xmlns:ui="http://java.sun.com/jsf/facelets"> 

 <h:head></h:head> 
 <h:body>
   <c:texttoupper jcomponent="#{myBean.a}" title="First"/>      
   <c:texttoupper jcomponent="#{myBean.b}" title="Second"/>
   <c:texttoupper jcomponent="#{myBean.c}" title="Third"/>
 </h:body> 
</html>


And that's it!  With very little effort we have created a simple reusable JSF component and demonstrated how to integrate it.






Wednesday, 14 November 2012

Setting up a Jboss 7.1 Cluster

Sadly, setting up clustering in jboss 7.1.1 is not as straight forward as it should be.  After hours of googling and numerous false starts, I finally got it all working.  Here are some of the gotcha's which tripped me up.

My starting assumption is that we're running a domain.  Out of the box, the Master node defines 3 servers:
 Server-1    - main-server-group
 Server-2    - other-server-group
 Server-3    - main-server-group

Server-1 and Server-2 are configured to start automatically.  In a cluster these are of no use - disable them.  We're only interested in Server-3 which uses the full-ha profile.

Before we go on, a quick heads up:

  • You only need to amend the domain.xml on the master node
Some helpfull links:


Gotcha #1

When you start up the nodes using the domain.bat scripts, always provide the bind ip and ports.  If you don't then you seem to get some strange behaviours:

domain.sh-b 192.168.0.24 -bmanagement 192.168.0.24     (this is the master)
and
domain.sh-b 192.168.0.25 -bmanagement 192.168.0.25


Gotcha #2

Server-3 does not start cleanly out of the box, due to a mismatch between the full-ha progile and the socket bindings.  In domain.xml, amend as follows:


<server-group name="other-server-group" profile="full-ha">
  <jvm name="default"
    <heap size="64m" max-size="512m"/>
  </jvm>
  <socket-binding-group ref="full-ha-sockets"/>
</server-group>


This will allow Server-2 to start cleanly.

Gotcha #3

The hornetq-server needs configuring with a user name and password.  If you don't you will get an exception along the lines of:

[Server:server-three] 16:24:36,875 ERROR [org.hornetq.core.protocol.core.impl.Ho
rnetQPacketHandler] (Old I/O server worker (parentId: 2128830893, [id: 0x7ee361a
d, /192.168.0.24:5695])) Failed to create session : HornetQException[errorCode=1
05 message=Unable to validate user: HORNETQ.CLUSTER.ADMIN.USER]

Update domain.xml with:
<subsystem xmlns="urn:jboss:domain:messaging:1.1">
  <hornetq-server>                
  <cluster-user>fred</cluster-user>
  <cluster-password>password</cluster-password>


It looks as though you can use any user and password.  It doesn't appear to be authenticated against anything!

Gotcha #4

Use the correct version of @Clustered annotation!   If you don't then in a failover situation you will get the "No EJBReceiver" exception.  The version of @Clustered your'e after is org.jboss.ejb3.annotation.Clustered.  This comes from the jboss-ejb3-ext-api dependency, which is only available from the jboss repo.  Assuming that you are using maven add the following to the pom.xml:

<dependencies>
 ...

  <dependency>
    <groupId>org.jboss.ejb3</groupId>
    <artifactId>jboss-ejb3-ext-api</artifactId>
    <version>2.0.0-beta-3</version>
    <scope>provided</scope>
  </dependency>

<dependencies>
...
<repositories>
  <repository>
    <id>JBoss repository</id>
    <url>http://repository.jboss.org/nexus/content/groups/public/</url>
  </repository>
<repositories>

Then correctly annotate the bean:

import org.jboss.ejb3.annotation.Clustered;

@Stateful
@Clustered
@Remote( coder36.demo.service.MyService.class )
public class MyServiceImpl implements MyService {
...

Gotcha #5

When injecting the EJB do not use the @Inject annotation!   Use @EJB on it's own.  No JNDI name is required:


@ManagedBean
public class PersonController implements Serializable {
  @EJB
  private MyService myService;


Note - the @EJB annotation is available via the following dependency:


<dependency>
  <groupId>org.jboss.spec.javax.ejb</groupId>
  <artifactId>jboss-ejb-api_3.1_spec</artifactId>
</dependency>


Gotcha #6

To make the web application cluster-able ensure that webapp/WEB-INF/web.xml exists, and has the <distributable/> tag:


<web-app xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0"> 

  <distributable/> 
</web-app>


To be extra helpful, I've provided the web.xml namespaces :)

Gotcha #7

Assuming you have downloaded and installed mod_cluster 1,2.Final from here.

Out of the box, mod_cluster does't  not work with jboss 7.1.1. A few tweaks are needed.  Keeping things as simple as possible, I've stripped the provided httpd.conf down the bare minimum:


LoadModule authz_host_module modules/mod_authz_host.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_cluster_module modules/mod_proxy_cluster.so
LoadModule manager_module modules/mod_manager.so
LoadModule slotmem_module modules/mod_slotmem.so
LoadModule advertise_module modules/mod_advertise.so

Listen 192.168.0.24:80
Listen 192.168.0.24:10001

<VirtualHost 192.168.0.24:10001>
  <Location />
    Order deny,allow
    Deny from all
    Allow from all
  </Location>

  KeepAliveTimeout 300
  MaxKeepAliveRequests 0

  EnableMCPMReceive

  <Location /mod_cluster_manager>
    SetHandler mod_cluster-manager
    Order deny,allow
    Deny from all
    Allow from all
  </Location>
</VirtualHost>
ErrorLog "logs/error_log"


I used port 10001 as the default port 6666 didn't work for me.  This httpd.conf should be enough to get you going.

The domain.xml also needs updating to link it up with the mod_cluster instance:


<subsystem xmlns="urn:jboss:domain:modcluster:1.0">
  <mod-cluster-config advertise-socket="modcluster" 
                      proxy-list="192.168.0.24:10001">
  ...


and

<subsystem xmlns="urn:jboss:domain:web:1.1" 
            default-virtual-server="default-host" 
            instance-id="${jboss.node.name}" 
            native="false">
...


Testing

To test everything is working, fire up the domain, deploy an application and start httpd (on windows 7 I needed to run it as administrator otherwise it complained about file permissions).  Navigate to:  http://192.168.0.24:10001/mod_cluster_manager.  You should see:



The web application can be now accessed through the mod_cluster proxy sitting on http://192.168.0.24 and http://192.168.0.24:10001:

ie. http://192.168.0.24/demo/index/jsf