Educating the world

Our blog has over 10,000 readers a month

Getting Started

December 7th, 2011

Today’s lesson was about getting started. It’s all about the drama!

Secrets & Lies

My friend Bill has just separated with his girlfriend of 22 years. They have 2 houses and one boy in primary. He never spoke of being unfaithful and wouldn’t go into much detail about what happened.
I’ve known them both for the same amount of time, so I’m wondering what went on behind closed doors. How many times had they put their face on to receive me as a guest on my regular Wednesday pizza and video night.
I had no idea, it came out of the blue. Had a call from Bill today saying he has moved into her house in London with his brothers. The house is owned by her and she is living in his house in Berkshire. It’s going to be complicated.

Comments:

  1. Clearly aligned with the boy.
  2. Female has no name.
  3. Narrator is a character.
  4. Present tense.
  5. Use of clichés. “Out of the blue” & “behind closed doors". Usually not advised but narrator was honest enough to carry it off.
  6. Drama. Lots of questions. why are there 2 houses? Why are they living in each others’ houses? why did they separate?

The Chair

Sitting on my chair. It’s comfortable but my back is cold. Everyone has the same chair; I wonder if their backs are cold. Maybe it’s just because the windows are behind me. Only teacher and I have our legs crossed. Everyone’s chair is the same faded maroon except teacher’s chair. It looks newer. Why does he get a new chair? Can I have a new chair? If I ask can I get one? Probably not! Just a student. As long as we keep paying out nine grand they don’t care. Bums on seats; that’s all they care about. They didn’t even tell us teacher was going away.

Comments:
Not read aloud.

The homework was to create a beginning and write an opening scene.

Pressure

Beads of sweat rolled off the end of my nose. Bill hasn’t phoned back yet. He said he’d call by five. He’s late. They don’t tolerate tardiness. I heard rumours from Harry about these guys. “Anything you want, is only a phone call away", he kept saying. “Just don’t forget to thank the cardinal", he would always add as a throw-away line. We thought he was joking, who the hell can find a cardinal around this god forsaken place.
“Briing” the loud bell from the factory resonated through the walls. I snatched the phone as if it were a rope from my rescue boat.
“Bill?", I shouted.
“Yeh", he mumbled with a low huskie voice.
“Well?", I enquired.
“You never went to see the cardinal, did you?".
“Couldn’t find one Bill".
“Syler, won’t be happy. Harry said he’ll try to soften him up before the exchange".
“Thanks", I said.
“That’ll cost you extra. You know it’ll be more dangerous now without the cardinal’s blessing".

Comments:

  1. Plenty of questions raised.
  2. Wondering what is going down.
  3. Is it legal?
  4. Good mixture of narrative and dialogue.
  5. 4 or 5 characters introduced very quickly.
  6. Each character has a goal.
  7. Drama in it straight away.
  8. Wonderful 1st sentence. The teacher said this :)

Creative writing

December 2nd, 2011

Some while ago I was listening to Radio 4 and there was a woman plugging her new book. She was an experienced writer but hadn’t always been. Before being a writer she had a normal job. One day she signed up to do a course in Creative Writing at her local college because it looked interesting and she has never looked back.

I’m not expecting world domination but now I’m a blogger with a couple of years under my belt I thought it might be nice if I could spruce up my articles. As you may have noticed this is primarily a technical blog and wouldn’t interest almost anyone off the street. I do write about my holiday experiences and there’s some stuff about optical illusions but the rest of the articles are pretty dry unless you are specifically looking for “some snippet that only 10 people in the world need to care about“.

I’ve had the first lesson of 8 and found it fascinating. I’m not going to give away the details of the lessons as most of the pearls of wisdom came out as part of an in-class discussion as opposed to the traditional black board style of teaching.

This article will be used to glue together related articles in order.

Getting started
Secrets & Lies, The Chair, Pressure

Condensing the story, then padding it out
Start with just six words

Dialogue
Direct and indirect discourse

Beginnings and endings
Rewriting classic stories

Jetty, Jersey and MySQL inside Eclipse

November 15th, 2011

This article gives a step by step set of instructions to set up Eclipse to run a Jetty application container using Jersey RESTful annotations and talk to a MySQL database. You would have thought that with all these technologies being really popular there would be loads of really helpful documentation and help but in reality the forums of the internet are overflowing with people having trouble with this. So let’s start from the beginning and see if we can’t work through it together - ok with me doing all the work.

For the purposes of simplicity we’ll be installing all the software into the c:\java folder.

