Open Source’s Talent Advantage

1 Comment

Was reading an article on TheStreet.com about Why Wall Street Hates Open Source.  I think one of the things that business people often don’t know about is the talent advantage open source companies have.  Answer this question:  What are our hiring practices?  How do we hire people?

We know they can do the job

Most of the developers that come to the JBoss division of Red Hat were/are contributors to at least one of our open source projects.   Think about that for a second…Before we start paying somebody a dime, we’ve worked with our potential new employees months, sometimes years at a time.  We know what they are capable of.  We know the quality of their work.

We can hire anybody anywhere

The world is our labor market.  We can hire anybody anywhere without having to move them because we already have distributed development model.  A development model that our employee has already participated in.

Our developers have initiative and are self-motivated

Open source developers are uncommon.  Why?  It takes initiative, and lots of it.  You have to have the gumption to download the code and figure out how to build it.  Then you have to have the skills to be able to understand and dive into somebody else’s code so you can add your pet feature or fix a bug that is holding you up.  You have to go beyond the scope of your job description and learn something new.  When we hire a contributor, we know we have somebody that isn’t afraid to take initiative and drive things on their own.

Our developers already know our products

In my experience, the vast majority of our contributors are actually users of our products.  They’ve come to help, because they are missing a feature or bug that hinders the progress of the work they are being paid to do.  They know our products, but more importantly, they know what’s wrong with our products and what they don’t like about our products.

Our developers enjoy what they do

Core contributors often contribute during their free time.  People aren’t willing to give up free time if they don’t a) enjoy what they are doing, b) don’t like our products.

Our developers are part of a movement

Richard Stallman aside, open source is not socialism, yet it is a movement.  A movement most developers are proud to be part of.

Anyways, this is one of the many reasons I think Red Hat is built to last.

Creating a JBoss Modules zip

Leave a comment

I’ve extracted some of the build files from AS7 to create a maven project that can create a modules/ directory structure for Resteasy.  I wanted this so that people can easily patch/upgrade AS7 to the latest resteasy release.  It should be fairly easy to use the project as an archetype if you want to do it for other things.

Improved HornetQ Spring Integration

6 Comments

I’ve been doing some work on HornetQ SVN trunk to improve the embeddable HornetQ experience (you’ll see these improvements in the next HornetQ release).  You can disagree with me, but I thought that embedding HornetQ was a bit verbose, especially for JMS, so first of all, I wrote two wrapper classes to make this easier.  While these classes will be in the next release along with a full docbook explanation, here’s what configuring JMS looks like now:

import org.hornetq.jms.server.embedded.EmbeddedJMS;

...
EmbeddedJMS jms = new EmbeddedJMS();
jms.start();

This class will look for hornetq-configuration.xml, hornetq-jms.xml, and hornetq-users.xml within your classpath.  It also has the option of manually creating configuration objects via pojo instantiation if you desire (or if you want to wire it with Spring for instance).

Simple Spring Integration

Another thing I did was to provide some simple Spring integration with the HornetQ JMS implementation.  I wrote a simple class that extends EmbeddedJMS that will register any configured queues, topics, and ConnectionFactorys direction within the Spring application context so that other beans can reference them.  Here’s an example of bootstrapping HornetQ JMS and referencing a queue within a Spring message listener container.

<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-3.0.xsd">

   <bean id="EmbeddedJms" 
                class="org.hornetq.integration.spring.SpringJmsBootstrap" 
                init-method="start" destroy-method="stop"/>

   <bean id="listener"
             class="org.hornetq.tests.integration.spring.ExampleListener"/>

   <bean id="listenerContainer"
             class="org.springframework.jms.listener.DefaultMessageListenerContainer">
      <property name="connectionFactory" ref="ConnectionFactory"/>
      <property name="destination" ref="/queue/exampleQueue"/>
      <property name="messageListener" ref="listener"/>
   </bean>

</beans>

Again, this assumes you have configured HornetQ properly within HornetQ specific configuration files.  You can also manually declare HornetQ config objects within Spring and inject them into the EmbeddedJMS bean instance too if you don’t want to use HornetQ config files.

Right now, the code does not also register HornetQ objects within JNDI.  Do you think I should add this capability?  Anyways, I hope you’ll find this HornetQ + Spring integration useful in the next HornetQ release.

Want to rewrite JAXB?

4 Comments

I’ve been pretty frustrated with Sun’s JAXB and JBoss’s JBossXB implementations.  Here’s why:

* JAXB is not very extendable.  For example, I’d love to be able to define custom annotations that trigger callback APIs so that I can read/write custom properties from an XML document.  For example, ever try to do Map support?  I’ve also wanted to convert URLs to/from Link objects in resteasy with hooks into RESTEasy runtime for automatic URL writing.  I just couldn’t find a way to do it within resteasy.

* JAXB (both Sun’s and JBoss’s) is very slow to initialize.  Yeah, they parse very fast, but initialization speed is very slow because it has to do a lot of reflection on the classes that make up the JAXBContext and build a lot of data structures to do quick parsing.  You might be saying, “Big Deal!”.  But what I’ve found with JAXB and JBoss’s impl is that for the meta-models we’re trying to parse in JBoss AS, it can take as much as 1 second to initialize all the models.  That’s 1 second more added to boot time.  1 second to make embedded/unit testing slower.

