Angry Bill

tech talk radio

Archive for the 'jboss' Category


Resteasy Project: JAX-RS Restful Web Services implementation

Posted by billburke on February 25, 2008

I’m pleased to announce the first beta release of the JBoss Resteasy JAX-RS implementation!

After about 4 months of on and off development, I finally have a working version of the new JSR-311, JAX-RS specification. For those of you who don’t know, JSR-311 is a RESTFul Web Services implementation for Java and is slated to be included within Java EE 6. The spec is still a bit of a moving target, but its still pretty useful. Let me know what you think!

Features:

  • JAX-RS implementation (almost full, still have a few minor things here and there)
  • Portable to any app-server/Tomcat that runs on JDK 5 or higher
  • EJB 3.0 and Spring integration
  • Client framework to make writing HTTP clients easy (JAX-RS only define server bindings)

Where can I find out more?

All information, including where to download it, is available on our Resteasy WIKI.

Posted in REST, Webservices, java, jboss | 10 Comments »

Scannotation fix for /WEB-INF/classes

Posted by billburke on February 14, 2008

I have a confession.  I didn’t really test the code that allowed you to scan /WEB-INF/classes for my Scannotation project.  In the old code, if you run within Tomcat, you’ll get a “jndi:” protocol based URL that my code doesn’t understand yet how to scan

Instead, I obtain the URL by doing a ServletContext.getRealPath(”/WEB-INF/classes”).  Unfortunately, this is not guaranteed to work by the specification, so, if you run into this problem, you’re gonna have to find another way to scan this directory portably.

I’ve released a version 1.02 of Scannotation that has this RealPath fix along with a few other minor bug fixes I found while using the library.

Posted in jboss | No Comments »

JBoss Unit Testing with Maven

Posted by billburke on February 13, 2008

Recently, I had the need to do some JBoss integration testing in a Maven environment. I had to piece together how to do this and couldn’t find one reference point that just gave me all the maven XML I had to cut/paste. So, I thought I’d log it here for others to reference. First of all, in your src/test/resources directory you need a jndi.properties file:

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=jnp://localhost:1099

This isn’t used by any of the maven plugins i’m going to show you, but you will need it in your test code if you want to connect at all with JBoss. Next, here’s the build fragment of what you need in your pom.xml

   <build>
      <finalName>jsr311-war</finalName>
      <plugins>
         <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>jboss-maven-plugin</artifactId>
            <configuration>
               <jbossHome>/Users/billburke/jboss/jboss-4.2.2.GA</jbossHome>
            </configuration>
            <executions>
               <execution>
                  <id>jboss-deploy</id>
                  <phase>pre-integration-test</phase>
                  <goals>
                     <goal>deploy</goal>
                  </goals>
                  <configuration>
                     <fileName>${basedir}/target/jsr311-war.war</fileName>
                  </configuration>
               </execution>
               <execution>
                  <id>jboss-undeploy</id>
                  <phase>post-integration-test</phase>
                  <goals>
                     <goal>undeploy</goal>
                  </goals>
                  <configuration>
                     <fileName>${basedir}/target/jsr311-war.war</fileName>
                  </configuration>
               </execution>
            </executions>
         </plugin>
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
               <skip>true</skip>
            </configuration>
            <executions>
               <execution>
                  <id>surefire-it</id>
                  <phase>integration-test</phase>
                  <goals>
                     <goal>test</goal>
                  </goals>
                  <configuration>
                     <skip>false</skip>
                  </configuration>
               </execution>
            </executions>
         </plugin> ...
      </plugins>
   </build>

First things first, is to use the Mojo JBoss plugin. This allows you to deploy/undeploy to JBoss. You must configure it to point to the JBoss home directory. I have it hardcoded, but you should use an environment variable. There are two executions that are run. One deploys a file I have in my projects target directory, the other undeploys it. These must run in the pre-integration-test phase and post-integration-test phase.

The next blob of XML deals with the Surefire test framework. Surefire will try to run tests before you have packaged and deployed your target archive. This is because in Maven’s lifecycle, testing comes before packaging and Surefire is automatically bound to run tests in the “test” phase. We turn this off and instead tell Surefire to run during the “integration-test” phase after our archive has been packaged and deployed to JBoss.