First up we’ll install Eclipse. We are going to create a Dynamic Web Project. We must install the JEE build of Eclipse because it comes with all the supporting dependencies that we need so there won’t be many additional plugins we’ll have to install. Just for your records I did this with Java EE IDE for Web Developers Helios Service Release 2 Build id: 20110218-0911.

  1. Head over to the Eclipse download page at: http://www.eclipse.org/downloads/
  2. We want the Eclipse IDE for Java EE Developers which comes in at a whopping 206 MB, one of the larger builds. Thanks to my lovely 50MB Virgin broadband it only takes a couple of seconds!
  3. Unzip the downloaded package eclipse-jee-helios-SR2-win32.zip into c:\java\eclipse.
  4. Run up Eclipse and select c:\java\workspace as the …erm workspace!

I thought that running Jetty inside Eclipse would be like running Tomcat in Eclipse. I spent quite a long time looking for something that let you launch Jetty from a pre-installed installation and was represented in the Eclipse platform as a server. I found JettyLauncher which does this job. On JettyLauncher’s main sourceforge page it says that the project has closed down and we should use Run Jetty Run instead.

Run Jetty Run installs into Eclipse as a plugin so there is no need to have a separate Jetty installation. The whole thing runs as an embedded program and so the integration is really tight.

Installing the Jetty plugin couldn’t be easier.

  1. Load Eclipse in.
  2. From the menu bar select Help -> Install New Software…
  3. Click the Add… button to add a new repository.
    1. For the Name enter Run Jetty Run
    2. for the Location enter
      http://run-jetty-run.googlecode.com/svn/trunk/updatesite
    3. then click Ok.
  4. Eclipse will go to the repository and download a list of the installable that can be downloaded. Expand them all and check the option with the highest version number. At the time of writing it is: Run Jetty Run 1.2.1.1.
  5. Click Finish to download and install it.

The Java JEE build of Eclipse has the correct configuration for us to create a Dynamic Web Project. From the menu bar select File -> New -> Dynamic Web Project.

Set the following options on the project set up page:

  1. Project name = carshare
  2. Target runtime = <None>
  3. Dynamic web module version = 3.0
  4. Configuration = JavaServer Faces v2.0 Project (this is really up to you)
  5. Select Next
  6. On the Web Module page, check the box for Generate web.xml deployment descriptor. This creates a starting web.xml file for you. Without this, the system is difficult to configure down the line.
  7. If you selected JavaServer Faces v2.0 Project then you will have to choose an implementation to use. Click the download button (which looks like a floppy disc with a down arrow next to it) and select Apache’s Myfaces JSP Core-2.0 implementation. The first time I did this it said “failed to open zip", so I tried again and it worked!
  8. Clicked Finish and let it whoor away.

Now that we have an Eclipse project we can start loading up the webapp’s lib directory with dependencies for you to use.

I have selected Jersey as my REST implementation because it is more compliant with JSR311 and is properly maintained by the real Java people.

It is not completely obvious which distribution to download because they don’t have names! They only have long wordy descriptions. So download the one which is described as: “A zip of Jersey containing the Jersey jars, core dependencies (it does not provide dependencies for third party jars beyond the those for JSON support) and JavaDoc”

Uncompress it to c:\java\jersey-archive-1.6 and copy all the jar files from c:\java\jersey-archive-1.6\lib to c:\java\workspace\carshare\WebContent\WEB-INF\lib.

While we are here we’ll install the MySQL driver jar as well.

  1. Hop over to MySQL’s connector/J download page: http://dev.mysql.com/downloads/connector/j/
  2. If you can read tar.gz files then you might as well get that version because it is 200K smaller.
  3. Uncompress it and copy the mysql-connector-java-5.1.15.jar file into c:\java\workspace\carshare\WebContent\WEB-INF\lib

When you have everything in place select the project name, right click and select Refresh. Right click again (on the project name) and select Validate (not really sure what this does but it sounds like you should do it!).

Before diving head long into databases and all the rest of it we will make sure our Jersey REST bit works by creating a simple POJO and decorating it with some JSR311 REST annotations.

  1. Right click on the src root package and create a new package calling it uk.co.bigsoft.carshare.
  2. Once the package is created, right click on it and select New -> Class.
  3. Call the class Person.
  4. Enter the following java code into the Person class:

    Code

    package uk.co.bigsoft.carshare;
     
    import javax.ws.rs.GET;
    import javax.ws.rs.Path;
    import javax.ws.rs.Produces;
    import javax.ws.rs.core.MediaType;
     
    @Path("/person")
    public class Person{
     
    @GET
    @Path("/list")
    @Produces(MediaType.TEXT_HTML)
    public String sayHtmlHello() {
      return "&lt;html&gt;&lt;body&gt;&lt;h1&gt;" + "Hello MrN" + "&lt;/h1&gt;&lt;/body&gt;";
      }
    }
  5. Save the class.