So, this is why I started the fast-jaxb project under the RESTEasy SVN.  The way it works is that you provide it a set of classes and it generates Java code that uses SAX to parse XML.  The problem is, I haven’t had the time finish it, which is why I’m blogging to ask if anybody is interested in taking it over (or suggesting a good alternative for solving the goals/problems mentioned above).  Fast-JAXB has basically no initialization overhead compared to Sun’s JAXB implimentation.  I haven’t worked on the extension points though, nor do I support all the JAXB annotations.  I have also only worked on parsing XML, not generating XML.  Anybody interested in taking it over and driving it?  Give me a ping here on this blog…

Webinar on REST, RESTEasy, JBoss – March 23rd

Leave a comment

I’m doing a webinar tomorrow on REST, JAX-RS, RESTEasy, and REST-*.  I only have 40 minutes, so it will be a brief overview of all those subjects and how they fit into our EAP product.  I’ll be giving it twice:

9am – EST

2pm – EST

For more information, click here

Mapping response on client side

8 Comments

I’ve been prototyping a bit lately for the REST-* effort, specifically for BPM.  I rely heavily on Link headers to pass links around.  RESTEasy has become pretty decent at handling links on the client side.  Here’s an example of client request/responses and link following via link headers:

      InputStream jpdl = Thread.currentThread().getContextClassLoader().getResourceAsStream(file);
      ApacheHttpClientExecutor executor = new ApacheHttpClientExecutor();

      ClientRequest request = executor.createRequest("http://localhost:8081/bpm/definitions");
      request.body(mediaType, jpdl);
      Link definition = request.create();
      Assert.assertNotNull(definition);
      ClientResponse response = null;

      response = definition.request().head();
      Assert.assertEquals(200, response.getStatus());
      Link instanceFactory = response.getLinkHeader().getLinkByTitle("instances");

      MultipartFormDataOutput form = new MultipartFormDataOutput();
      form.addFormData("order", "$199.99", MediaType.APPLICATION_XML_TYPE);
      response = instanceFactory.request()
              .body(MediaType.MULTIPART_FORM_DATA_TYPE, form)
              .post();
      Assert.assertEquals(201, response.getStatus());
      System.out.println(response.getLinkHeader().toString());
      Link instance = response.getLocation();
      Assert.assertNotNull(instance);

      Link next = response.getLinkHeader().getLinkByTitle("continue");
      Assert.assertNotNull(next);

      Link variables = response.getLinkHeader().getLinkByTitle("variables");
      Link newVariables = response.getLinkHeader().getLinkByTitle("variable-template");

      response = variables.request().head();
      Assert.assertEquals(200, response.getStatus());
      System.out.println(response.getLinkHeader().toString());
      Link order = response.getLinkHeader().getLinkByTitle("order");
      String xml = order.request().getTarget(String.class);
      request = newVariables.request();
      response = request.pathParameter("var", "customer")
             .body(MediaType.APPLICATION_XML_TYPE, "bill")
              .put();
      Assert.assertEquals(201, response.getStatus());
      response = request.pathParameter("var", "customer")
             .body(MediaType.APPLICATION_XML_TYPE, "bill burke")
              .put();
      Assert.assertEquals(204, response.getStatus());

      response = next.request().post();
      Assert.assertEquals(204, response.getStatus());

The thing about this code, it is a little hard to read.  Because HTTP is being treated like a messaging API, the code is a conglomeration of simple API calls.  The RESTEasy client proxy framework provides a nice way to map Java method calls to HTTP requests.  It also allows you to map automatically, a response body to a Java object.  Unfortunately though, this doesn’t work that well for my usecases.  Because I’m relying a lot on Link headers to pass information around in REST-*, I need something that can represent an HTTP response as a whole in a nice way.

A POJO Response Mapping

So, I thought, why not define (or reuse JAX-RS annotations) to map an HTTP response to a Java POJO?  It would kind of be the opposite of the RESTEasy @Form feature (where form maps an incoming request to a POJO).  It could look something like this:

@ResponseMapping
@ExpectedCode(200)
public interface MyResponse {

   @Body
   public Customer getCustomer();

   @LinkHeader
   public Link getNext();

   @LinkHeader("last")
   public Link getLastCustomer();

   @Header("ETag")
   public String getHash();

}

In this example, the client code would be expecting a response code of 200 (OK), a message body converted to a Customer object, a Link header named “next”, and a HTTP response header “ETag”. Using the RESTEasy proxy framework, you could then return this as a method return value, i.e.

@Path("/customers")
public interface CustomerClient {

   @Path("{id}")
   @Produces("application/xml")
   public MyResponse getCustomer(@PathParam("id") int custId);
}

What about errors?

For responses where the response code does not match, you could define similar mappings on an exception class.

@ResponseMapping
@ExpectedCode(404)
public class NotFoundException extends RuntimeException {}

You’d integrate it with the RESTEasy proxy framework by putting it within the throws clause.

@Path("/customers")
public interface CustomerClient {

   @Path("{id}")
   @Produces("application/xml")
   public MyResponse getCustomer(@PathParam("id") int custId) throws NotFoundException;
}

What do you think?
Maybe I’m going a little overboard here. Maybe not? I don’t know. Let me know what you think.

Speaking at new Boston JBoss User Group 2/9

Leave a comment

Jesper Pederson has created a Boston JBoss User Group.  Our first meeting is next Tuesday, February 9th.  I’m the first speaker and will be giving an intro to REST, JAX-RS, and, if I have time, some of the stuff that we’re doing at REST-* (rest-star.org).  Please click here for more details.

Older Entries Newer Entries

%d bloggers like this: