<?xml version="1.0" encoding="utf-8"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:lang="en">
<title>Marc Hadley&apos;s Blog</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/mhadley/" />
<modified>2008-06-16T20:19:55Z</modified>
<tagline></tagline>
<id>tag:weblogs.java.net,2008:/blog/mhadley/57</id>
<generator url="http://www.movabletype.org/" version="3.01D">Movable Type</generator>
<copyright>Copyright (c) 2008, mhadley</copyright>
<entry>
<title>JAX-RS Public Review Draft and JavaOne</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/mhadley/archive/2008/05/jaxrs_public_re.html" />
<modified>2008-06-16T20:19:55Z</modified>
<issued>2008-05-02T20:44:06Z</issued>
<id>tag:weblogs.java.net,2008:/blog/mhadley/57.9670</id>
<created>2008-05-02T20:44:06Z</created>
<summary type="text/plain">The JAX-RS public review draft is now available for, er, review - download it here. If you are attending JavaOne we&apos;d love to see you at any or all of the following sessions: TS-5425, Tuesday May 06 12:10 - 13:10,...</summary>
<author>
<name>mhadley</name>

<email>Marc.Hadley@sun.com</email>
</author>
<dc:subject>Web Services and XML</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/mhadley/">
<![CDATA[<p>The JAX-RS public review draft is now available for, er, review - <a href="http://jcp.org/aboutJava/communityprocess/pr/jsr311/index.html">download it here</a>.</p>

<p>If you are attending JavaOne we'd love to see you at any or all of the following sessions:</p>
<ul>
<li><a href="https://www28.cplan.com/cc191/session_details.jsp?isid=295425&ilocation_id=191-1&ilanguage=english">TS-5425, Tuesday 
May 06 12:10 - 13:10, Esplanade 307-310</a></li>
<li><a href="https://www28.cplan.com/cc191/session_details.jsp?isid=295613&ilocation_id=191-1&ilanguage=english">BOF-5613, Tuesday 
May 06 20:30 - 21:20, Esplanade 307-310</a></li>
<li><a href="https://www28.cplan.com/cc191/session_details.jsp?isid=295425&ilocation_id=191-1&ilanguage=english">TS-5425 (repeat), Friday 
May 09 14:50 - 15:50, Esplanade 304/306</a></li>
</ul>

<p>I'll also be on Glen's panel <a hre="https://www28.cplan.com/cc191/session_details.jsp?isid=296330&ilocation_id=191-1&ilanguage=english">"REST Versus SOA: Can We All Just Get Along?"</a> which follows our BOF in the same room at 21:30 (Tuesday is shaping up to be a busy day).</p>
]]>

</content>
</entry>
<entry>
<title>JAX-RS Implementations</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/mhadley/archive/2008/04/jaxrs_implement.html" />
<modified>2008-06-16T20:20:23Z</modified>
<issued>2008-04-01T21:20:30Z</issued>
<id>tag:weblogs.java.net,2008:/blog/mhadley/57.9457</id>
<created>2008-04-01T21:20:30Z</created>
<summary type="text/plain">The Restlet team just announced a new release. Amongst the new features is support for JAX-RS, see an example here. With the RI (Jersey), Apache CXF, and JBoss RESTeasy, that makes a total of four implementations currently underway. The feedback...</summary>
<author>
<name>mhadley</name>

<email>Marc.Hadley@sun.com</email>
</author>
<dc:subject>Web Services and XML</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/mhadley/">
<![CDATA[<p>The Restlet team just <a href="http://blog.noelios.com/2008/04/01/restlet-11-m3-released/">announced a new release</a>. Amongst the new features is support for JAX-RS, see an <a href="http://wiki.restlet.org/docs_1.1/g1/13-restlet/28-restlet/57-restlet.html">example here</a>. With the RI (<a href="http://jersey.dev.java.net/">Jersey</a>), <a href="http://cwiki.apache.org/CXF20DOC/jax-rs-jsr-311.html">Apache CXF</a>, and <a href="http://wiki.jboss.org/wiki/Wiki.jsp?page=RESTeasyJAXRS">JBoss RESTeasy</a>, that makes a total of four implementations currently underway. The feedback we're receiving as a result of these parallel implementations is proving very useful and I'm grateful for the all the good input we've been getting.</p>

<p>The graph below shows the monthly totals for emails sent to the dev, users, issues and commits mailing lists for both JAX-RS and Jersey.</p>

<p align="center"><img src="http://weblogs.java.net/blog/mhadley/activity.png" alt="activity.png" border="0" width="647" height="445"/></p>

<p>As you can see, traffic on the lists has picked up quite a bit over the last few months and a good proportion of the increase is due to the additional implementation work flushing out issues. We've also been working through our issues list with a view to publishing a JCP public review draft in the not too distant future.</p>

]]>

</content>
</entry>
<entry>
<title>Authentication in Jersey</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/mhadley/archive/2008/03/authentication.html" />
<modified>2008-06-16T20:20:46Z</modified>
<issued>2008-03-07T21:14:53Z</issued>
<id>tag:weblogs.java.net,2008:/blog/mhadley/57.9331</id>
<created>2008-03-07T21:14:53Z</created>
<summary type="text/plain">I&apos;m working on an internal project building some RESTful services using a combination of Jersey, JPA, Glassfish and Derby. Actions on some resources require authentication and I need access to the name of the authenticated user in the resource method....</summary>
<author>
<name>mhadley</name>

