Monday, October 26, 2009

Mobicents SIP Load Balancing

Check out our SIP Load Balancing (SIP LB) designs and deployment scenarios.

Our goal is to support as many scenarios as possible in a simple way and maintain flexibility for future enhancements and custom load balancing. We look at the load-balancer as a platform where you can implement your own routing decision logic - distributed or standalone, stateful or stateless, layer 3/4 or layer 7, it is all up to you.

The new load balancer provides quite a few improvements on top of the old one:
  • Performance (>1000 cps, but depending on the algorithm)
  • Flexibility - pluggable algorithms and customizable algorithms
  • Fault Tolerance - multiple smart SIP LBs can work together and nterchangeably in case of failure when sprayed by "dumb" IP load balancers
  • Cooperative Load Balancing - very often, mutliple protocols and sessions are involved in a telco service. Then you need to group calls, HTTP or other protocol sessions to stick together and be failed-over together. Only your application knows the right way to group these sessions, thus sometimes it is crucial to delegate load-balancing decisions to your application. Now, you could implement your own algorithms that take hints or instructions from the applications.
For more details you can look at these slides:



Feedback is welcome!

UPDATE: Revised November 1st, 2009

Wednesday, October 14, 2009

Introducing Mobicents IPBX

Many Mobicents community users are already familiar with IPBX, which is complete (and open-source) Media PBX with rich Web User Interface, but it's been on the background for some time due to higher priority tasks. Now with the increased community feedback, we present the new version of IPBX 1.0 CR, which is stable and covers a number of real use-cases. I cannot not mention the guys from Manaty for their help testing the IPBX and finding/solving a number of problems. But I want to thank all users who gave feedback and reported their experiences.

For those who are new to IPBX - this is a converged application (meaning it serves several protocols HTTP, SIP, Media/RTP) and as such it provides integrated experience acrosss several technologies. Let's see this short video of what the application really does:



What we see here is users authenticating against the application over HTTP and SIP protocols from Web browsers and SIP Phones respectively. They use the same credentials for both HTTP and SIP, the sessions are related to each other by the users and the state of the calls can be displayed in the Web browser of particular users. Moreover, when users call each-other they participate in the same calls, thus many users may want to see the state of the same call or conference bridge - the IPBX provides that as well.

Once you are in a call, you can invite more people in a conference, or you can remove participants. When you need to type something, use the conference chat. All participants in the conference will see the messages. The video also shows a function known as call parking, which allows you to transfer a call from one phone to another.

There are many things not shown in this video. When you are getting started you should take a look at the administrative panels (log in as admin/admin). Three important features there:
  • PSTN Accounts - allows you to call PSTN phones such as mobile and landline phones through a PSTN gateway service provider
  • PBX Settings - allows you to configure the PBX behaviour, the system announcement files, calling prefix, etc
  • User Administration - you can edit the user accounts from here
It is important to note that once configured, the PBX can operate without any Web User Interface. If you like you can register your phones blindly and start making calls by dialing peers or PSTN numbers (with the prefix). The SIP and Web parts of the application, although implemented by the same application logic can operate independently and still catch-up with each other if you want to log in from the Web UI.

On the technical side, this application was implemented on top of Mobicents Sip Servlets 1.0 for JBoss AS 4.2.3, Seam Telco Framework 2.2, JBoss Seam and Richfaces with JBoss Developer Studio and Mobicents Eclipse Plugins.

I really hope this project to gain more developer community interest to help us build the next features on the roadmap. Right now the following features are planned for the near future:
  • Recording calls
  • Better UI
  • Voicemail
  • Multiline calls
There are certainly a lot of other features we'd like to add, and if you have other ideas they are more than welcome.

There are few other videos, but I will just add this one for the Linux users with another set of phones:


Finally, some links:
Enjoy!

Tuesday, October 6, 2009

Amazing OKI Technology


Last week, I visited OKI, a major japanese telecom product vendor, to help creating a better technical relationship for the telecom vertical between OKI and Red Hat JBCP team. Along with our technical meetings I got to see one of their new products in action.

It's no secret that Japan is way ahead in many IT&Telecom fields. New things are developed fast and pushed to the market quickly. As a result, the people I see on the streets are almost always "on the phone" - looking the the screen, pressing some buttons or waving the phone around. I quickly learned that the phones usually come with tons of apps and services that make you stick around such as built-in contact-less e-wallets chips, bar-code readers, TV (the Japanese TV is crazy!) and what not. I don't even mention the browsers and all the internet/IP services here. You can walk through the subway doors with the phone in your hand and the ticketing transactions occur automatically. You can scan some QR code to pick up information about items in the store, on the street or elsewhere.

