Help

Built with Seam

You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.

Active development of Seam JMS has been halted by Red Hat. Functionality has been absorbed by the new JMS Spec.

Seam JMS

Provides improved JMS APIs and bridges the CDI event bus over JMS.


To get started, add the dependencies below to your pom.xml:
Individual JARs
<dependency>
   <groupId>org.jboss.seam.jms</groupId>
   <artifactId>seam-jms-api</artifactId>
   <version>3.0.0.CR1</version>
</dependency>

<dependency>
   <groupId>org.jboss.seam.jms</groupId>
   <artifactId>seam-jms</artifactId>
   <version>3.0.0.CR1</version>
   <scope>runtime</scope>
</dependency>
* Maven artifacts are located in the JBoss Community Repository: http://repository.jboss.org/nexus/content/groups/public

Module team

Name Module role Commit username (Git) Organization Hometown (Time zone)
John Ament Lead johnament Mt. Laurel, NJ, USA (UTC-5)
Jordan Ganoff Founder, contributor jganoff Pentaho Orlando, FL, USA (UTC-5)
Dan Allen Contributor mojavelinux Red Hat, Inc. Laurel, MD, USA (UTC-5)
Want your name to appear in this list? Join us in #seam-dev on freenode and let us know you want to get involved.

Description

The general goals can be divided into two categories: injection of JMS resources and forwarding of events.

Injection of JMS Resources

  • Connection
  • Session
  • Destinations
  • Message Producer
  • Message Consumer

Event Bridge

  • Egress: Routes CDI events to JMS destinations
  • Ingress: Fires CDI events based on the reception of JMS messages

Simplified APIs

  • MessageManager: Creation of basic messaging objects (Session, Producer, Consumer, Message)
  • RouteBuilder: Startup call back on ingress routes.
  • DurableMessageManager: Support for Durable Subscriptions.
  • TopicBuilder and QueueBuilder: Builder pattern implementation for working with Queues/Topics

Release plan

Version Time frame search engine optimisation Focus
3.0.0.Alpha1 2010-05-14
  • Injection
  • Event Forwarding
3.0.0.Beta1 April 4th, 2011
  • Revised JMS Resource injection
  • Elaboration of Event Forwarding
  • Ingress translation of JMS Messages to CDI Events
  • Updated internal APIs that can be exposed to developers - MessageManager and RouteManager
  • Improved compatibility with JBoss AS 6 and Glassfish V3.1
  • Programmatic Durable Subscriptions
3.0.0.Beta-2 April 2011
  • Improved code coverage and testing
  • Refined Durable Subscription support
  • Clarification on MessageListeners
  • Simplified APIs
  • Annotation renaming based on feedback
3.0.0.CR1 July 2011
  • Further test coverage improvement
  • Bug fixes
  • Builder pattern implementation
  • Code refactoring, moved several components into API suite.
3.0.0.CR2 Late July 2011
  • SE Testing and cleaner support (client running in an SE environment, connected to an EE server)
  • Documentation clean up

Additional Configuration

The default location of ConnectionFactory URL or JNDI name Seam JMS uses; it is hardcoded as ConnectionFactory. That being said, if you're testing with Glassfish V3 you should define a ConnectionFactory by that name as follows. Thanks Dan Allen for this tip:

The prerequisite for using this on GlassFish V3 is to define a ConnectionFactory named ConnectionFactory. You can either do this through the Admin Console or this asadmin command:

Admin Console:

Resources > JMS Resources > Connection Factories New... Pool Name: ConnectionFactory Resource Type: javax.jms.ConnectionFactory OK (Accept all other defaults)

asadmin:

$GLASSFISH_HOME/bin/asadmin create-jms-resource --restype javax.jms.ConnectionFactory ConnectionFactory

That will enable the internal resource injection that Seam JMS uses:

@Resource("ConnectionFactory")
private ConnectionFactory cf;

However, you can now specialize the bean org.jboss.seam.jms.inject.JmsConnectionFactoryProducer, overriding the producer method that returns the ConnectionFactory.

Design whiteboard

This section serves as a whiteboard for design and ideas for this module. Once you've decided to pursue a feature, it should be added to JIRA as a feature request and optionally linked from this page.

Destination Injection

Goal: Injection should be simple, intuitive, and type-safe.

Comments:

Seam JMS at one point supported a Stereotype implementation that wrapped the injection of destinations via JNDI. However, it is much easier to just provide a producer on an injected resource as noted below. Note that the JmsDestination support remains, but it cannot be wrapped in another qualifier.

Planned:

SEAMJMS-2: Implement original design from spec draft from 20090520 (Page 41) where we use the producer field pattern to provide access JMS artifacts. This is much more flexible, as it allows the use of @Alternative etc:

@Resource(name="java:global/env/jms/PaymentQueue")
@Produces @PaymentProcessor Queue paymentQueue;
@Resource(name="java:global/env/jms/Prices")
@Produces @Prices Topic pricesTopic;

Event Bridging

Goal: Provide a mechanism to send/receive events transparently over JMS.

Implemented:

Bridging JMS messages and CDI events can also be done by annotated a method @EventRouting and returning Collection<Route> or Route:

@EventRouting
public Route eventRoutingConfig(RouteManager routeManager)
{
   return routeManager.createRoute(EGRESS, Object.class).addQualifier(SPECIAL).connectTo(Topic.class, myTopic);
}

@EventRouting
public Collection<Route> manyRoutingConfigs(RouteManager routeManager)
{
   return Arrays.asList(
      routeManager.createRoute(EGRESS, MyEvent.class).connectTo(Queue.class, myQueue),
      routeManager.createRoute(EGRESS, LogginEvent.class).connectTo(Topic.class, eventTopic));
}

Please be cautious when using EventRouting, the CDI container has not initialized yet therefore it is not valid to inject anything into these classes. You can also use Observer Method Interfaces to define routes. This is actually the preferred approach.

public interface ObserverInterface {
    @Routing(RouteType.EGRESS)
    public void obsStringToTopic(@Observes String s, @JmsDestination(jndiName = "jms/T2") Topic t);

    @Routing(RouteType.INGRESS)
    public void obsLongToTopic(@Observes Long l, @JmsDestination(jndiName = "jms/T2") Topic t);

    @Routing(RouteType.BOTH)
    public void obsDoubleToTopic(@Observes Double d, @JmsDestination(jndiName = "jms/T2") Topic t);
}

You can use both @Routing(RouteType) or @Inbound/@Outbound here. You can use qualified destinations in the method signature, they are lazily instantiated when the route is first activated by the application.

Miscellaneous Outstanding Project Items

  • Arquillian configuration for Glassfish
  • Arquillian configuration for remote HornetQ and ActiveMQ
  • SE Deployments