<email>Marc.Hadley@sun.com</email>
</author>
<dc:subject>Web Services and XML</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/mhadley/">
<![CDATA[<p>I'm working on an internal project building some RESTful services using a combination of <a href="http://jersey.dev.java.net/">Jersey</a>, JPA, <a href="http://glassfish.dev.java.net/">Glassfish</a> and <a href="http://db.apache.org/derby/">Derby</a>. Actions on some resources require authentication and I need access to the name of the authenticated user in the resource method. This entry describes the steps to set this up - kudos to my colleague <a href="http://blogs.sun.com/hubertsblog/">Hubert</a> for working out much of the below.</p>

<p>Obviously you're going to need all the ingredients listed above. I'm using <a href="http://www.netbeans.org/">NetBeans</a> which came bundled with Glassfish and Derby so all I had to do was install the RESTful Web Services plug-in, YMMV.</p>

<p>Next you need a database to store username, password and group information. Here's the table definitions I used:</p>

<pre>CREATE TABLE users (
    id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    username VARCHAR(64) UNIQUE NOT NULL,
    password VARCHAR(64) NOT NULL,
);
CREATE INDEX username ON users(username);

CREATE TABLE groups (
    id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    username VARCHAR(64) NOT NULL REFERENCES users(username) ON DELETE CASCADE,
    groupname VARCHAR(64)
);</pre>

<p>Depending on your needs you could lose the integer fields, the important thing is to have a column in the group table with the same name as the column in the users table that holds the username. Those two columns are used to join the users table to the groups table. The Glassfish security realm is going to execute a query like this to retrieve the groups (which map to security roles) that a particular user is a member of:</p>

<pre>SELECT groupname FROM groups g, users u where g.username = u.username and u.username = ?</pre>

<p>Add some users and groups for testing purposes, note that the password should be an md5 hash, not plaintext - there are several web sites that offer online MD5 generators that you can use. I used groups named USERS and ADMINISTRATORS, you'll see where these come in later.</p>

<p>Next you need to define a JDBC data source, connection pool and security realm in Glassfish. The first two are pretty straightforward and will likely be taken care of already if you have deployed a web application using the database. Setting up the security realm is also straightforward once you have a suitable database structure as described above. You do this via the admin console as shown below (there are a couple of additional fields on the form, you can leave those blank):</p>

<div style="text-align:center;"><img src="http://weblogs.java.net/blog/mhadley/realm.png" alt="realm.png" border="0" width="867" height="700" /></div>

<p>Its now possible to require authentication for access to a JAX-RS resource via web.xml. Say I have a resource that only authenticated users can use, e.g.:</p>

<pre>@Path("dropbox")
public class DropBox {
    @Context
    SecurityContext security;
    
    @POST
    public Response drop(InputStream data) {
        String username = security.getUserPrincipal().getName();
        ...
    }
}</pre>

<p>Note the use of dependency injection to get an instance of <code>SecurityContext</code> and how that interface provides access to the username. In order for this to work we have to tell the container that authentication is required for access to the <code>/dropbox</code> URI. Add the following lines to your web.xml to restrict use of this resource to members of the USERS group:</p>

<pre>&lt;security-constraint&gt;
    &lt;display-name&gt;DropBox&lt;/display-name&gt;
    &lt;web-resource-collection&gt;
        &lt;web-resource-name&gt;DropBox&lt;/web-resource-name&gt;
        &lt;description&gt;&lt;/description&gt;
        &lt;url-pattern&gt;/dropbox&lt;/url-pattern&gt;
        &lt;http-method&gt;GET&lt;/http-method&gt;
        &lt;http-method&gt;POST&lt;/http-method&gt;
        &lt;http-method&gt;HEAD&lt;/http-method&gt;
        &lt;http-method&gt;PUT&lt;/http-method&gt;
        &lt;http-method&gt;OPTIONS&lt;/http-method&gt;
        &lt;http-method&gt;TRACE&lt;/http-method&gt;
        &lt;http-method&gt;DELETE&lt;/http-method&gt;
    &lt;/web-resource-collection&gt;
    &lt;auth-constraint&gt;
        &lt;description&gt;Have to be a USER&lt;/description&gt;
        &lt;role-name&gt;USERS&lt;/role-name&gt;
    &lt;/auth-constraint&gt;
&lt;/security-constraint&gt;
&lt;login-config&gt;
    &lt;auth-method&gt;BASIC&lt;/auth-method&gt;
    &lt;realm-name&gt;userauthn&lt;/realm-name&gt;
&lt;/login-config&gt;
&lt;security-role&gt;
    &lt;description/&gt;
    &lt;role-name&gt;USERS&lt;/role-name&gt;
&lt;/security-role&gt;</pre>

<p>That about it, after you redeploy the application, the next time you try to access <code>/dropbox</code> you'll get a <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html%23sec10.4.2">401 Unauthorized</a> response unless you include a suitable <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html%23sec14.8">Authorization header</a> in the request.</p>
]]>

</content>
</entry>
<entry>
<title>Integrating Jersey and Abdera</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/mhadley/archive/2008/02/integrating_jer_2.html" />
<modified>2008-02-05T19:43:31Z</modified>
<issued>2008-02-05T19:38:56Z</issued>
<id>tag:weblogs.java.net,2008:/blog/mhadley/57.9142</id>
<created>2008-02-05T19:38:56Z</created>
<summary type="text/plain">I&apos;m working on an internal project that involves adding Atom Publishing Protocol support to a data store. Naturally, I&apos;m using Jersey for the HTTP side of things and decided to give Apache Abdera a try for simplifying working with feeds...</summary>
<author>
<name>mhadley</name>

