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
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.
- Head over to the Eclipse download page at: http://www.eclipse.org/downloads/
- 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!
- Unzip the downloaded package eclipse-jee-helios-SR2-win32.zip into
c:\java\eclipse
. - Run up Eclipse and select
c:\java\workspace
as the …erm workspace!
- Load Eclipse in.
- From the menu bar select Help -> Install New Software…
- Click the Add… button to add a new repository.
- For the Name enter Run Jetty Run
- for the Location enter
http://run-jetty-run.googlecode.com/svn/trunk/updatesite - then click Ok.
- 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.
- Click Finish to download and install it.
- Project name = carshare
- Target runtime = <None>
- Dynamic web module version = 3.0
- Configuration = JavaServer Faces v2.0 Project (this is really up to you)
- Select Next
- 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. - 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!
- Clicked Finish and let it whoor away.
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.
- Hop over to MySQL’s connector/J download page: http://dev.mysql.com/downloads/connector/j/
- If you can read tar.gz files then you might as well get that version because it is 200K smaller.
- Uncompress it and copy the mysql-connector-java-5.1.15.jar file into
c:\java\workspace\carshare\WebContent\WEB-INF\lib
- Right click on the src root package and create a new package calling it
uk.co.bigsoft.carshare
. - Once the package is created, right click on it and select New -> Class.
- Call the class
Person
. - Enter the following java code into the
Person
class: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 "<html><body><h1>" + "Hello MrN" + "</h1></body>"; } }
- Save the class.
- @Path - to get to this class go to
/person
, to go to thesayHtmlHello()
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
toAPPLICATION_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.
c:\java\workspace\carshare\WebContent\WEB-INF\web.xml
to include the following XML.
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>uk.co.bigsoft.carshare</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
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:
<resource-ref>
<description>My DataSource Reference</description>
<res-ref-name>jdbc/carshare</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource>
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 version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<configure class="org.mortbay.jetty.webapp.WebAppContext">
<new id="carshare" class="org.mortbay.jetty.plus.naming.Resource">
<arg></arg>
<arg>jdbc/carshare</arg>
<arg>
<new class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource">
<set name="Url">jdbc:mysql://localhost:3306/carshare</set>
<set name="User">mrn</set>
<set name="Password">hard2crack</set>
</new>
</arg>
</new>
</configure>
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:
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
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.
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-namenotfoundexceptiI 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.bz2It 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.txtThe 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.bz2I 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
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!
- On the master load the Synergy program and make sure the Server (share this computer’s mouse and keyboard).
- Click Configure Server….
- 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.
- Double click it.
- Change the Screen name to the name of the computer that will be connecting with you.
- Click ok.
- Then click Start and close when you are done.
One of the greatest obstacles facing a dyslexic is how do you look up a word if you can’t spell it? Most of the time I can recognise the correct spelling so can pick it out of the list provided by the spell checker. But what if your spell checker can’t recognise it either.
There aren’t many phonetic spell checkers or dictionary sites and there are only a couple of words that get me each time, so I thought I’d list them here:
- He goes to the shops.
- He does his best.
- I want to precis this text.
- There are five scenes in this play.
- We are running 2 scenarios.
- The Lake District has lovely scenery.
- I have 5ish cousins
- My mortgage is really expensive.
- I’ll definitely be there.
- You must guarantee there are no underscores in host names
- French pastry croissant
- flush privileges