Obviously, when you create a new service here, you can leverage a lot of unique infrastructure, but the Japanese market is massive and very saturated and staying on top is a real challenge.

The new product from OKI is up for the challenge. It is an advanced platform for a variety of services delivered in a unique integrated and rich user interface. Basically you call a number, it turns out the service you dialed supports streaming the enhanced user interface and your phone picks it up. Your TV, PC or other devices at home can join the service session and show you visually the current menus in the service or the results of your operations. The feedback from the system is both audio and video updated accurately in real time on all devices in the session. With your voice you can navigate through the menus or ask operations to be executed. You could use DTMF to enter a password or a code privately in case you don't want to speak out confidential information to feed the system. One of the coolest features is that if you are not at home, you could use some nearby ATM or other kiosk in Japan as a display. So, you are walking on the street and you just literally tell your phone to move the visualization to the kiosk and it's there. Additionally, kiosk and other devices may have more UI controls such as touchscreen, keyboard or a mouse. Within your service session you can use the extra controls for input. The OKI team allowed me to blog about this omitting some details and features. They put a lot of attention to details in the UI and interop interfaces, and some are really worth keeping secret :)

One of the example services implemented on top of the platform is ordering food for a family. You go through the usual steps - identifying yourself, searching for a particular type of food, selecting a restaurant, going through the menu, examine additional options, ask questions, make your order and then confirm the payment. On every step of the order the platform adds something unique to the UI that couldn't be done otherwise especially when it comes to ordering for a group of people or while on the go.

I think along with the typical customer services this platform can be useful for a number of office or enterprise applications - collaboration tools, e-meeting tools, online business workflow and so forth.

This is just one of the mind-blowing things I've seen in Japan, which is truly a very special place on Earth in every aspect. I will try to cover more "Only in Japan" stories when I catch up with my regular job.

Saturday, September 5, 2009

JBossWorld update

JBossWorld is over. Overall, it was a good experience and a big step ahead in gaining mindshare, especially with Jean's efforts to deliver the Mobicents message internally and externally.

On the BOF side we ended up with a few requests about how to get started. So, this is the Rapid Telco App Development BOF Slide Deck

And the other useful links discussed:
And for the people with no experience in Telco, this is the fast-track on the theory:
I hope it helps and if there is anything else we'd be glad to give more info.

Friday, July 10, 2009

Join us at JBossWorld 2009 in Chicago








Once again, someone made a terrible mistake and I will be leading the BOF session on Rapid VoIP development - SIP Servlets 1.1, Seam Telco Framework, JRuby on Rails, Eclipse VoIP tooling. They just never learn :)

The talk is on September, 2nd at 5:45 PM. It seems a bit late, but knowing the JBoss parties that occur during summits, that's actually early and a very good slot. The other good news is that I will have Jean Deruelle and some guests with me. Jean also has another talk on Telco 2.0 on Friday in the What's next track. It is worth mentioning that this year JBossWorld and Red Hat Summit take place at the same time on the same location and visitors have have access to both with their passes.

In my BOF session, we will begin with a short presentation and demos how to start developing VoIP and Converged applications with Mobicents from scratch with our telco application frameworks/platforms focusing on Seam Telco Framework and the IDEs. We will move on to some real-world examples. We will have a lot of time for questions and discussion on other Mobicents topics, VoIP technology and the current trends in the market. I hope it will be a great experience for everybody.

As always, if you are around Chicago, we can do another Mobicents user meeting somewhere.

Update: Early bird registration extended until 17th.

Friday, June 12, 2009

All Mobicents IDE Tools Online

Some news from the past few days - all Mobicents Eclipse Plug-ins are now updated and available from the new repository. Previously, only the Sip Servlets tools were maintained, but now the EclipSLEE, the JAIN SLEE Service Creation Tool is there as well.

