Cornelia's Weblog

my sporadically shared thoughts on, well, whatever is capturing my attention at the moment.

Posts Tagged ‘CXF’

Jax-RS : Regular Expressions in @Path Annotations

Sometimes I really wish I did something else for a living. Okay, perhaps a bit over-dramatic but I’m feeling a bit tired this evening and wasting even 20 minutes on something totally useless (which, let’s face it, isn’t unusual in computing) has me ready to call it a night. But since googling the error codes I was getting netted nothing (other than this 2 year old thread), perhaps I can be of service to the next person bitten by this.

I’m writing a RESTful web service, using Jax-RS with a CXF runtime (v 2.2.10). I’m defining a resource with a URI something like /foo/bar/… – that is, the first part of my uri will have the literals “foo” and “bar” and then I want everything else on the URI to go into a parameter. So I want /foo/bar/a, /foo/bar/a/b and /foo/bar/ab/c to all resolve to the same resource/method with a path parameter bound to “a”, “a/b” and “a/b/c”, respectively. So I create the follwoing @Path annotation:

@Path("foo/bar/{therest : .*}")

My initial source for this tidbit was the Safari Books Online copy of Restful Java with Jax-RS, page 47 which showed an example just like this.

When I tried to launch my web service, however, I got an error that indicated something was wrong with the regular expression.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'Prototype': Error setting property values;
nested exception is org.springframework.beans.PropertyBatchUpdateException;
nested PropertyAccessExceptions (1) are:PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'serviceBeans' threw exception;
nested exception is java.util.regex.PatternSyntaxException: Illegal repetition near index 27/foo/bar/{therest : .*}(/.*)?...

The answer was really simple, get rid of the spaces around the ‘:’. Argh! Since when do languages care that much about whitespace?! And Argh again! How can a published book have this error?! Or perhaps the bug is in CXF? I’ll look into that when I have a chance.

What happened to the FUSE->FUSE Project option in the eclipse plugin?

A colleague of mine was still running eclipse with an older version of the FUSE plugin – in particular 1.0.0. He had a single option under the New->Project->FUSE category called “FUSE Project”. Selecting this option created what was essentially a web services project (in particular we are using it for RESTful services) that had all of the libraries set up, etc.When I installed the latest version of everything, following the instructions in the FUSE installation guide that option was gone. Under the FUSE category there are now three options that are all essentially Camel focused – EIPs and the like. I did some digging and found that creating a web services project set up for FUSE (Service Mix – CXF) is now done via project options shipped with the Eclipse Web Tools Platform. Here’s how it works:Select File->New->Project and then under Web select Dynamic Web Project. Clicking “Next” presents the following dialog:Creating CXF ProjectUnder the Configuration section select the CXF Web Services Project v2.5 option and that’s it. Exporting this project to a war includes all of the necessary jars. This does, of course, require that you have set your CXF runtime preferences appropriately. In Windows->Preferences:Setting CXF Runtime ParametersThe only gotcha I ran into was that plugin installation order matters. It’s still not clear to me if and when WTP is included in Eclipse IDE for Java EE Developers – the WTP 3.1 Release page says it does with Galileo but I was constrained to using Ganymede for other plugin compatibility; installing Ganymede Eclipse IDE for Java EE Developers did NOT seem to include the WTP, at least not the CXF pieces. Assuming WTP has to be installed, and assuming I want to install the latest FUSE integration designer, you have to install WTP first. When I did the FUSE plugin first I had several problems, most notably there was no CXF 2.x Preferences option under the Web Services preferences (see screen shot above); this is an option that is added when you install the appropriate parts of the WTP.UPDATE 1/22/2010:I’ve just installed Galileo and while it does include WTP, it does not include the CXF portions. Go to the update sitehttp://download.eclipse.org/webtools/updatesand then expanding each of Web Tools Platform, Web Tools Platform SDK and Web Tools Platform Tests (optional) select the CXF pieces – there is one in each category.Installing CXF tools with WTP

Getting the Apache CXF Jax-RS Basic sample running

I did it in January – just came back to it today and could not remember what I did. Where is my memory? So for my benefit, and perhaps the benefit of others, I’m writing it down. There are hints in the README that ships with the sample, but it was far from step by step.Of course, there are a number of different ways you can get this running – this is just one way.My environment:

  • FUSE Services Framework (CXF) version 2.1.3.2
  • Eclipse 3.3.2

And here’s what you do.

  1. Start up Eclipse with a new or existing workspace and use the Java perspective.
  2. Create a new project by selecting File->New->Other… and then Java->Java Project from Exiting Ant Buildfile. Enter the name of the project, something like “Basic Jax-RS Sample”. Browse to {FUSE Install dir}/samples/jax_rs/basic/build.xml. Check the box that reads “Link to the buildfile in the file system” and click Finish. Note that this checkbox does NOT make a copy of the sample directory, nor does it create a separate build.xml, rather uses the one that is in the sample directory. This build file references another build file that is relative to the build.xml file so in order to use the build file without changes it must be invoked from that directory.

This is all you need to do to set the project up. Now you can run it. We are going to do so all inside of eclipse. First we’ll run the server part of the sample and use a browser to invoke the services – just reads. Then we’ll run both the server and a simple client application from within eclipse. Read on.

Running the Server and GETting resources

  1. Expand the Basic Jax-RS Sample project
  2. Right click on the build.xml file and select “Run As->Ant Build…” – be sure to to select the “Ant Build…” with the dot-dot-dot so you can select what you want to build and run.
  3. Now you can fetch some resources – note that a few are created for you when you run the server. Invoke a URL either http://localhost:9000/customerservice/customers/123 or http://localhost:9000/customerservice/orders/223/products/323. Notice in the code that customers, via the path “customers/{id}” and products, via the path “orders/{oid}/products/{pid}” are the only two resources that support GET.

Also notice that the server only stays up and running for 5 minutes by default – if you wish to lengthen this you can change the line of code in the Server.java file that reads:Thread.sleep(5 * 60 * 1000);And that’s it. You are running the application. If you want to test out some write operations…

Running the Server and a Client Application

Both the server and the client can be run from within eclipse.

  1. If your server is not running follow the steps outlined in the section above – basically do a Run As->And Build… and select the server.
  2. Now run the client by right-click on the build.xml, Run As->Ant Build… and this time select “client” (deselect “server”)
  3. You can see the results of the execution in the console pane. Customer number 123 was updated and a new customer was created and assigned an id of 124 by the server. In fact you can now invoke the URL http://localhost:9000/customerservice/customers/124 to see that new customer resource.

That’s it, the basics of getting the application up and running.