The mojo plugin also allows you to start and stop jboss. I could not get this to work with JBoss 4.2.2. Since I prefer to run JBoss manually when integration testing anyways, I was too lazy to investigate further.

Posted in jboss, maven | 4 Comments »

JSR 311, JAX-RS: Comment and suggestions

Posted by billburke on October 1, 2007

Since I’m so RESTless lately I started thinking about what JBoss could do to help with this effort. We’re involved with JSR-311, which is defining a server-side framework for REST web services, so I decided to contact Heiko Braun, our representative on this specification. I got a copy of the latest draft and dived in. Sometimes the rules of the JCP prevent you from talking about a specification publicly (please correct me if I’m wrong), so I wasn’t sure I could blog about this specification. But, since Brian Leonard has blogged about 311, then I guess I can too.

I don’t want to get into too much detail on 311. Instead please read Brian’s blog and follow the additional links he provides. 311 does seem like it is just standardizing the REST framework Sun has already written. I will though provide example code so that I can reference it later in this blog.

public class Shopping {
   @HttpMethod("GET")
   @UriTemplate("/shopping/orders")
   @ProduceMime("text/xml")
   public String getAllOrders(@QueryParam("expand") boolean expand) {...}

   @HttpMethod("POST")
   @UriTemplate("/shopping/orders")
   @ConsumeMime("text/xml")
   public String buy(Document order) {...}

   @HttpMethod("GET")
   @UriTemplate("/shopping/orders/{id}")
   @ProduceMime("text/xml")
   public String getOrder(@UriParam("id") int orderNum) {...}

   @HttpMethod("DELETE")
   @UriTemplate("/shopping/orders/{id}")
   public void deleteOrder(@UriParam("id") int orderNum) {...}
}

The spec allows you to map http header entries, query parameters, and individual elements within a URI to a method invocation and its parameters and return types. You can also specify what MIME types a method produces and consumes. The spec also provides you with the ability to define factories that can map representations to and from Java objects.

Change suggestions

After reading the specification and browing the Sun REST framework documentation, I have a few suggestions I’d like to make to JSR 311.

Remove magic methods

It seems like @HttpMethod can be placed without a http method identifier on a Java method and the HTTP method type inferred through the Java method name.

@HttpMethod String getOrders()

In this example, HTTP GET would be used because getOrders() begins with the string ‘get’. I never liked the idea of magic method names. They are too fragile and IMO, just bad programming practice. Instead let’s……..

Annotation refactoring of @HttpMethod

Annotation frameworks should be as tiny and concise as possible. Avoid verbosity at all costs. I’d like to see @HttpMethod replace with a more concrete set of http annotations with the additional ability of being able to define a uri template embedded within these applications. So, instead of @javax.ws.rest.HttpMethod (or whatever the package name will be), let’s instead have individual Get, Put, Post, Delete, and Options annotations under the package @javax.ws.rest.httpmethod:

public @interface Get {

   String value() default "";

}

The value() of Get, Post, Delete, etc. would be an optional uri template. So, instead of the verbose:

   @HttpMethod("GET")
   @UriTemplate("/shopping/orders/{id}")
   @ProduceMime("text/xml")
   public String getOrder(@UriParam("id") int orderNum) {...}

We would get:

   @Get("/shopping/orders/{id}")
   @ProduceMime("text/xml")
   public String getOrder(@UriParam("id") int orderNum) {...}

Reduces one line of typing and also, IMO, makes things easier to read.

Allow annotations on an interface instead

RESTful classes should be allowed to declare their REST annotations on the methods of an interface instead of on the class methods. IMO, this is a better way of isolating the published interface of a service. Doing so would also allow the EJB specification to adopt REST and be able to publish remote, local, and restful interfaces to the outside world. Another interesting side affect of this is….

How about a client side framework?

Another interesting side affect of being able to apply REST annotations to an interface is that this interface could be re-used by a client-side framework to generate a proxy that could invoke on REST web services. The client-side programmer could use the same annotations to describe many REST web services that may or may not be using the server-side implementation of 311 or even Java at all! Doesn’t seem like much more effort to define this client-side API.