What's new in this latest update?
  • EclipSLEE 1.2.5 updated to work with Eclipse 3.4 Ganymede and with JAIN SLEE 1.1 - Many thanks to wernerdit for the patches. EclipSLEE still needs to be updated to support the new deployment mechanism. For now you can only deploy to localhost.
  • Sip Servlets Core Plugin 1.0.3 updated to fix a deployment issue and some glitches with Windows when loading the management console. It works with both JBoss Application Server 4.2.x and 5.1.x distros.
  • Sip Phone Plugin 1.0.1 updated to fix some Windows issues. There is still a flicker in the graphs in Windows, but it's reduced now. Will work on that later.
Well, with this set of tools you can create and test both Sip Servlets and JAIN SLEE applications. Note that all 3 plugins do not depend on each other and you can install them separately, but they look best together :)



This is our update site: http://mobicents.googlecode.com/svn/downloads/sip-servlets-eclipse-update-site/
(i admit, putting the update site in "sip-servlets-..." was a shortsighted idea, because we have JAIN SLEE tools there as well, but it's just a path name, it doesn't matter)

You can see the documentation about the Sip Servlets plugins here.
While the EclipSLEE documentation will remain at the old location for now.

I hope you enjoy it.

Sunday, May 31, 2009

Time for Seam Telco Framework 2.1

The Mobicents application framework for SIP and Media on top of Seam is now officially named Seam Telco Framework (STF) and it just reached version 2.1!

There have been a number of changes and fixes since the last public version and the current 2.1 version must be stable enough to be consumed by all users.

The goal is still the same - to unify the programming model for Telco and JEE application. A somewhat new perspective for the framework is to minimize the new APIs and reuse as many standard or established APIs as possible (JSR-289, MSC or JSR-309) in order to keep a flat learning curve. You can think of it as something using the Seam infrastructure to expose these APIs to your application. For example the SIP messages and the media notification are delivered through Seam events in the context of a JSR-289 Sip Servlets Session. The Sip Servlets Session itself is backing the Seam SESSION scope context similarly to how the HTTP sessions work in Seam. Additionally, most of the framework objects are available and exposed through the Seam IoC and scoped at the right level. The STF simply plugs into Seam and reuses whatever makes sense in the SIP world. By the same logic, Seam uses that same infrastructure to expose the other APIs from the diagram (JEE, JBoss Frameworks and others) in certain roles - JSF for presentation, jBPM for flow and navigation, Drools for security and so forth.

We also want to highlight the point that most major IDEs already have support for Seam core syntax. You can use the same IDE tools to code SIP components without any extra plugins. Again, everything from STF is exposed through the Seam core infrastructure as events, components or scopes.

You should note the following changes:
  • The new documentation is here.
  • This source code of the latest stable release 2.1 is here (where the examples are stable).
  • The source code trunk has moved to here (including the dev examples).
  • The media framework is bundled.
  • The Connection and Link IVR helper classes are unified under a single IVRHelper class now. You can check the examples and the documentation for more information.