<email>Marc.Hadley@sun.com</email>
</author>
<dc:subject>Web Services and XML</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/mhadley/">
<![CDATA[<p>I'm working on an internal project that involves adding <a href="http://tools.ietf.org/html/rfc5023">Atom Publishing Protocol</a> support to a data store. Naturally, I'm using <a href="http://jersey.dev.java.net/">Jersey</a> for the HTTP side of things and decided to give <a href="http://incubator.apache.org/abdera/">Apache Abdera</a> a try for simplifying working with feeds and entries.</p>

<p>With <a href="http://jsr311.dev.java.net/">JAX-RS</a> I can write a feed resource pretty easily:</p>

<pre>import java.net.URI;
import java.util.Date;
import javax.ws.rs.ConsumeMime;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.ProduceMime;
import javax.ws.rs.UriParam;
import javax.ws.rs.core.HttpContext;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.apache.abdera.model.Entry;
import org.apache.abdera.model.Feed;

@ProduceMime("application/atom+xml")
@ConsumeMime("application/atom+xml")
@Path("myfeed")
public class FeedResource {
   @HttpContext
   private UriInfo uriInfo;

   @GET
   public Feed getFeed() {
       Feed f = AbderaSupport.getAbdera().getFactory().newFeed();
       f.setTitle("...");
       f.setId(...);
       f.addAuthor(...);
       f.setUpdated(...);
       URI feedLink = uriInfo.getRequestUri();
       f.addLink(feedLink.toString(),"self");
       for (...) {
           Entry e = f.addEntry();
           URI entryLink = ...
	       f.addLink(entryLink.toString(),"alternate");
           ...
       }
       return f;
   }

   @POST
   public Response addEntry(Entry e) {
       Entry newEntry = AbderaSupport.getAbdera().newEntry();
       URI entryLink = ...;
       ...
       return Response.created(entryLink).entity(newEntry).build();
   }
}</pre>

<p>The <code>getFeed</code> method creates an Abdera <code>Feed</code> instance and returns it in response to a <code>GET</code> request on the <code>myfeed</code> URI. The <code>addEntry</code> method is called with an Abdera <code>Entry</code> instance that corresponds to the body of a <code>POST</code> request. It does whatever is necessary to persist the new entry and then creates and returns a <code>201 Created</code> response with a <code>Location</code> header and a new <code>Entry</code> corresponding to the persisted entry as the body of the response.</p>

<p>To allow use of Abdera's <a href="http://incubator.apache.org/abdera/docs/api/org/apache/abdera/model/Entry.html"><code>Entry</code></a> and <a href="http://incubator.apache.org/abdera/docs/api/org/apache/abdera/model/Feed.html"><code>Feed</code></a> types in resource method arguments and return types I had to implement the JAX-RS interfaces <a href="https://jsr311.dev.java.net/nonav/javadoc/javax/ws/rs/ext/MessageBodyReader.html"><code>MessageBodyReader</code></a> and <a href="https://jsr311.dev.java.net/nonav/javadoc/javax/ws/rs/ext/MessageBodyWriter.html"><code>MessageBodyWriter</code></a> for those types. This turned out to be quite simple with Abdera:</p>

<pre>import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.ws.rs.ProduceMime;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import org.apache.abdera.Abdera;
import org.apache.abdera.model.Document;
import org.apache.abdera.model.Element;
import org.apache.abdera.model.Entry;
import org.apache.abdera.model.Feed;

@Provider
@ProduceMime("application/atom+xml")
@ConsumeMime("application/atom+xml")
public class AbderaSupport implements MessageBodyWriter&lt;Object&gt;, 
       MessageBodyReader&lt;Object&gt; {

   private final static Abdera abdera = new Abdera();

   public static Abdera getAbdera() {
       return abdera;
   }

   public long getSize(Object arg0) {
       return -1;
   }

   public boolean isWriteable(Class&lt;?&gt; type) {
       return (Feed.class.isAssignableFrom(type) || Entry.class.isAssignableFrom(type));
   }

   public void writeTo(Object feedOrEntry, MediaType mediaType, 
           MultivaluedMap&lt;String, Object&gt; headers, 
           OutputStream outputStream) throws IOException {
       if (feedOrEntry instanceof Feed) {
           Feed feed = (Feed)feedOrEntry;
           Document&lt;Feed&gt; doc = feed.getDocument();
           doc.writeTo(outputStream);
       } else {
           Entry entry = (Entry)feedOrEntry;
           Document&lt;Entry&gt; doc = entry.getDocument();
           doc.writeTo(outputStream);
       }
   }

   public boolean isReadable(Class&lt;?&gt; type) {
       return (Feed.class.isAssignableFrom(type) || Entry.class.isAssignableFrom(type));
   }

   public Object readFrom(Class&lt;Object&gt; feedOrEntry, MediaType mediaType, 
           MultivaluedMap&lt;String, String&gt; headers, 
           InputStream inputStream) throws IOException {
       Document&lt;Element&gt; doc = getAbdera().getParser().parse(inputStream);
       Element el = doc.getRoot();
       if (feedOrEntry.isAssignableFrom(el.getClass())) {
           return el;
       } else {
           throw new IOException("Unexpected payload, expected "+feedOrEntry.getName()+
               ", received "+el.getClass().getName());
       }
   }
}
</pre>

<p>Notice I actually implemented <code>MessageBodyReader&lt;Object&gt;</code> rather than <code>MessageBodyReader&lt;Entry&gt;</code> and <code>MessageBodyReader&lt;Feed&gt;</code>. This allowed me to support both types in the same class. Same for <code>MessageBodyWriter</code>. The <code>isReadable</code> and <code>isWriteable</code> methods allow a class to reject types it doesn't support.

<p>Abdera is shaping up to be a nice API for working with Atom documents. Hopefully the above demonstrates how easy it is to integrate support for new formats into Jersey.</p>]]>

</content>
</entry>
<entry>
<title>WADLing in Jersey</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/mhadley/archive/2007/12/wadling_in_jers.html" />
<modified>2008-03-02T15:18:12Z</modified>
<issued>2007-12-21T21:43:03Z</issued>
<id>tag:weblogs.java.net,2007:/blog/mhadley/57.8884</id>
<created>2007-12-21T21:43:03Z</created>
<summary type="text/plain">For a long time you&apos;ve been able to retrieve a WADL document that describes the set of resources that make up a Jersey application. However, the returned WADL was generated at compile time and would only include resources that were...</summary>
<author>
<name>mhadley</name>