@Location annotation?

One common pattern I’ve seen in the REST articles and books I have read is that when you have a service method that creates a new object or queries for an existing object, and Location header should be sent back to the client containing the URI the resource is locatable. The 311 spec seems to support this by allowing the user to return a spec-define Response class. What if instead, we provided the ability to map a return value to a Location header?

@Post("/shopping/orders")
@Location("/shopping/orders/{$r}")
public int buy(Document order) {...}

The $r would represent the string representation of the returned value of the buy() method. The client would receive an empty response with a Location header pointing to the new resource created by the buy() method. We could get even funkier in the @Location annotation and allow Unified EL expressions.

@Post("/shopping/orders")
@Location("/shopping/orders/{$r.getId()}")
public Order buy(Document order) {...}

This kind of flexibility could allow one object to be used both RESTfully and locally.

Security?

Another thing I see missing is security hooks. For instance, how about an annotation specifiying whether the resource should be accessed over HTTPS or not? How about an annotation that allows you to plug in an authentication mechanism? IMO, 311 shouldn’t be diving into defining security protocols, but should at least think about providing metadata that allows you to plug in your own implementation. Then again, maybe authentication is best left to being implemented in servlet filters. I don’t know…

XML Descriptor?

There are some bigots out there that despise annotations. An XML descriptor should be created that can define this type of metadata. It should follow the style of other EE components so that we can do things like integrating JAX-RS with EJB.

EJB bridge

The 311 specification does talk about how JAX-RS interacts in a servlet environment. I’d also like to see some work done so that EJBs can become restful as well. This will probably require some work around define lifecycle and creating an annotation like @Restful to ping the container that it needs to perform restful bindings. This would also require work with the EJB 3.1 JSR to expose JAX-RS XML descriptors within EJB 3.1. Red hat would be happy to drive this in the EJB 3.1 expert group.

More to come

I’m seriously thinking about implementing 311 with the changes I’ve suggested here and integrating it with our EJB3 implementation. Hopefully I have the time. Maybe somebody in the community would be interested? I’d be happy to help as long as the individual showed initiative and ability to work on their own. I’ll also talk to Heiko more on what he thinks should be massaged in the specification and blog about them here.

Posted in JAX-RS, REST, Webservices, jboss | 11 Comments »

Compensating Transaction Framework

Posted by billburke on August 14, 2007

Mark Little’s team has put together a nice annotation framework on top of the JBoss TS, Business Activity service. What?!? JBoss has a Business Activity service? Yup, we do. Have had it for a long while, accept nobody but Mark (did he even?) made any noise about it within the JBoss community. What is the Business Activity service? Mark does a better job in an article he wrote a few years ago, (his book is even better), so I won’t get into a lot of detail. To summarize in my own words, the Business Activity service looks very much like XA and traditional transactions, except they are really meant for long running conversations or activity. Traditional transactions are not good in that scenario because they hold onto resources too long. Particpants in BA look a lot like resources in XA. The register themselves with an activity. An activity is very similar to a transaction in that you begin it, and either cancel (rollback) or close (commit) the activity when you are finished. Participants can interact at closing with a 2 phase protocol, much like 2PC in regular XA. The difference is that the rules are much more lax. Participants can choose to leave the activity whenever they like as well as some other neat things. See Mark’s book or article for more details. Oh, and I forgot, this is a WS-* specification.

So back to the annotation framework. Its pretty cool. It allows you to tie in a compensatory action to an executed method. So, if the business activity is cancelled, the coordinator will automatically callback to this compensation. Here’s an example:

@Stateless
@SOAPBinding(style = SOAPBinding.Style.RPC)
@HandlerChain(file = "jaxws-ba-handler-server.xml")
public class HotelBAImpl implements HotelBA
{
	@WebMethod
	@BAService(BAServiceType.MODIFY)
	@BAAgreement(BAAgreementType.PARTICIPANT_COMPLETION)
	@BACompensatedBy(value="cancel",type = BACompensationType.PARAMETERS_MATCH)
	public Integer book(String user, String pass, Integer room)
	{
		// ... business logic
		return reservationNumber;
	}

