Seam and SOA
I am in Atlanta for our internal JBoss ESB / SOA training this week. Burr Sutter and his team are doing a great job conveying our SOA vision -- to mesh and reuse services you already built in your "single silo" applications (e.g., a web store and a warehouse management app can share an "order" object when the user confirms an order. Each application then process and save the order in their own ways.).
I have been thinking how Seam fits into this picture. With the support for web services in Seam 2.0, it is actually quite easy to fit a Seam application into a SOA environment. In this post, I'd like to discuss some work I did with the seambay example (a spoof auction site) to make it share its listings with other services, and receive listings from other services.
@Out
To make the seambay application share its auction listings with other services in the SOA environment, we need to serialize the Auction object and push it to the ESB, while it is being saved into the database by the Seam application. The least intrusive way to do this is to use an EJB3 interceptor to "steal" the Auction object when the confirm() method is called. This way, we do not need to make any change to the Seam application code.
-
public class AuctionInterceptor {
-
-
@AroundInvoke
-
-
-
if (target instanceof AuctionAction) {
-
if (ctx.getMethod().getName().equals("confirm")) {
-
Auction auction = ((AuctionAction) target).getAuction ();
-
// Send the following XML string to JMS
-
formatMessage(auction);
-
}
-
}
-
-
try {
-
return ctx.proceed();
-
} finally {
-
}
-
}
-
... ...
-
}
When the user enters a new auction listing on the site, the server console prints the following message.

@In
To make the Seam application as a SOA service end-point requires external applications to invoke its business logic through web services. The challenge here is that most business logic in Seam are managed in "conversations", which holds finer grained application state than Http sessions. How do you keep the conversation state across multiple SOAP calls? Well, here is where the Seam Web Service comes into play.
To expose business logic methods in Seam components as Web Service methods, you need to write a facade SLSB to wrap around the methods you want to expose. You can use the Seam.getComponent() method to get any Seam component by its name and then proceed to invoke any method on the component.
-
@Stateless
-
@WebService(name = "AuctionService", serviceName = "AuctionService")
-
public class AuctionService implements AuctionServiceRemote
-
{
-
@WebMethod
-
{
-
}
-
-
@WebMethod
-
{
-
AuctionActionInt action = getAuctionAction();
-
action.createAuction();
-
action.setDetails(title, description, categoryId);
-
}
-
-
@WebMethod
-
public Auction getNewAuctionDetails()
-
{
-
return getAuctionAction().getAuction();
-
}
-
-
@WebMethod
-
public void setAuctionPrice(double price)
-
{
-
getAuctionAction().getAuction().setPrice(price);
-
}
-
-
@WebMethod
-
public void confirmAuction()
-
{
-
getAuctionAction().confirm();
-
}
-
-
private AuctionActionInt getAuctionAction()
-
{
-
// Get seam component named "auctionAction" from context
-
}
-
... ...
-
}
Notice that the createAuction(), setAuctionDuration(), setAuctionPrice() and confirmAuction() methods all need to happen in the same conversation so that they can access the same "auctionAction" component. But we do not explicitly pass the conversation id to the web service calls. Instead, when the createAuction() method returns, it inserts a conversation id in the SOAP header, and expect the client to use the same conversation id in the header until the caller reaches confirmAuction(), which ends the conversation. The SOAP request inside a conversation looks like the following:
-
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
-
xmlns:seam="http://seambay.example.seam.jboss.org/">
-
<soapenv:Header>
-
<seam:conversationId>2</seam:conversationId>
-
</soapenv:Header>
-
<soapenv:Body>
-
<seam:setAuctionPrice>
-
<arg0>20</arg0>
-
</seam:setAuctionPrice>
-
</soapenv:Body>
-
</soapenv:Envelope>
As a proof of concept to demonstrate that Seam web service is well supported by existing SOAP tools, I build a SoapUI script to demonstrate how to add an auction to the Seam app via web services. Notice the "transfer" elements in the script. They are used to maintain the conversation id header across SOAP requests in a conversation.