Lets have a look at the annotations. They are pretty straightforward.

  • @Path - to get to this class go to /person, to go to the sayHtmlHello() method go to /person/list.
  • @GET - type of request. So you can have @POST, @DELETE and @PUT.
  • @Produces - take the return type and renders it automatically into the type you specify. If you change the MediaType to APPLICATION_JSON and return a POJO instead, Jersey will automatically convert it to JSON without any extra coding. There is also a @Consumes to handle data coming inwards.

We need to register Jersey as the servlet dispatcher for REST requests so update the c:\java\workspace\carshare\WebContent\WEB-INF\web.xml to include the following XML.

XML

&lt;servlet&gt;
  &lt;servlet-name&gt;Jersey REST Service&lt;/servlet-name&gt;
  &lt;servlet-class&gt;com.sun.jersey.spi.container.servlet.ServletContainer&lt;/servlet-class&gt;
    &lt;init-param&gt;
      &lt;param-name&gt;com.sun.jersey.config.property.packages&lt;/param-name&gt;
      &lt;param-value&gt;uk.co.bigsoft.carshare&lt;/param-value&gt;
    &lt;/init-param&gt;
    &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
&lt;/servlet&gt;
&lt;servlet-mapping&gt;
  &lt;servlet-name&gt;Jersey REST Service&lt;/servlet-name&gt;
  &lt;url-pattern&gt;/rest/*&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;

The package uk.co.bigsoft.carshare is the top level package. All classes and sub-packages will be searched for classes that have been annotated with …erm annotations! All @Paths will appear under the /rest/ URL, so with the example above the URL path will be /rest/person/list.

If you have done it correctly you will see Jersey REST Service under <eclipse-project> -> Deployment Descriptor: uk.co.bigsoft.carshare -> Servlets and
/rest/* -> Jersey REST Service under <eclipse-project> -> Deployment Descriptor: uk.co.bigsoft.carshare -> Servlet Mappings.

Now we are ready to run. From the menu select Run -> Debug Configurations. Highlight Jetty Webapp, right click and select New. Everything will be automagically filled in for you so just click Debug.
Jetty will start up inside Eclipse so using your favourite browser navigate to: http://localhost:8080/carshare/rest/person/list and you should see the text “Hello MrN".

Happy that everything is in place we can configure the webapp to talk to MySQL. This took me all day to solve. For such a common set of technologies there is little or no documentation. The information I found was on forums, mail lists and Stack Overflow. All the information I found was wrong and it was just a fluke I hit the right answer with a bit of trial and error.

We have already installed the MySQL Connector/j so all that is left to do is add the configuration. We are going to add MySQL as a JNDI datasource. Edit the c:\java\workspace\carshare\WEB-INF\web.xml in Eclipse and add the following lines:

XML

&lt;resource-ref&gt;
    &lt;description&gt;My DataSource Reference&lt;/description&gt;
    &lt;res-ref-name&gt;jdbc/carshare&lt;/res-ref-name&gt;
    &lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;
    &lt;res-auth&gt;Container&lt;/res-auth&gt;
&lt;/resource&gt;

That defines a resource called jdbc/carshare and the interface it uses, but we need to define what the resource actually looks like. This part of the configuration is somewhat container specific so we need to put it into a separate file. All the documentation says to use WEB-INF/jetty-env.xml but this is actually ignored by Jetty so you have to call it c:\java\workspace\carshare\WEB-INF\jetty-web.xml.

Next, create the following context definition:

XML

&lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd"&gt;
 
&lt;configure class="org.mortbay.jetty.webapp.WebAppContext"&gt;
 
&lt;new id="carshare" class="org.mortbay.jetty.plus.naming.Resource"&gt;
  &lt;arg&gt;&lt;/arg&gt;
  &lt;arg&gt;jdbc/carshare&lt;/arg&gt;
  &lt;arg&gt;
    &lt;new class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource"&gt;
      &lt;set name="Url"&gt;jdbc:mysql://localhost:3306/carshare&lt;/set&gt;
      &lt;set name="User"&gt;mrn&lt;/set&gt;
      &lt;set name="Password"&gt;hard2crack&lt;/set&gt;
    &lt;/new&gt;
  &lt;/arg&gt;
&lt;/new&gt;
 
&lt;/configure&gt;

And now for the final stage. We need to call an instance of the datasource into existence from inside our RESTful class.

All the documentation I read said you just have to add:

Code

InitialContext ctx = new InitialContext();
ds = (DataSource) ctx.lookup("java:comp/env/jdbc/carshare");

to your code and it would all work. Well every time a called new InitialContext() it returned an empty (or blank) Context so my lookup always failed. To get around this you need to add a c:\java\workspace\carshare\WEB-INF\lib\jndi.properties containing some magic “make-it-work” lines

XML

java.naming.factory.url.pkgs=org.mortbay.naming
java.naming.factory.initial=org.mortbay.naming.InitialContextFactory

Add jetty-name-ver.jar and jetty-plus-ver.jar to WEB-INF/lib as well.

Finally the name I was getting the exception:

java:comp/env/jdbc/carshare javax.naming.NameNotFoundException; remaining name ‘env/jdbc/carshare’

All the Jetty documentation says that if you name the resource jdbc/carshare then Jetty’s context will automatically add the java:comp/env so it fits in with other application containers. This was not my experience. The only name I could look up was jdbc/carshare. So I changed the code to the following and all was good.

Code

InitialContext ctx = new InitialContext();
ds = (DataSource) ctx.lookup("jdbc/carshare");

There is no way I could have done this without the help of the following articles and a bit of luck!

Jersey + eclipse: http://www.vogella.de/articles/REST/article.html
Install run-jetty-run: http://code.google.com/p/run-jetty-run/wiki/GettingStarted

http://stackoverflow.com/questions/2131798/jetty-mysql-connection-pool-configuration-error-javax-naming-namenotfoundexcepti

Tar'ing files from a file

November 9th, 2011

I recently had to take a copy of a web server to test some layout stuff but when I zipped it up, it was over 6GB. This was too much for me to transfer, so I had a look to see what was taking up all the space. It turned out that most of it was video files and tutorials. I didn’t really need them for the work I was doing so I wanted to filter them out and tar up the rest.

I did a find to get a list of all the files under the document root, but found that when I invoked the tar command it kept including the video files.

find docroot -print > files.txt
grep -v -i “\.wmv$” files.txt > filtered-files.txt
tar -cvj -T filtered-files.txt -f docroot.tar.bz2

It took a while to realise what was going on, so I thought I’d document the trap I fell into. The find command lists all the files and directories which meant that the tar command was effectively:

tar -cvj -f docroot.tar.bz2 docroot/file1.txt docroot/movies_dir docroot/file2.txt

The grep I issued didn’t make any difference because I was including the movie’s parent directory, which contained all the files.

So I modified my find command to only include files and it worked as expected.

find docroot -type f -print > files.txt
grep -v -i “\.wmv$” files.txt > filtered-files.txt
tar -cvj -T filtered-files.txt -f docroot.tar.bz2

I kept finding different movie formats so the grep command was getting longer and longer. In retrospect it would have been better to use more of the features of the tar command:

tar -cvj -f docroot.tar.bz2 –exclude="*.wmv” –exclude="*.mpg” –exclude="*.mpeg” docroot

Shared mouse with Synergy

November 7th, 2011

I upgraded my PC at work which meant transferring all my old files and configuration from one computer to another. The pain is having 2 keyboards and 2 mice cluttering up my desk which is pretty messy already! Files and the like are easy to transfer; you can just set up shares and copy the stuff over - don’t get me started on windows copying. Keep an eye on Sourceforge for my application JustF’ingCopyIt, JustF’ingMoveIt or JustF’ingDoIt not sure which yet! It’s all the other bits that you want to move over like application configurations or the contents of ini files that you want to copy without the actual application.

This is where Synergy comes in. Synergy lets you use one keyboard and one mouse across multiple computer desktops. It makes it feel like you are using one computer with 2 monitors and not 2 computers. It is effortless to switch between the PCs. Cutting and pasting is shared between the two.

While it isn’t common, you can mix the platform desktops. Synergy shares a single mouse across Windows (XP/Vista/7), Mac OS X (10.4/10.5/10.6), Ubuntu/Debian, Fedora/Red Hat to provide a multiple desktop feel.

On each PC:
Download the application for the operating system you are using from :
http://synergy-foss.org/download

The setup is more like and X-Windows environment, in that your primary PC is a client to loads of other PCs that serve you.

Choose the PC that you are going to be primarily using as the master. If you are using them all equally then select the most powerful as the master and if they are all the same specification then pick the one closest to the door!

  1. On the master load the Synergy program and make sure the Server (share this computer’s mouse and keyboard).
  2. Click Configure Server….
  3. Drag a picture of the monitor in the top right of the screen and place it where you would like it to appear in relation to you.
  4. Double click it.
  5. Change the Screen name to the name of the computer that will be connecting with you.
  6. Click ok.
  7. Then click Start and close when you are done.

On all the clients load the Synergy program and make sure the Client(use another computer’s keyboard and mouse). Enter the name of the master PC and click Start, and then close when you are done.

In both cases closing will move the application to the System Tray.