	@WebMethod
	public void cancel(String user, String pass, Integer room)
	{
		// ... business logic
	}
}

So, in the example, if you invoke the book() method of the Hotel service, it will interact with the coordinator to register a compensation action. This action will be to invoke the cancel() method with the exact parameters that were passed into the book() method if the activity is aborted. Alternatively, you can map the book() method’s return value and parameters to the compensation action using the @BAResult and @BAParam.

{
	@WebMethod
	@BAService(BAServiceType.MODIFY)
	@BAAgreement(BAAgreementType.PARTICIPANT_COMPLETION)
	@BACompensatedBy(value="cancel",type = BACompensationType.CUSTOM)
        @BAResult("reservationNumber")
        public Integer book(@BAParam("user") String user, @BAParam("password") String pass, Integer room)
        {
           // ... business logic
          return reservationNumber;
        }

        @WebMethod
        public void cancel(@BAParam("reservationNumber") Integer reserverationNumber,
                                 @BAParam("user")String user, @BAParam("password") String pass)
        {
           // ... business logic
        }
}

There’s also a CompensationManager object that allows you to programatically put data into the activity that can be referenced by the @BAParam annotation:

{
        // injected field
        @CompensationManagement CompensationManager cm;

	@WebMethod
	@BAService(BAServiceType.MODIFY)
	@BAAgreement(BAAgreementType.PARTICIPANT_COMPLETION)
	@BACompensatedBy(value="cancel",type = BACompensationType.CUSTOM)
        public Integer book(String user, String pass, Integer room)
	{
		// ... business logic
               cm.put("reservationNumber", reservationNumber);

               return reservationNumber;
        }

        @WebMethod
        public void cancel(@BAParam("reservationNumber") Integer reserverationNumber)
        {
           // ... business logic
        }
}

There’s a few more ways to define a compensation. You can have the method compensated by another different EJB method, Web Service, or even a plain POJO. I won’t get into further detail. You’ll have to read the documentation and take a look at the demo app that comes with the distribution.

Client interface

The client interface is very simple and similar to UserTransaction:

public abstract class UserBusinessActivity
{
    public static final int ATOMIC_OUTCOME = 0;
    public static final int MIXED_OUTCOME = 1;

    /**
     * Start a new business activity with atomic outcome.
     * If one is already associated with this thread
     * then the WrongStateException will be thrown. Upon success, this
     * operation associates the newly created transaction with the current
     * thread.
     */
    public abstract void begin()
        throws WrongStateException, SystemException;

    /**
     * Start a new BA with atomic outcome and the specified timeout as
     * its lifetime.
     * If one is already associated with this thread then the
     * WrongStateException will be thrown.
     */
    public abstract void begin(final int timeout)
        throws WrongStateException, SystemException;

    /**
     * The BA is normally terminated by the close method. This signals to
     * all registered participants that the BA has ended and no compensation
     * is required.
     */
    public abstract void close()
        throws TransactionRolledBackException, UnknownTransactionException, SystemException;

    /**
     * If the BA must undo its work then the cancel method is used. Any
     * participants that can compensate are forced to do so.
     */
    public abstract void cancel()
        throws UnknownTransactionException, SystemException;

    /**
     * If participants have registered for the BusinessAgreementWithComplete
     * protocol then they will be expecting the application to inform them
     * when all work intended for them has been sent (and responded to). The
     * complete method is used for this purpose.
     */
    public abstract void complete()
        throws UnknownTransactionException, SystemException;

    public abstract String transactionIdentifier();
}

Here’s an example of using the activity service:

UserBusinessActivity businessActivity = UserBusinessActivityFactory.userBusinessActivity();
businessActivity.begin();
try {
   // do some work
   businessActivity.close();
} catch (Exception ex) {
   businessActivity.cancel();
}