Finally, I'd like to make the SOA version of the seambay example available for download. You can find the ready built EAR file in the dist directory, as well as the SoapUI script in the root directory.
August 1st, 2007 at 1:26 am
Any plans on doing the training in Europe?
August 1st, 2007 at 1:52 am
Yes, actually we are trying to identify early adopters for JBoss ESB / SOA — we will be able to provide *free* training and consulting services to those clients. If you want to be part of the program, please let me know and I will ask our SOA guys to contact you.
cheers
Michael
August 1st, 2007 at 12:26 pm
Hi, have your book and I really like seam and I want to use seam for a production app. I noticed that the support page has not been updated this year and there are a number of outstanding issues in jira going back as much as six months. Can you give me an update on the status of the project? Thanks Rob
August 1st, 2007 at 2:52 pm
Rob,
Actually, Red Hat does provide official support for Seam 1.2.1 through the JBoss Enterprise Application Platform subscription.
As for Seam itself, yes, a lot of work has been done in the past weeks. We are addressing JIRA issues listed under the Seam 2.0.0 CR1 module right now. If there are “old” issues you’d like to escalate, you feel free to raise them on the forum and we will go over them. Thanks.
cheers
Michael
August 1st, 2007 at 2:57 pm
Can you possibly use Seam 2.0 (in CVS)? I believe this issue is fixed in Seam 2.0. It is hard for us to go back and release updates for the Seam 1.2.1 branch (we will probably have to if a support customer demands it …)
There are a few more configuration changes you need to make in order to run Seam 2.0. Please see the migration readme file in the Seam 2.0 root directory for more. Thanks.
August 2nd, 2007 at 4:46 pm
Thanks for your reply, I will get 2.0, I hope to see the wiki more up to date, I went through this kind of thing with jboss portal and it just seemed dead even though a lot of work was being put into it. Rob
August 23rd, 2007 at 7:12 am
I’m quite interested in Europe training topic. What is the most efficient way to register?
September 6th, 2007 at 10:22 am
I’m interested in the ESB “early adopter” opportunity. Let me know how to get in touch.
October 3rd, 2007 at 7:17 am
I would be interested in the JBoss “early adopter” opportunity. Is Mark the right person to contact?What email can one reach you at?
October 17th, 2007 at 5:08 am
Hi Michael,
I am actually planning to use Seam 2.0 and its SOA features in a future-product and I’m very interested in training and the JBoss “early adopter” opportunity.
Which is person I can contact about this?
David
November 30th, 2007 at 4:40 pm
I tried to run the example from the SOAP UI tool and I get the error:
Fri Nov 30 17:33:23 EST 2007:WARN:Failed to prettyPrint xml [JBossWeb/2.0.1.GA - Error report HTTP Status 404 - /AuctionServiceService/AuctionServicetype Status reportmessage /AuctionServiceService/AuctionServicedescription The requested resource (/AuctionServiceService/AuctionService) is not available.JBossWeb/2.0.1.GA]: org.apache.xmlbeans.XmlException: error: does not close tag .
Fri Nov 30 17:33:23 EST 2007:WARN:Failed to prettyPrint xml [JBossWeb/2.0.1.GA - Error report HTTP Status 404 - /AuctionServiceService/AuctionServicetype Status reportmessage /AuctionServiceService/AuctionServicedescription The requested resource (/AuctionServiceService/AuctionService) is not available.JBossWeb/2.0.1.GA]: org.apache.xmlbeans.XmlException: error: does not close tag .
Any ideas? I did an ant deploy and it seemed to work — no errors.
I am using JBoss 4.2.2 and the latest Seam (2.0.0GA)
Jim
March 5th, 2008 at 3:36 am
@Jim: Replace the endpoint with ‘/jboss-seam-bay-jboss-seam-bay/AuctionService’
and it will work.
JBoss 4.2.2 shows the registered service endpoints on http://localhost:8080/jbossws/services
February 27th, 2009 at 2:07 am
Hi Michael,
I am currently using Seam 2.1.1 GA, JBoss AS 4.2.2, Eclipse Europa, to develop a web application. I have 2 separate project which want to integrate using Seam WS. Server side project consists 3 entity classes, for instance, an User entity consists of username and DOB attributes.
I have written the interface and implementation classes at server end, the return type is User instance. On the client end, I want to retrieve the username and DOB info, I am wondering how to achieve that.
I did write a same interface class on the client end, but I did not have User entity class on client project, and stucked on writing the interface method. I am thinking should I create the same User entity class on the client end, please advice.
I did look at the seambay example, but it has only server side implementation.
My objective is to know how I can retrieve the User info from client and without implement the User entity class in client end. Correct me if I am wrong about the concept of WS.