To have quick glance let's dive into the familiar conference IVR example:
@Scope(ScopeType.STATELESS)
public class MediaFrameworkDemo {
@Logger Log log;
@In MediaController mediaController;
@In SipSession sipSession;
@In MediaSessionStore mediaSessionStore;
@In IVRHelper ivrHelper;
@In MediaEventDispatcher mediaEventDispatcher;

@In(scope=ScopeType.APPLICATION, required=false)
@Out(scope=ScopeType.APPLICATION, required=false)

String conferenceEndpointName;

private final String announcement =
"http://mobicents.googlecode.com/svn/branches/servers/media/1.x.y/examples/mms-demo/web/src/main/webapp/audio/welcome.wav";

@Observer("INVITE")
public void doInvite(SipServletRequest request) throws Exception {
// Extract SDP from the SIp message
String sdp = new String((byte[]) request.getContent());

// Tell the other side to ring (status 180)
request.createResponse(SipServletResponse.SC_RINGING).send();

// Store the INVITE request in the sip session
sipSession.setAttribute("inviteRequest", request);

// If this is the first INVITE in the app, then we must start a new conference
if (conferenceEndpointName == null)
conferenceEndpointName = "media/trunk/Conference/$";

// Create a connection between the UA and the conference endpoint
mediaController.createConnection(conferenceEndpointName).modify("$",
sdp); // also updates the SDP in Media Server to match capabilities of UA
}

@Observer("connectionOpen")
public void doConnectionOpen(MsConnectionEvent event) throws IOException {
// Save this connection where the framework can read it
// mediaSessionStore.setMsConnection(event.getConnection());// This is done automatically in STF 2.0

// The conference endpoint is now assiged after we are connected, so save it too
conferenceEndpointName = event.getConnection().getEndpoint()
.getLocalName();

// Recall the INVITE request that we saved in doInvite
SipServletRequest request = (SipServletRequest) sipSession
.getAttribute("inviteRequest");

// Make OK (status 200) to tell the other side that the call is established
SipServletResponse response = request.createResponse(SipServletResponse.SC_OK);

// Put the SDP inside the OK message to tell what codecs and so on we agree with
response.setContent(event.getConnection().getLocalDescriptor(),
"application/sdp");

// Now actually send the message
response.send();

// And start listening for DTMF signals
ivrHelper.detectDtmf();
}

@Observer("DTMF")
public void dtmf(String button) {
// If the other side presses the button "0" stop the playback
if("0".equals(button)) {
ivrHelper.endAll();
} else {
// otherwise play announcement
ivrHelper.playAnnouncementWithDtmf(announcement);
}
// Also log the DTMF buttons pressed so far in this session
log.info("Current DTMF Stack for the SIP Session: "
+ mediaEventDispatcher.getDtmfArchive(sipSession));
}

@Observer( { "BYE" })
public void doBye(SipServletRequest request) throws Exception {
request.createResponse(200).send();

// And clean up the connections (not really required, because there is automatic cleanup in STF 2.1)
MsConnection connection = mediaSessionStore.getMsConnection();
connection.release();
}

@Observer("REGISTER")
public void doRegister(SipServletRequest request) throws Exception {
request.createResponse(200).send();
}

}
This is how you can do conferencing and IVR just by subscribing a few methods to a few events without implementing any callback interfaces or keeping track of how the media and SIP events are related. You will notice some differences and comments. There is significant effort by STF to automatically assign and cleanup media objects when it's clear what is expected or when they should not be used any more (for example they are cleaned up when the SIP session is destroyed). Overall we just try to keep the glue code out of your application or at worst keep the glue in the metadata.

What happened with version 2.0?

Version 2.0 is was released without announcment only to solve particular problems without being fully tested. The 2.1 version has some fixes on top of 2.0 and the API changes are explained in the documentation. If you are 2.0 user all APIs are back-compatible and you should be able to switch to 2.1 without any effort.

As usual, any suggestions and feedback are welcome!

Monday, March 23, 2009

Google Summer of Code 2009 with Mobicents

This year, the Mobicents project is part of the JBoss/Red Hat/Fedora GSoC student mentoring organisation. We have collected some project ideas here, but if you have others ideas, they are welcome and you can work on them as well.

I signed up as a mentor and I am particularly interested in seeing some contributors on the PBX project or the tooling. The PBX project combines all the cutting edge Web and VoIP technologies and there are many cool tasks on the todo-list. Moreover, the project is allows you to push your own design ideas and contribute to our Seam Telco Framework.

Check the program homepage, where you can read more details, register and apply.

Any questions or comments should go to our google group.

Tuesday, February 3, 2009

Rich Telco Applications with Seam

UPDATE: The post was edited for clarity.

The Mobicents Seam-based Sip Servlets framework was extended with Media functions and now goes beyond SIP to unify the component models for Telco and Web applications. With this move, we are addressing the need to build quickly Media-intensive applications like PBX, conferencing, Interactive Voice Response (IVR), transaction confirmation and others.

With the help of the Seam development tools these applications can be written and tested in no time, so even if you don't want to use the Seam model in your production applications, you will find it useful for smaller "disposable" applications, or for rapid prototyping and proof-of-concept applications.

Need a conferencing application?

@Name("conference")
@Scope(ScopeType.STATELESS)
public class Conference {
@Logger Log log;
@In MediaController mediaController;
@In SipSession sipSession;

@In(scope=ScopeType.APPLICATION, required=false)
@Out(scope=ScopeType.APPLICATION, required=false)
String conferenceEndpointName;

@Observer("INVITE")
public void doInvite(SipServletRequest request) throws Exception {
String sdp = new String((byte[]) request.getContent());
request.createResponse(180).send();
sipSession.setAttribute("inviteRequest", request);
if (conferenceEndpointName == null)
conferenceEndpointName = "media/trunk/Conference/$";
mediaController.createConnection(conferenceEndpointName).modify("$",
sdp);
}

@Observer("connectionOpen")
public void doConnectionOpen(MsConnectionEvent event) throws IOException {
conferenceEndpointName = event.getConnection().getEndpoint()
.getLocalName();
SipServletRequest request = (SipServletRequest) sipSession
.getAttribute("inviteRequest");
SipServletResponse response = request.createResponse(200);
response.setContent(event.getConnection().getLocalDescriptor(),
"application/sdp");
response.send();
}

@Observer( { "BYE", "REGISTER" })
public void sayOK(SipServletRequest request) throws Exception {
request.createResponse(200).send();
}

}