There is of course some initialization to do. I’ll leave that to the documentation, but overall its a very simple API. What I like about this way of doing compensations is that the client is decoupled from the knowledge of whether something should be compensated for, and how it is compensated. The knowledge of this is encapsulated in the services the client interacts with. Services automatically register themselves for the appropriate callbacks. User code does not have to perform commits or rollbacks. Very similar in ease of use to what we’re used to with JCA combined with JTA transactions.

I really think this stuff would be even more useful in plain web applications, not just coordinated remote web services. In my previous blog, Andy Oliver commented how Hibernate application transactions with FlushMode NEVER isn’t always a great solution for long running web apps that interact with your browser. This new framework could provide a very simple mechanism for registering compensatory callbacks so that browser interactions with a database don’t have to be held in memory.

In my next blog on this subject, I want to dive into some ideas I have for improving this framework. Until then, have fun.

Posted in Webservices, jboss, transactions | 4 Comments »

Guaranteed jBPM Failure Handling

Posted by billburke on August 6, 2007

jBPM 3.x allows you to define exception handlers in .jpdl. You can define exceptions you want to catch and either recover from the exception, or allow the execution to fail. These exception handlers are incomplete in functionality though. In my last blog, I talked about how asynchronous continuations give you the ability to have guaranteed transitions. If you dive into the asynchronous code though, you see that exception handlers are executed within the same transaction as the command service triggering the node execution. What does this mean? What are the consequences of this?

Let’s say that your action logic runs into an error condition and it needs to rollback any database changes it has made. Since the thread of execution is marked for rollback, you cannot make any changes to the execution context of the business process, for instance, like transitioning to a failure state. Any failure changes you make to the execution context would just be rolled back by the transaction. Another scenario is the guaranteed transitions I talked about in my last blog. On a rollback situation, what if you want to let your business process decide on whether the node execution should be tried again or not instead of the simple logic of the MDB’s retry count. We talked a bit about these problems on the jBPM forum. Let me summarize some solutions that were discussed.

Execute in a separate transaction

One approach is to solve the problem by invoking non-jbpm code in its own transaction. Your jbpm action could just delegate to an EJB or Spring bean that uses a REQUIRES_NEW semantic. If the invocation succeeds, populate the appropriate bpm variables and move on. If it fails, transition to a failure state or abort and retry the action.

I don’t think this is a good approach because you wouldn’t be able to use frameworks like Seam which make integrating business processes and business logic much easier. Seam uses annotations to biject (push data to and from) jbpm context data into your beans. Freeing you from writing a lot of jbpm specific code.

More importantly, I don’t think this is a solid solution. For instance, what if your non-jbpm code is successful and commits, but the machine crashes before the jbpm context commits? Then your system ends up in an inconsistent state and you are screwed.

Have a Failure State

A better way to solve this is to actually define a transition to a failure state in your process definition

<process-definition>
   <start-state>
     <transition to='business-state-1'/>
   </start-state>
   <state name='business-state-1' asynch='true'>
     ...
     <transition name="failure" to='failure-state-1'/>
   </state>
   <state name='failure-state-1' asynch='true'>
     ...
   </state>

...
</process-definition>

Your failure processing would be encapsulated within actions of the failure state instead of within exception handlers in the original business state. The failure state should be asynchronous because we want to get guaranteed processing of this state. There are two ways to ensure that either a) the business-state-1 state gets processed, or b) the failure state gets processed. I already discussed in a previous blog how to guarantee (a), but for (b) we needs some more thought.

Guarnateed failure handling: Dead Letter Queue Processing

One way to do guaranteed failure handling would be to take advantage of dead letter queues. Most MDB containers allow you to specify how many times you want a message redelivered. After the message redelivery count is reached and there still is failure, the container will reroute the message to a dead letter queue. This queue is a normal queue that you can listen on. Although not a standard JMS feature, I looked into it a little, and at least JBoss, ActiveMQ, and MQSeries have the notion of a DLQ.

So, to do jBPM failure handling, you could just register a new MDB to listen on the dead letter queue. Asynchronous continuations post instances of org.jbpm.job.ExecuteNodeJob. The MDB would check to see if the message contained an org.jbpm.job.ExecuteNodeJob, if it did, check the node for a “failure” transition. If one exists, then signal the process instance to traverse that “failure” transition.

