Educating the world

Our blog has over 10,000 readers a month

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.

Words I can never spell

November 1st, 2011

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

I’ve decided to expand this page to include helpful information on grammar.

Learn Web Application Project Tutorials (with C#)

October 21st, 2011

I’ve been learning how to use Microsoft’s Web Application Projects in C-Sharp. I started with the MSDN documentation and in spite of being familiar with all the web concepts I found Microsoft’s documentation confusing. The code examples that were listed appeared to be incomplete snippets. I had searched the internet looking for tutorials but couldn’t find anything.

After altering my search a bit, I found a tutorial which was all based on Visual Studio 2003 & 2005. The instructions are just the same for Visual Studio 2010.

I found a set of 6 tutorials which takes you from creating a web page with a simple calender on it through to data binding and on to user control libraries. Each tutorial contains step-by-step instructions with plenty of screen shots.

If you want to learn then this is an excellent and surprisingly simple starting point.
http://webproject.scottgu.com/CSharp/