Pages

Showing posts with label web services. Show all posts
Showing posts with label web services. Show all posts

Friday, July 9, 2010

The REST architectural style

REST, Representational State Transfer, is an architural style that captures (post-hoc) the characteristics of the Web that made it so successful. It is a simpler alternative to SOAP and WSDL-based Web Services, where a representation of the requested resource is returned.

A concrete implementation of a REST web service follows four basic design principles:
  • Uses HTTP methods explicitly (POST, GET, PUT, DELETE)
  • Stateless
  • Exposes directure structure
  • Transfer XML, Javascript Object Notation, or both
In the Web Services world, REST is a key design idiom that embraces a stateless client-server architecture in which the web services are viewed as resources and can be identified by their URIs.

The JAX-RS provides full support for building and deploying RESTful web services. It offers a number of utility classes and interfaces, and declarative annotations that allow you to:
  • Identify components of the application
  • route requests to particular methods/classes
  • extract data from requests into arguments of methods
  • provide metadata used in responses

Tuesday, June 22, 2010

EJB Web Service Frustrations

It always amazes me how much time can be wasted trying to get some simple framework/middleware up and running. There is no actual coding involved, only googling error messages, substituting various pieces, plugging, patching, copying and pasting, etc, etc. And sadly today I am no where near as close to getting EJB3 web services working as I would like.

I wanted to get this working as there are a number of advantages to using EJBs as web services instead of POJOs:
  • A richer set of protocols are available
  • Gain access to framework like declarative security and transactions

So I began by googling to find a simple example that I could copy and paste into a few beans/classes and see some results without too much hassle. This was not a problem and I'd created a Remote Interface @WebService using @SOAPBinding(style=Style.RPC), declaring a couple of @WebMethod s, a stateless session bean implementing those methods, and a Client to test it within 10 minutes.

And then the fun began. It deployed with no problems but when I ran the client it crashed with some error about not being able to find some Xerces class. I googled that message and soon figured out that for some reason JBoss was not looking at the .../lib/endorsed/ folder where xercesImpl.jar was. Neither could I figure out how to make it look there so I just added the xercesImpl.jar as an external library. And that fixed that.

Running the client once more resulted in:

Exception in thread "main" java.lang.reflect.UndeclaredThrowableException at $Proxy0.add(Unknown Source) at org.jboss.tutorial.webservice.client.Client.main(Client.java:45)Caused by: java.rmi.RemoteException: Call invocation failed; nested exception is: java.lang.UnsupportedOperationException: setProperty must be overridden by all subclasses of SOAPMessage at org.jboss.ws.core.jaxrpc.client.CallImpl.invokeInternal(CallImpl.java:535) at org.jboss.ws.core.jaxrpc.client.CallImpl.invoke(CallImpl.java:275) at org.jboss.ws.core.jaxrpc.client.PortProxy.invoke(PortProxy.java:154) ... 2 moreCaused by: java.lang.UnsupportedOperationException: setProperty must be overridden by all subclasses of SOAPMessage at javax.xml.soap.SOAPMessage.setProperty(Unknown Source) at org.jboss.ws.core.soap.SOAPMessageImpl.(SOAPMessageImpl.java:87) at org.jboss.ws.core.soap.MessageFactoryImpl.createMessage(MessageFactoryImpl.java:169) at org.jboss.ws.core.CommonSOAP11Binding.createMessage(CommonSOAP11Binding.java:57) at org.jboss.ws.core.CommonSOAPBinding.bindRequestMessage(CommonSOAPBinding.java:157) at org.jboss.ws.core.CommonClient.invoke(CommonClient.java:290) at org.jboss.ws.core.jaxrpc.client.CallImpl.invokeInternal(CallImpl.java:516) ... 4 more

This after much googling I concluded to be a SOAPMessage implementation bug, where the setProperty() method has been overridden in the abstract SOAPMessage class instead of the SOAPMessageImpl subclass where it should have been. The SOAPMessageImpl class is being loaded from rt.jar (Java 1.6) in the classpath instead of the JBoss one, and it calls the setProperty() method of the parent, which throws the UnsupportedOperationException. Hmmm... I'm not even sure if that makes sense as I have not looked into the source of the implementations but taken the explaination from another site. Note to self, check this.

I then proceeded to attempt to make JBoss look at the right jars by placing jbossws-native-core.jar and various other jbossws jars in the /lib/endorsed directory, adding them as external jars directly, and even taking some users' suggestions and using Java 5 instead of 6. Sadly none of this worked for me and I by the time I have given up for the day and set about documenting my experiences I have worked almost an 8 hour day (with liberal breaks for morning tea, lunch, a run, and a shower). I am no Eclipse guru and just switching to Java 5 took enough time by the time I figured out that I should really set the version of Java via the Project Properties -> Project Facets panel to make it take effect on the "java facet" version as well as the compiler compliance level. If it isn't set here the following error results:

"Java compiler level does not match the version of the installed Java project facet"

So a whole day has gone by and I have not managed to get a simple EJB3 web service example working. This is one thing that continues to frustrate me about software development - the amount of wasted time spent googling errors and trying random fixes in order to get something so simple working. Hopefully my next post will be an update on how I finally got a simple EJB3 web service working!

 
Powered by Blogger