@MessageDriven(activationConfig= {
      ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"),
      ActivationConfigProperty(propertyName="messageSelector", propertyValue="jobId IS NOT NULL"),
      ActivationConfigProperty(propertyName="destination", propertyValue="queue/DLQ")})
public class DLQFailureHandler implements MessageListener
{
    JbpmConfiguration jbpmConfiguration = null;
    @Resource(name="JbpmCfgResource") String jbpmCfgResource = null;

    @PostConstruct
    public void initJbpm() {
      jbpmConfiguration = JbpmConfiguration.getInstance(jbpmCfgResource);
    }

    public void onMessage(Message message) {
        long jobId = 0;
        try {
            jobId = message.getLongProperty("jobId");
        } catch (JMSException ignored) {
            // message selector confirms existence
        }

        JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
        try {
            JobSession jobSession = jbpmContext.getJobSession();
            Job job = jobSession.loadJob(jobId);
            if (!(job instanceof ExecuteNodeJob)) {
                // do some other failure handling
                jbpmContext.close();
                return;
            }
            ExecuteNodeJob executeNodeJob = (ExecuteNodeJob)job;
            if (executeNodeJob.getNode().hasLeavingTransition("failure")) {
                executeNodeJob.getProcessInstance().signal("failure");
                jobSession.deleteJob(job);
            }
            else {
                // push to a different DLQ?
            }
        } finally {
            jbpmContext.close();
        }
    }
}

To make sure we process dead jbpm jobs, we use a message selector configured at line 02. Lines 06-12 lookup and configure the jbpm context. Line 24-25 extracts the Job. If the Job is not an ExecuteNodeJob, you’ll want to add specific handling there or forward the message to another DLQ. Next in line 32 we check to see if the node has a “failure” transition. We transition and delete the job. If there is no “failure” transition, you might want to repost the message to a different DLQ that you create. If there is a failure in this processing, because of message delivery, we are still guaranteed to reprocess the failure logic.

The advantage of this approach is that it is totally seemless to your application: both in code and in your process diagram. You are guaranteed to either be in a successful or failure jbpm state. (At least with using the JBoss JMS inflow adapter but you should probably be ok in other implementations). The disadvantage of this approach is that you have no knowledge of the error condition and can’t report it to the “failure” state. Your failure logic will not know the cause of the failure. This isn’t always an issue because sometimes, specifically in a machine crash, you may not know why there is a failure.


Guaranteed failure handling: Transaction Synchronization

Another idea that came up in the forum discussion was to register a javax.transaction.Synchronization with the Transaction Manager. In afterCompletion(), do the transition to a failure state if there was a rollback. The advantage of such an approach over DLQ is that you can programmatically add the behavior in action code or write an action that performs the TM synchronization. Because of this, you can propagate any exception or failure reason to the failure state. I’m not going to get into details of this approach as I am not sure it will work, specifically:

  • You must set your redelivery count to 0. The synchronization has no way of knowing whether or not the message had been redelivered or whether or not you should transition the token to the failure state with jBPM code out-of-the-box. Since you don’t want the original JMS message redelivered after you have transitioned to the failure state, you need a retry count of zero.
  • JMS Providers may not be able to guarantee that a message isn’t redelivered. Since we require a redelivery count of zero, this is not an option.
  • Your machine could crash before transitioning to the failure state. Since we cannot redeliver the message, the node will never transition to the failure state. You may say, “well, can’t the same thing happen with the DLQ option?”. With the JBoss Inflow adapter, no. The JBoss adapter performs the DLQ check within the same transaction as the delivered method. Since both the sending to the DLQ and acknowledgement of the message are within the same transaction, you are guaranteed of one or the other succeeding.
  • Probably the most important thing is that Synchronization.afterCompletion() is not guaranteed to be executed on TX recover, after a machine crash.

So, the winner is DLQ! Of course I may have missed something. This approach would be better if we could work out the issues.

Side Effect: Redelivery handling