That's all. No cheating.

What is happening here is that when an INVITE comes (i.e. when you dial the server), we connect the call to a conference endpoint in Mobicents Media Server. If this is the first call, the conference endpoint is not assigned yet (null) and we allocate a new endpoint (with .../Conference/$) for the application. Once the connection is established, the connectionOpen event occurs, then we store the conference endpoint name at the application scope and when the subsequent calls in this application see it they will connect to the same endpoint. We can easily extend this application to work with multiple conferences or add other media functionality. All SIP and Media events occur in a SIP Session, which is basically one call from one user (or one phone). If you want to share data in the SIP session scope simply inject the SipSession as shown in the application or create a SESSION-scoped Seam component. This conference example is available here. If you want to understand Mobicents Media Server and the MSC API you should read the Mobicents Media Server Guide.

In addition to the basic media support we are aiming to simplify the most common use-cases for media applications. While developing media applications I noticed that one SIP call is always constructed like this:

or the more simple chain:

In both chains the call is terminated at some media endpoint - IVR or Conference or an Announcement endpoint (which is not shown in the diagrams). After the call is established, the user agent is connected to exactly one media endpoint at any time, either directly or through a Packet Relay endpoint. This means that we can safely store all these links and endpoints related to the call right into the SIP session and never worry again about how to pass them to another method or component. If you need to switch to another chain just keep the session data updated. That's why we are looking into reserving a special place in the SIP session for the media objects.

To understand it better let's look at another example:
@Name("mediaFrameworkDemo")
@Scope(ScopeType.STATELESS)
public class MediaFrameworkDemo {
@Logger Log log;
@In MediaController mediaController;
@In SipSession sipSession;
@In MediaSessionStore mediaSessionStore;
@In ConnectionIVRHelper connectionIVRHelper;
@In MediaEventDispatcher mediaEventDispatcher;

@In(scope=ScopeType.APPLICATION, required=false)
@Out(scope=ScopeType.APPLICATION, required=false)

String conferenceEndpointName;

private final String announcement =
"http://mobicents.googlecode.com/svn/branches/servers/media/1.x.y/examples/" +
"mms-demo/web/src/main/webapp/audio/welcome.wav";

@Observer("INVITE")
public void doInvite(SipServletRequest request) throws Exception {
// Extract SDP from the SIp message
String sdp = new String((byte[]) request.getContent());

// Tell the other side to ring (status 180)
request.createResponse(SipServletResponse.SC_RINGING).send();

// Store the INVITE request in the sip session
sipSession.setAttribute("inviteRequest", request);

// If this is the first INVITE in the app, then we must start a new conference
if (conferenceEndpointName == null)
conferenceEndpointName = "media/trunk/Conference/$";

// Create a connection between the UA and the conference endpoint
mediaController.createConnection(conferenceEndpointName).modify("$",
sdp); // also updates the SDP in Media Server to match capabilities of UA
}

@Observer("connectionOpen")
public void doConnectionOpen(MsConnectionEvent event) throws IOException {
// Save this connection where the framework can read it
mediaSessionStore.setMsConnection(event.getConnection());

// The conference endpoint is now assiged after we are connected, so save it too
conferenceEndpointName = event.getConnection().getEndpoint()
.getLocalName();

// Recall the INVITE request that we saved in doInvite
SipServletRequest request = (SipServletRequest) sipSession
.getAttribute("inviteRequest");

// Make OK (status 200) to tell the other side that the call is established
SipServletResponse response = request.createResponse(SipServletResponse.SC_OK);

// Put the SDP inside the OK message to tell what codecs and so on we agree with
response.setContent(event.getConnection().getLocalDescriptor(),
"application/sdp");

// Now actually send the message
response.send();

// And start listening for DTMF signals
connectionIVRHelper.detectDtmf();
}

@Observer("DTMF")
public void dtmf(String button) {
// If the other side presses the button "0" stop the playback
if("0".equals(button)) {
connectionIVRHelper.endAll();
} else {
// otherwise play announcement
connectionIVRHelper.playAnnouncementWithDtmf(announcement);
}
// Also log the DTMF buttons pressed so far in this session
log.info("Current DTMF Stack for the SIP Session: "
+ mediaEventDispatcher.getDtmfArchive(sipSession));
}

// Just say OK to these messages.
@Observer( { "BYE", "REGISTER" })
public void sayOK(SipServletRequest request) throws Exception {
request.createResponse(200).send();

// And clean up the connections
MsConnection connection = mediaSessionStore.getMsConnection();
connection.release();
}

}