<email>Marc.Hadley@sun.com</email>
</author>
<dc:subject>Web Services and XML</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/mhadley/">
<![CDATA[<p>For a long time you've been able to retrieve a <a href="http://wadl.dev.java.net/">WADL</a> document that describes the set of resources that make up a <a href="http://jersey.dev.java.net/">Jersey</a> application. However, the returned WADL was generated at compile time and would only include resources that were statically known. In recent weeks we've switched many parts of Jersey including the WADL subsystem to use a shared abstract resource model that is built at runtime. This has allowed us to add some additional functionality that I'll describe here.</p>

<p>The main new feature is that you can now retrieve a WADL for an individual resource. The resource can be a static resource which is described in the application WADL or it can be a resource for which you've received a link in some returned representation. For an example, consider the <a href="https://jersey.dev.java.net/source/browse/jersey/trunk/jersey/examples/SimpleConsole/">Simple Console</a> example in the Jersey distribution. This example has two resource:</p>

<pre>
http://127.0.0.1:9998/resources/form
http://127.0.0.1:9998/resources/form/colours
</pre>

<p>If you retrieve the "global" WADL (available at <code>http://127.0.0.1:9998/resources/application.wadl</code>) you get the following:</p>

<pre>&lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;
&lt;application xmlns="http://research.sun.com/wadl/2006/10"&gt;
	&lt;resources base="http://localhost:9998/resources/"&gt;
		&lt;resource path="/form"&gt;
			&lt;method name="GET"&gt;
				&lt;response&gt;
					&lt;representation mediaType="text/html" /&gt;
				&lt;/response&gt;
			&lt;/method&gt;
			&lt;method name="POST"&gt;
				&lt;request&gt;
					&lt;representation mediaType="application/x-www-form-urlencoded" /&gt;
				&lt;/request&gt;
				&lt;response&gt;
					&lt;representation mediaType="text/html" /&gt;
				&lt;/response&gt;
			&lt;/method&gt;
			&lt;resource path="colours" /&gt;
		&lt;/resource&gt;
	&lt;/resources&gt;
&lt;/application&gt;
</pre>

<p>From this you can see that you can get the "form" resource and post a HTML form to it and both will return some HTML. Also notice that there's a resource element with path <code>colours</code> but no other information about that resource. This is due to the "colours" resource being dynamically created by the subresource locator in <a href="https://jersey.dev.java.net/source/browse/jersey/trunk/jersey/examples/SimpleConsole/src/com/sun/ws/rest/samples/console/resources/Form.java?rev=590&view=markup">Form.java</a>:</p>

<pre>
@Path("/form")
@ProduceMime("text/html")
public class Form {
    
    @Path("colours")
    public Colours getColours() {
        return coloursResource;
    }
    
    ...
}
</pre>

<p>With the latest changes to Jersey you can now get information on such dynamic resources by GETing the resource with an <code>Accept: application/vnd.sun.wadl+xml</code> header that specifies that you want WADL rather than another representation. The Jersey runtime will inspect the object returned by the subresource locator and dynamically generate a WADL description. Thus:</p>

<pre>GET /resources/form/colours
Accept: application/vnd.sun.wadl+xml</pre>

<p>will return:</p>

<pre>
&lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;
&lt;application xmlns="http://research.sun.com/wadl/2006/10"&gt;
	&lt;resources base="http://localhost:9998/resources/"&gt;
		&lt;resource path="form/colours"&gt;
			&lt;method name="GET"&gt;
				&lt;request&gt;
					&lt;param xmlns:xs="http://www.w3.org/2001/XMLSchema" type="xs:string" style="query" name="match" /&gt;
				&lt;/request&gt;
				&lt;response&gt;
					&lt;representation mediaType="text/plain" /&gt;
				&lt;/response&gt;
			&lt;/method&gt;
			&lt;method name="GET"&gt;
				&lt;request&gt;
					&lt;param xmlns:xs="http://www.w3.org/2001/XMLSchema" type="xs:string" style="query" name="match" /&gt;
				&lt;/request&gt;
				&lt;response&gt;
					&lt;representation mediaType="application/json" /&gt;
				&lt;/response&gt;
			&lt;/method&gt;
		&lt;/resource&gt;
	&lt;/resources&gt;
&lt;/application&gt;
</pre>

<p>which corresponds to the resource class <a href="https://jersey.dev.java.net/source/browse/jersey/trunk/jersey/examples/SimpleConsole/src/com/sun/ws/rest/samples/console/resources/Colours.java?rev=532&view=markup">Colours.java</a>.

<p>The above works except in the case that the resource supports the GET method but does not declare the supported media types (equivalent to <code>@ProduceMime("*/*")</code>). In this case the resource GET method will be invoked for any value of the <code>Accept</code> including WADL so we've added an alternate way of getting the WADL. Rather than GETing the resource you can use a HTTP OPTIONS request. The body of the returned response will be a WADL describing the resource.</p>

<p>All of the above is currently implemented in the trunk and will be included in the forthcoming 0.5 snapshot release.</p>]]>

</content>
</entry>
<entry>
<title>Integrating Jersey and Guice</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/mhadley/archive/2007/11/integrating_jer_1.html" />
<modified>2007-11-19T15:14:10Z</modified>
<issued>2007-11-19T15:13:52Z</issued>
<id>tag:weblogs.java.net,2007:/blog/mhadley/57.8681</id>
<created>2007-11-19T15:13:52Z</created>
<summary type="text/plain">Further to my recent post about integrating Jersey and Spring, Christian Rivasseau shows how to integrate Jersey and Guice. As Paul notes in comments to that post, we plan to further simplify integration of template engines like Freemarker but its...</summary>
<author>
<name>mhadley</name>

<email>Marc.Hadley@sun.com</email>
</author>
<dc:subject>Web Services and XML</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/mhadley/">
<![CDATA[<p>Further to my recent post about <a href="http://weblogs.java.net/blog/mhadley/archive/2007/09/integrating_jer.html">integrating Jersey and Spring</a>, Christian Rivasseau shows how to <a href="http://objectif-naiade.blogspot.com/2007/11/integrating-jersey-with-guice-and.html">integrate Jersey and Guice</a>. As <a href="http://blogs.sun.com/sandoz/">Paul</a> notes in comments to that post, we plan to further simplify integration of template engines like Freemarker but its great to see the existing resource provider SPI working for another IoC framework.]]>

</content>
</entry>
<entry>
<title>Early Draft Review of JSR 311</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/mhadley/archive/2007/11/early_draft_rev.html" />
<modified>2007-11-05T16:12:54Z</modified>
<issued>2007-11-05T16:12:43Z</issued>
<id>tag:weblogs.java.net,2007:/blog/mhadley/57.8569</id>
<created>2007-11-05T16:12:43Z</created>
<summary type="text/plain">The first early draft of JSR 311 is now available for review, download the spec and Javadoc here. As the name suggests this is an early draft and the specification is far from complete but it does provide an early...</summary>
<author>
<name>mhadley</name>

<email>Marc.Hadley@sun.com</email>
</author>
<dc:subject>Web Services and XML</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/mhadley/">
<![CDATA[<p>The first early draft of JSR 311 is now available for review, <a href="http://jcp.org/aboutJava/communityprocess/edr/jsr311/index.html">download the spec and Javadoc here</a>. As the name suggests this is an early draft and the specification is far from complete but it does provide an early look at the current API. You can also find a <a href="https://jsr311.dev.java.net/issues/buglist.cgi?Submit+query=Submit+query&component=jsr311&subcomponent=www&issue_status=UNCONFIRMED&issue_status=NEW&issue_status=STARTED&issue_status=REOPENED&issue_status=RESOLVED&issue_status=VERIFIED&issue_status=CLOSED&version=current&email1=&emailtype1=exact&emailassigned_to1=1&email2=&emailtype2=exact&emailreporter2=1&issueidtype=include&issue_id=&changedin=&votes=&chfieldfrom=&chfieldto=Now&chfieldvalue=&short_desc=&short_desc_type=fulltext&long_desc=&long_desc_type=fulltext&issue_file_loc=&issue_file_loc_type=fulltext&status_whiteboard=&status_whiteboard_type=fulltext&field0-0-0=noop&type0-0-0=noop&value0-0-0=&cmdtype=doit&order=Reuse+same+sort+as+last+time">list of current issues here</a>.</p>

<p>Please send feedback on the specification, Javadocs or current issues to users [at] jsr311.dev.java.net.</p>]]>

</content>
</entry>
<entry>
<title>Integrating Jersey and Spring</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/mhadley/archive/2007/09/integrating_jer.html" />
<modified>2008-06-23T14:11:31Z</modified>
<issued>2007-09-14T17:18:29Z</issued>
<id>tag:weblogs.java.net,2007:/blog/mhadley/57.8245</id>
<created>2007-09-14T17:18:29Z</created>
<summary type="text/plain">To further test the new resource provider SPI I described earlier I thought I&apos;d try building a new resource provider that defers to Spring for resource creation. Note that I&apos;ve never used Spring before so if there are better ways...</summary>
<author>
<name>mhadley</name>

<email>Marc.Hadley@sun.com</email>
</author>
<dc:subject>Web Services and XML</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/mhadley/">
<![CDATA[<p>To further test the new resource provider SPI I <a href="http://weblogs.java.net/blog/mhadley/archive/2007/09/new_jersey_feat.html">described earlier</a> I thought I'd try building a new resource provider that defers to <a href="http://springframework.org/">Spring</a> for resource creation. Note that I've never used Spring before so if there are better ways to accomplish what I did please let me know. I also ran into a problem that limited the integration more than I'd prefer (details at the <a href="#problem">end of this post</a>). The <a href="https://jersey.dev.java.net/servlets/SummarizeList?listName=dev">Jersey dev list</a> would be a great place to post any suggestions on how to improve the integration.</p>

<h4>Implementation</h4>

<p>The first task was to write a <code>ResourceProvider</code> implementation that uses Spring for resource creation. This is pretty straightforward and the <code>getInstance</code> method turned out to require only a few lines of code:</p>

<pre>public Object getInstance(ResourceProviderContext context) {
  try {
    initSpringContext(context);
    initBeanName();
    Object resource = springContext.getBean(beanName, resourceClass);
    context.injectDependencies(resource);
    return resource;
  } catch (Exception ex) {
    throw new ContainerException("Unable to create resource", ex);
  }
}</pre>
    
<p>The <code>ResourceProvider</code> interface only supplies a <code>ResourceProviderContext</code> to the <code>getInstance</code> method so I had to defer some initialization code to that method that would have fit better in the <code>init</code> method. I'll check if it makes sense to  add a <code>ResourceProviderContext</code> to the <code>init</code> method but for this experiment I stuck with the SPI as is. The <code>initSpringContext</code> method uses the <code>ResourceProviderContext</code> to get the <code>ServletContext</code> which is then used to get the Spring <code>ApplicationContext</code> which has been initialized in <a href="http://static.springframework.org/spring/docs/2.0.x/reference/beans.html#context-create">the suggested way</a>.</p>

<pre>protected static synchronized void initSpringContext(
      ResourceProviderContext context) {
  if (springContext==null) {
    DummyResource r = new DummyResource();
    context.injectDependencies(r);
    springContext = WebApplicationContextUtils.getRequiredWebApplicationContext(
        r.servletConfig.getServletContext());
  }
}</pre>

<p><code>DummyResource</code> is a simple annotated static inner class that is used as an injection target:</p>

<pre>public static class DummyResource {
  @Resource
  public ServletConfig servletConfig;
}</pre>

<p>Jersey is based on annotated classes whereas Spring is based on named beans. The Spring <code>ResourceProvider</code> needs to map a class name to a Spring bean name which is accomplished with the <code>initBeanName</code> method:</p>

<pre>protected synchronized void initBeanName() {
  if (beanName==null) {
    String names[] = springContext.getBeanNamesForType(resourceClass);
    if (names.length==0)
      throw new RuntimeException("No configured bean for "+resourceClass.getName());
    else if (names.length>1)
      throw new RuntimeException("Multiple configured beans for "+resourceClass.getName());
    beanName=names[0];
  }
}</pre>

<p>I couldn't see any straightforward way to determine which bean to use for a given resource class if there is more than one defined at the top level so the provider requires a single top-level bean for each resource class.</p>

<p>The final task was to define a new annotation that instructs the Jersey runtime to use the Spring resource provider:</p>

<pre>@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ResourceFactory(SpringProvider.class)
public @interface SpringFactory {}</pre>

<h4>Example</h4>

<p>With the above implemented you can now write a resource class whose instantiation is controlled by Spring:</p>

<pre>@UriTemplate("{id}")
@SpringFactory
public class SpringResource {
    
  private String name;
    
  public SpringResource() {
    name="unset";
  }

  public String getName() {
    return name;
  }
    
  public void setName(String name) {
    this.name = name;
  }
    
  @HttpMethod("GET")
  @ProduceMime("text/plain")
  public String getDescription() {
    return "Name: "+getName();
  }
}</pre>

<p>With the following <code>applicationContext.xml</code> in the <code>WEB-INF</code> directory the resource will report its name as "Mr. Bean" thus demonstrating Spring-provided resource injection.</p>

<pre>&lt;beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
      http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"&gt;
  &lt;bean id="bean1" scope="prototype" class="com.sun.ws.rest.spring.resources.SpringResource"&gt;
    &lt;property name="name" value="Mr. Bean"/&gt;
  &lt;/bean&gt;
&lt;/beans&gt;</pre>

<p>The complete code is <a href="http://weblogs.java.net/blog/mhadley/SpringServlet.zip">available here</a>. No libraries are included in the ZIP file so you'll have to patch up the references to the required Jersey and Spring libraries.</p>

<h4>Integration Shortcoming</h4>
<a id="problem" name="problem"/>

<p>I couldn't see any way to add support for Jersey-defined resources as constructor parameters. In an <a href="http://weblogs.java.net/blog/mhadley/archive/2007/09/new_jersey_feat.html">earlier post</a> I described the new support for non-empty constructors. When using the Spring resource provider, the constructor can only include resources defined within the Spring configuration, not values supplied by Jersey. Is there a Spring API I could use to programatically add support for Jersey-defined constructor parameters ?</p>
]]>

</content>
</entry>
<entry>
<title>NetBeans Jersey Tooling</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/mhadley/archive/2007/09/netbeans_jersey.html" />
<modified>2007-09-10T20:37:41Z</modified>
<issued>2007-09-10T20:37:31Z</issued>
<id>tag:weblogs.java.net,2007:/blog/mhadley/57.8217</id>
<created>2007-09-10T20:37:31Z</created>
<summary type="text/plain">A couple of video&apos;s demonstrating NetBeans 6 support for creating Jersey-based Web services: Part 1: Building and Deploying Part 2: Testing and Invoking This is an up-to-date version of the demo we showed in our JavaOne session this year....</summary>
<author>
<name>mhadley</name>

<email>Marc.Hadley@sun.com</email>
</author>
<dc:subject>Web Services and XML</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/mhadley/">
<![CDATA[<p>A couple of video's demonstrating <a href="http://www.netbeans.org/community/releases/60/index.html">NetBeans 6</a> support for creating <a href="http://jersey.dev.java.net/">Jersey</a>-based Web services:</p>

<ul>
<li><a href="http://www.youtube.com/watch?v=cDdfVMro99s">Part 1: Building and Deploying</a></li>
<li><a href="http://www.youtube.com/watch?v=_c-CCVy4_Eo">Part 2: Testing and Invoking</a></li>
</ul>

<p>This is an up-to-date version of the demo we showed in our <a href="http://www28.cplan.com/cc158/session_details.jsp?isid=285410&ilocation_id=158-1&ilanguage=english">JavaOne session</a> this year.</p>]]>

</content>
</entry>
<entry>
<title>New Jersey Features</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/mhadley/archive/2007/09/new_jersey_feat.html" />
<modified>2008-06-23T14:12:54Z</modified>
<issued>2007-09-07T17:05:37Z</issued>
<id>tag:weblogs.java.net,2007:/blog/mhadley/57.8201</id>
<created>2007-09-07T17:05:37Z</created>
<summary type="text/plain">I recently merged the experimental &quot;resourcefactory&quot; branch back into the main Jersey trunk. The new code includes the following features and changes: A change to the default resource object lifecyle from singleton to per-request Support for non-empty resource class constructors...</summary>
<author>
<name>mhadley</name>

<email>Marc.Hadley@sun.com</email>
</author>
<dc:subject>Web Services and XML</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/mhadley/">
<![CDATA[<p>I recently merged the experimental "resourcefactory" branch back into the main Jersey trunk. The new code includes the following features and changes:</p>

<ul>
<li>A change to the default resource object lifecyle from singleton to per-request</li>
<li>Support for non-empty resource class constructors</li>
<li>A new SPI for plugging-in new resource providers</li>
</ul>

<p>Details on these changes below</p>

<h4>Lifecycle Changes</h4>

<p>Prior to the merge the Jersey runtime would create a single instance of a resource class and use that for all requests. Resource classes had to be re-entrant and thread safe. Following the merge the default scope for a resource object is per-request, i.e. the Jersey runtime creates a new instance of a resource class for each request. This change brings Jersey back in line with the current JSR 311 specification which requires a default per-request life-cycle. The old behavior can be recovered by annotating a resource class with the <code>Singleton</code> annotation from the <code>com.sun.ws.rest.spi.resource</code> package. If you want to be explicit about a resource classes life-cycle rather than rely on the default you can also use the <code>PerRequest</code> annotation from the same package. More on how these annotations work in the description of the new SPI below.</p>

<h4>Non-empty Constructors</h4>

<p>Prior to the merge a resource class was required to have a zero argument constructor that the Jersey runtime would use when creating the singleton instance. Following the merge this requirement has been relaxed such that constructors can now have arguments. This in conjunction with the change to a default per-request lifecycle allows a more natural use of constructors to perform instance initialization, e.g.:</p>

<pre>@UriTemplate("entries/{id}")
public class Entry {
  
  EntryEntity entity;

  public Entry(@UriParam("id") String id) {
    entity = findEntryEntity(id);
    ...
  }

  @HttpMethod
  @ProduceMime({"application/json", "application/xml"})
  public EntryEntity getEntity() {
    return entity;
  }
}</pre>

<p>The arguments allowed in a resource class constructor depends on the resource provider used to create an instance of the resource class (see the description of the new SPI below). For default per-request resource classes you can use any combination of parameters annotated with <code>UriParam</code>, <code>UriParam</code>, <code>QueryParam</code>, <code>MatrixParam</code>, <code>HeaderParam</code> or <code>HttpContext</code>. Singleton resource classes must still have a zero argument constructor.</p>

<h4>Resource Provider SPI</h4>

<p>The new <a href="https://jersey.dev.java.net/source/browse/jersey/trunk/jersey/src/spi/com/sun/ws/rest/spi/resource/">resource provider SPI</a> allows plugging-in of custom resource class factories and is used internally to support the per-request and singleton life-cycles. If you're not planning to develop a new resource provider you can safely stop reading here unless of course you are curious as to how the above features are implemented.</p>

<p>A resource provider is responsible for creating instances of resource classes for the Jersey runtime to use. A resource provider implements <a href="https://jersey.dev.java.net/source/browse/jersey/trunk/jersey/src/spi/com/sun/ws/rest/spi/resource/ResourceProvider.java?view=markup"><code>ResourceProvider</code></a> and must have a zero-argument constructor. The Jersey runtime will create a new instance of a resource provider for each resource class that uses that provider so there is no need for a provider to maintain a list or map of resource classes and instances thereof.</p>

<p>The Jersey runtime identifies the resource provider to use for a particular resource class by examining the annotations on that resource class. It examines each class-level annotation in turn looking for a <a href="https://jersey.dev.java.net/source/browse/jersey/trunk/jersey/src/spi/com/sun/ws/rest/spi/resource/ResourceFactory.java?view=markup"><code>ResourceFactory</code></a> meta-annotation and then uses the value of that annotation or the default per-request provider if none is found as the resource provider. This approach allows you to define new annotations that point to a particular resource provider, e.g. Jersey defines the <a href="https://jersey.dev.java.net/source/browse/jersey/trunk/jersey/src/spi/com/sun/ws/rest/spi/resource/Singleton.java?view=markup"><code>Singleton</code></a> annotation as follows:</p>

<pre>@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ResourceFactory(SingletonProvider.class)
public @interface Singleton {}</pre>

<p>Note the <code>ResourceFactory</code> meta-annotation which points to <a href="https://jersey.dev.java.net/source/browse/jersey/trunk/jersey/src/impl/com/sun/ws/rest/impl/resource/SingletonProvider.java?view=markup"><code>SingletonProvider</code></a>, the Jersey-supplied resource provider for singleton resource classes.</p>

<p>The <code>getInstance</code> method of <a href="https://jersey.dev.java.net/source/browse/jersey/trunk/jersey/src/spi/com/sun/ws/rest/spi/resource/ResourceProvider.java?view=markup"><code>ResourceProvider</code></a> supplies a <a href="https://jersey.dev.java.net/source/browse/jersey/trunk/jersey/src/spi/com/sun/ws/rest/spi/resource/ResourceProviderContext.java?view=markup"><code>ResourceProviderContext</code></a> that a resource provider can use to obtain values for the resource class constructor's arguments and perform dependency injection on a newly created resource class instance, <a href="https://jersey.dev.java.net/source/browse/jersey/trunk/jersey/src/impl/com/sun/ws/rest/impl/resource/PerRequestProvider.java?view=markup"><code>PerRequestProvider</code></a> shows an example of its use. A resource provider is expected to supply values for constructor arguments unknown to Jersey (anything not annotated with <code>UriParam</code>, <code>UriParam</code>, <code>QueryParam</code>, <code>MatrixParam</code>, <code>HeaderParam</code> or <code>HttpContext</code>) and inject additional dependencies as required.</p>

<p>Its hoped that this SPI will support integration of Jersey with a variety of frameworks. Let us know if anything is unclear or needs improvement.</p>]]>

</content>
</entry>
<entry>
<title>Comments on JSR 311</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/mhadley/archive/2007/08/comments_on_jsr.html" />
<modified>2007-08-20T16:52:34Z</modified>
<issued>2007-08-17T22:57:09Z</issued>
<id>tag:weblogs.java.net,2007:/blog/mhadley/57.8052</id>
<created>2007-08-17T22:57:09Z</created>
<summary type="text/plain">Patrick Mueller has some nice things to say about JSR 311 but also has some concerns that I&apos;d like to address. The first and easiest to address is the license under which the RI (Jersey) is distributed. Rather than GPL...</summary>
<author>
<name>mhadley</name>

<email>Marc.Hadley@sun.com</email>
</author>
<dc:subject>Web Services and XML</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/mhadley/">
<![CDATA[<p>Patrick Mueller has <a href="http://www-03.ibm.com/developerworks/blogs/page/pmuellr?entry=on_jsr_311">some nice things to say about JSR 311</a> but also has some concerns that I'd like to address.</p>

<p>The first and easiest to address is the license under which the RI (<a href="http://jersey.dev.java.net/">Jersey</a>) is distributed. Rather than GPL as Patrick states, Jersey is actually available under the <a href="http://www.opensource.org/licenses/cddl1.php">CDDL license</a>. Apologies if that wasn't entirely clear from the Jersey home page, I've just fixed that.</p>

<p>Patrick also raised a metaphorical eyebrow over some of the non-goals listed in the <a href="https://jsr311.dev.java.net/drafts/spec20070703.pdf">latest editors draft of the specification (PDF)</a>:</p>

<blockquote>Support for Java versions prior to J2SE 5.0: The API will make extensive use of annotations and will require J2SE 5.0 or later. <i>Read: Sorry, J2ME. Sorry, folks stuck on Java 1.4.</i></blockquote>

<p>Yes, certainly it would have been good to be able to offer something to Java 1.4 users but we felt that an annotation-based approach offered the best solution going forward and decided to focus on that. On the Java ME side, the fact that 311 is primarily a server side API (see the final point) means it is less suitable for the ME environment anyway.</p>

<blockquote>Description, registration and discovery: The specification will neither define nor require any service description, registration or discovery capability.
<i>Read: We'll figure this out later; hopefully we won't have to change anything in this spec once we start thinking about this aspect of the problem.</i></blockquote>

<p>Several folks whose opinions I respect think that description is antithetical to REST and given that there's no accepted standard for describing RESTful Web services (beyond the resource representations themselves) its hard to see what we could have done here. Certainly I have my <a href="http://wadl.dev.java.net/">own favorite description language</a> and Jersey will automatically produce a WADL description of a set of JSR 311 resource classes but it would be wrong to require support for something like WADL in JSR 311.</p>

<blockquote>Client APIs: The specification will not define client-side APIs. Other specifications are expected to provide such functionality.
<i>Read: We'll figure this out later; hopefully we won't have to change anything in this spec once we start thinking about this aspect of the problem.</i></blockquote>

<p>The goal of JSR 311 is to make it simple to write RESTful Web <i>services</i> in Java. Of course we're keeping an eye out for classes and interfaces that might be useful on the client side (those concerned with URI manipulation seem like reasonable candidates) but the primary focus is on exposing Java objects as RESTful services so I don't think there's too much danger of unexpected overlap with any new client-side HTTP API that might emerge in the future.</p>]]>

</content>
</entry>
<entry>
<title>Jersey</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/mhadley/archive/2007/06/jersey.html" />
<modified>2007-08-20T16:52:38Z</modified>
<issued>2007-06-20T20:47:26Z</issued>
<id>tag:weblogs.java.net,2007:/blog/mhadley/57.7695</id>
<created>2007-06-20T20:47:26Z</created>
<summary type="text/plain">We just released the source code for the reference implementation of JSR 311 as project Jersey. Paul&apos;s post has more details. It seems we&apos;ve already had our first bug report, keep them coming....</summary>
<author>
<name>mhadley</name>

<email>Marc.Hadley@sun.com</email>
</author>
<dc:subject>Web Services and XML</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/mhadley/">
<![CDATA[<p><img src="http://jersey.dev.java.net/images/Jersey_yellow.png" align="left"/>We just released the source code for the reference implementation of <a href="http://jsr311.dev.java.net/">JSR 311</a> as <a href="http://jersey.dev.java.net">project Jersey</a>. <a href="http://blogs.sun.com/sandoz/entry/announcing_jersey">Paul's post</a> has more details.</p>

<p>It seems we've already had our <a href="https://jersey.dev.java.net/servlets/ReadMsg?list=dev&msgNo=1">first bug report</a>, keep them coming.</p>]]>

</content>
</entry>
<entry>
<title>What Leonard Said</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/mhadley/archive/2007/06/what_leonard_sa.html" />
<modified>2007-08-20T16:52:40Z</modified>
<issued>2007-06-06T22:39:17Z</issued>
<id>tag:weblogs.java.net,2007:/blog/mhadley/57.7580</id>
<created>2007-06-06T22:39:17Z</created>
<summary type="text/plain">I&apos;ve been offline on holiday in the UK for the last couple of weeks and it seems I&apos;ve been missing out on an interesting debate about whether a description language for RESTful services is useful or not. The debate so...</summary>
<author>
<name>mhadley</name>

<email>Marc.Hadley@sun.com</email>
</author>
<dc:subject>Web Services and XML</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/mhadley/">
<![CDATA[<p>I've been offline on holiday in the UK for the last couple of weeks and it seems I've been missing out on an interesting debate about whether a description language for RESTful services is useful or not. The debate so far is nicely summarized by Arnon Rotem-Gal-Oz in <a href="http://www.infoq.com/news/2007/06/rest-description-language">Debate: Does REST Need a Description Language?</a>.</p>

<p>Obviously as the author of the <a href="http://wadl.dev.java.net/">WADL specification</a> I think there is some utility in such a language and normally I'd be tempted to write a longer post addressing some of the points raised but rather than do that I'll instead direct you to Leonard Richardson's <a href="http://www.crummy.com/2007/06/04/0">It's Just A Hypermedia Format</a> which covers most of the things I'd have said had they not already been expressed so well.</p>

<p>One thing I would like to add since many people are concerned with the link to XML schema: the element attribute of the WADL representation element is <i>optional</i>; WADL can use XML schemas but it isn't built on them. In fact WADL doesn't presume XML will be used for entity bodies and it can easily describe an application built using other media types.</p>
]]>

</content>
</entry>
<entry>
<title>Google REST Describe</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/mhadley/archive/2007/04/google_rest_des.html" />
<modified>2008-03-17T21:43:32Z</modified>
<issued>2007-04-26T18:06:19Z</issued>
<id>tag:weblogs.java.net,2007:/blog/mhadley/57.7166</id>
<created>2007-04-26T18:06:19Z</created>
<summary type="text/plain">Thomas Steiner just released the first working demo of Google REST Describe. This tool takes a novel approach to creating WADL descriptions of Web applications by analyzing sample requests and responses and applying heuristics to extract descriptive information. You can...</summary>
<author>
<name>mhadley</name>

<email>Marc.Hadley@sun.com</email>
</author>
<dc:subject>Web Services and XML</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/mhadley/">
<![CDATA[<p>Thomas Steiner just released the first <a href="http://blog.tomayac.de/index.php?date=2007-04-26&time=18:05:54&perma=Google+REST+Describe.html">working demo of Google REST Describe</a>. This tool takes a novel approach to creating <a href="http://wadl.dev.java.net">WADL</a> descriptions of Web applications by analyzing sample requests and responses and applying heuristics to extract descriptive information. You can then manually add or modify metadata to improve the automatically generated description. Very cool.</p>

<p>Check it out <a href="http://tomayac.de/google-rest-describe/latest/RestDescribe.html">here</a>.</p>]]>

</content>
</entry>
<entry>
<title>Sun Web Developer Pack R1 with WADL and RESTful WS goodies</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/mhadley/archive/2007/03/sun_web_develop.html" />
<modified>2007-08-20T16:52:59Z</modified>
<issued>2007-03-13T18:02:17Z</issued>
<id>tag:weblogs.java.net,2007:/blog/mhadley/57.6808</id>
<created>2007-03-13T18:02:17Z</created>
<summary type="text/plain">As Dave already blogged: &quot;The Sun Web Developer Pack (SWDP) finally uncloaked today&quot;. In addition to the items Dave mentioned I&apos;d also like to point out that the pack contains prebuilt binaries of some WADL tools and an early access...</summary>
<author>
<name>mhadley</name>

<email>Marc.Hadley@sun.com</email>
</author>
<dc:subject>Web Services and XML</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/mhadley/">
<![CDATA[<p>As <a href="http://rollerweblogger.org/roller/entry/sun_web_developer_pack_r1">Dave already blogged</a>: "The <a href="http://developers.sun.com/web/swdp/">Sun Web Developer Pack</a> (SWDP) finally <a href="http://blogs.sun.com/arungupta/entry/introducing_sun_web_developer_pack">uncloaked</a> today". In addition to the items Dave mentioned I'd also like to point out that the pack contains prebuilt binaries of some <a href="http://wadl.dev.java.net/">WADL tools</a> and an early access API and runtime for development of RESTful Web services.</p>

<p>I <a href="http://weblogs.java.net/blog/mhadley/archive/2007/02/jsr_311_java_ap.html">blogged earlier about JSR 311</a>, I expect the API produced by JSR 311 will differ significantly to the RESTful WS API in SWDP R1 but the experience we gained building it and the runtime to support it has been very useful for testing some of our early assumptions and clarifying our thinking about the JSR. We hope you'll take it for a spin and let us know what you think.</p> 

]]>

</content>
</entry>

</feed>