In my previous blog on Guaranteed Execution in jBPM, I discussed at the end how jBPM actions have know current way of knowing whether or not they have been retried by a new transaction. An indirect consequence of the DLQ approach to failure handling is that we now have some ability to recognize and keep track of redeliveries.

<process-definition>
   <start-state>
     <transition to='guarantee'/>
   </start-state>
   <state name='business-state-1' asynch='true'>
     ...
     <transition name="failure" to='failure-state-1'/>
   </state>
   <decision name='failure-state-1' asynch='true'>
     <transition name="recover" to='recovery-state-1'>
        <condition expression="retryCount >=3"/>
     </transition>
     <transition name="retry" to='business-state-1'>
        <condition expression="retryCount < 3"/>
     </transition>

   </state>

...
</process-definition>

Since failures result in a transition to a failure state we can keep increment and store redelivery counts within the token. We can programmatically decide wheter or not we are allowed to retry the message.

Conclusion

So that’s how you can have guaranteed failure handling. I do have a disclaimer though. I’m too lazy to actually try out these ideas. When I do I’ll get back to you in a follow up blog. Please try it out yourself and provide feedback on the jbpm forum topic. We’re still working out the issues here and your thoughts would be most appreciated.

Posted in jboss, jbpm | 1 Comment »

MarcF interview

Posted by billburke on August 3, 2007

How’s Marc Fleury doing?  Matt Asay gave a pretty good interview with Marc.

Posted in jboss | 1 Comment »

Guaranteed Execution in jBPM

Posted by billburke on July 30, 2007

Was thinking a bit about jBPM today. One thought crossed my mind: How can you guarantee that a specific state transition happens in jBPM? We’ll talk about guaranteed state transition in this blog, but first of all, before we even think of jBPM, how could you guarantee that *any* event happens in a general application? There are few things you have to think about here:

  • You want to be guaranteed that the event is scheduled to be processed
  • You only want the event to be scheduled if your business logic succeeds
  • You want to be guaranteed that somebody processes the event

Being as stupid and slow as I am, took me a few minutes to realize that JMS provides guaranteed delivery of messages. This is obvious to many people, but let’s walk through what you would have to do in JBoss to have the guaranteed processing of an event.

First things first is to write the sender code. Let’s do this in an EJB 3.0 stateless session bean. I know this is basic stuff, but you may not be familiar with a) EJB 3.0 or b) the JBoss specifics:

@Stateless
public class BusinessLogicBean implements BusinessLogic {
   @Resource(mappedName="java:/JmsXA") ConnectionFactory factory;
   @Resource(mappedName="queue/mylogic") Destination destination;

   public void doSomething() {
      ... do some logic ...
      Connection con = factroy.createConnection();
      ... do all the JMS sugar ...
      messageProducer.setDeliverMode(DeliveryMode.PERSISTENT);
      messageProducer.send(message);
   }
}

The doSomething() method is a transactional unit of work. We want every piece of business logic to have succeeded when we deliver the message. In other words, we want the message delivered as part of a transaction. To use a transactionally aware sender, we injected the “java:/JmsXA” connection factory into our SLSB. We also set the delivery mode of the producer to be PERSISTENT. So, we both guaranteed that the message would only be sent if the business logic succeeded and that the message has been scheduled for processing. On to the server:

@MessageDriven(activationConfig= {
      ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"),
      ActivationConfigProperty(propertyName="destination", propertyValue="queue/mylogic"),
      ActivationConfigProperty(propertyName="DLQMaxResent", propertyValue="5")
})
public class MyMessageConsuomer implements MessageListener {
   public void onMessage(Message msg) {
      ... do the work ...
   }
}

Typical message driven bean in EJB 3.0. Since this bean is using the container to manage transactions and being invoked inside of a transaction, the receipt of the message will not be sent back to the JMS provider if the business logic is rolled back. So, if there is a system failure, or some other reason for abort, the message will be redelivered, thus guaranteeing its processing. The “DLQMaxResent” property is JBoss specific and tells the JMS adapter how many times the message should be resent before it is sent to a “dead letter queue” and put to death. There’s other configuration items around dead-letter queues. Go read our documentation for additional DLQ settings.

Guaranteed State Transitions in jBPM