This is almost the same conference application with some IVR capabilities and some comments between the lines. The MediaSessionStore stores the call-related media objects (the MsConnection in this case) and ConnectionIVRHelper will read it from there when it is doing DTMF detection or playing announcement.

Once you are connected to the conference the application works like this - when you press a button 1-9 it will play a personal announcement (only the user who pressed the button can hear it). If the users presses "0" the announcement will be stopped. Note that MediaSessionStore, MediaEventDispatcher and ConnectionIVRHelper are not part of the framework right now, but you can copy and paste them into your own application from the media framework demo application in SVN (the discussed example). Eventually the classes from the org.mobicents.servlet.sip.seam.session.framework package will be moved into the main framework jar.

Development


If you've read the previous post about the Seam framework, you would already know that these applications can use almost all Seam features including hot-deployment and JBoss Tools-assisted development. Note that you don't need JBoss Tools, you can use your own IDE or no IDE with Ant or Maven or whatever you want.

Here is what you need to get started with JBoss Tools:
  • Mobicents Sip Servlets 0.7.2 with JBoss AS 4.2.3 or Mobicents Sip Servlets 0.8 with JBoss AS 4.2.3 (please do not use it with JBoss AS 5.0 for now, since the Media support there is still in technology preview stage)
  • Install the latest nightly build of JBoss Tools in Eclipse 3.4 (this is the update site) - you need JBoss Seam, JBoss AS Tools and Richfaces plug-ins as minimum. You must use the nightly builds for Seam 2.1 support. Soon, a new JBoss Developer Studio will be released with official Seam 2.1 support.
  • Get Seam 2.1.1.GA and configure it as Seam runtime in JBoss Tools when asked.
Once you create a Seam 2.1 project you can extend it with the Telco framework by following these steps:
<?xml version="1.0" encoding="UTF-8"?>

<sip-app>

<app-name>PUT_SOME_APPLICATION_NAME_HERE</app-name>
<display-name>SeamEntryPointApplication</display-name>
<description>SeamEntryPointApplication</description>

<main-servlet>
SeamEntryPointServlet
</main-servlet>

<servlet>
<servlet-name>SeamEntryPointServlet</servlet-name>
<display-name>SeamEntryPointServlet</display-name>
<description>Seam Entry Point Servlet</description>
<servlet-class>
org.mobicents.servlet.sip.seam.entrypoint.SeamEntryPointServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<listener>
<listener-class>
org.mobicents.servlet.sip.seam.entrypoint.SeamEntryPointServlet
</listener-class>
</listener>

</sip-app>
  • Now you are done. Just start adding Seam components.
Another way to get started is to checkout one of the examples mentioned above and play with them without IDE support (but it requires Maven).


Some guidelines
  • Do not subscribe methods to SIP and media events in Seam components with SESSION or CONVERSATION scopes! The reason is that each of these SESSION or CONVERSATION scoped components is likely to have multiple instances (depending on the number of the sessions) and they all will be called, which is probably not what you want.
  • Always subscribe public methods to SIP and media events. Any other access modifier will cause you method not to be called.
  • When dealing with JPA, always use your own EntityManager. Either EVENT or METHOD scoped or manage it manually through the EntityManagerFactory. The default CONVERSATION-scoped entityManager might produce "EntityManager closed" errors.
  • When initiating a SIP request from a Web session, do it in another thread! Seam uses thread-local storage and the Web contexts will collide with the SIP contexts. We are working on solving this issue and will probably be addressed in the future.
  • Keep in mind that outjection occurs at the end of a method call. If you attempt to use an outjected variable from a nested method call, it will fail.
Any feedback or contributions are welcome!