Guaranteed state transitions with jbpm is all about using asynchronous continuations and the Enterprise Archive. In jBPM if you mark a node as asynch then jBPM will use its configured messaging system to transition to that state in another thread and transaction. If you have deployed jBPM through the Enterprise Archive, JMS is used to do the transition. Here’s example .jpdl

<process-definition>
   <start-state>
     <transition to='guarantee'/>
   </start-state>
   <state name='guarantee' asynch='true'>
     ...
   </state>
...
</process-definition>

So, starting a process instance of this definition will generate a JMS message that transitions to the ‘guarantee’ state. By default, jBPM is configured to use transactional connection factory, “java:/JmsXA”, describe earlier in this blog. So, when the start-state transitions, it will create a persistent JMS message and deliver it to the queue transactionally. Now, the ‘guarantee’ node will be triggered by an MDB that receives the message sent by the jBPM message layer. This MDB uses container managed transactions. This means that if there is a failure within the execution of the state, the message will be redelivered until the transaction completes successfully. This MDB is configured to use JBoss’s old EJB 2.1 container which does not use JCA message inflow. The default message redelivery count is 10. Chapter 5 in the JBoss AS documentation shows how you can define the max redelivery as well as dead letter queue configurations. You’ll need to open up the Enterprise Archive, jbpm-enterprise.ear, to get to the file, jbpm-enterprise.jar. This file contains the ejb-jar.xml and jboss.xml files you need to modify to change the jbpm configuration of the message driven bean.

The only thing missing with this JMS transitioning in jBPM is that the node receiving the transition does not have knowledge on whether the message was redelivered or not. Future versions might incorporate this knowledge. I have pinged the jBPM team and there is some discussion on the jbpm forum.

That’s about it! Yeah, I know a lot of this stuff is basic, hope I didn’t bore you too much. I just wanted to set down some foundation for other topics I want to discuss that may use these JMS and jBPM features.

Posted in ejb3, jboss, jbpm, transactions | 2 Comments »

It’s free and it doesn’t suck

Posted by billburke on July 30, 2007

Burr Sutter reminisces about Marc Fleury’s first Atlanta JUG presentation in 2002. Its a great story and a must read for anybody interested in JBoss history.

Posted in jboss | No Comments »

Unbreakable Red Hat

Posted by billburke on July 18, 2007

I’m angry again,

Came across Savio Rodrigues’s blog about whether Oracle would buy Red Hat and/or BEA. One particular comment is a very incorrect assumption, specifically Savio wrote:

By announcing Oracle Unbreakable Linux, Oracle has already proven that Red Hat doesn’t have a whole lot of technology that can’t be easily replicated. ….

Maybe Savio believes that Red Hat doesn’t produce any technology? JBoss aside, I used to think that Red Hat was just a packager and was surprised to find out this wasn’t the case. They are one of the biggest presences the Linux and FSF community. I was astounded by the kind of quality engineers Red Hat has in key positions in the OSS community.

Or maybe Savio believes what Larry believes, that since Red Hat is all open source based Oracle can steal whatever IP they want and that’s the end of that. I’m not sure either of them understands that professional open source runs on top of the same fundamentals of any other business. Brand, employees, management, happy customers, and ability to execute and innovate. Let’s face it, open source is a software industry segment. Only Red Hat has proven it can execute effectively in such a space. If you’re just going to “take Red Hat’s IP”, you still have to establish strong OSS community relations, you still have to have great engineers that know the software, productization teams that know how to take raw OSS projects and turn them into a product you can support for 5 years, you need sales people that know how to sell it, marketing that knows how to promote, management that knows how to deal with “freetards” and open source prima donas.

None of this means that Oracle can’t establish itself in Red Hat’s market, it just means that as long as Red Hat continues to execute and innovate they will still be the leaders. Over the years JBoss had to go through various crisis’s in order to grow up as a company, I remember myself panicking thinking we were done, it was over. Marc and Sacha, always the steady hands say, “just continue to execute and everything will be fine”. You know what? It was. When you see us stop being able to execute, then you can say we’re done.

Posted in business, jboss | 2 Comments »