"A JAIN SLEE beginner's tutorial? That's a question I see frequently in Mobicents forums, and so I decided to write one ... You can call it Developing a Hello World JAIN SLEE service in 30 minutes or less".
I wrote this in a blog post 3 years ago, and today is still the post with most visitors, and it's not rare that someone shows up in the mobicents-public forums asking questions about it. Well... time to update it, but this time I will use EclipSLEE instead of Maven archetypes.
Of course, before we need a working environment - Mobicents JAIN SLEE binary, Eclipse (with EclipSLEE) and Maven - but since we have an article about that, I'm assuming such environment is already set. Please check the article, and confirm you have such environment set.
- Part 1 - Creating the Hello SLEE World project
- Part 2 - JAIN SLEE Service Introduction
- Part 3 - Creating the Hello SLEE World SBB
- Part 4 - Creating the Hello SLEE World Service
- Part 5 - Deploying and running the Hello SLEE World Service
- Part 6 - The Service build and deployment by Maven
- Part 7 - What do and read next
Part 1 - Creating the Hello SLEE World project
Ready to rumble? Lets start Eclipse...
Ensure you have the Java perspective activated, then right click in the Package Explorer tab and select New > Project ...
Now look for JAIN SLEE, expand it, and select JAIN SLEE Project...
Click Next and the JAIN SLEE 1.1 Project Wizard starts, choose hello-slee-world as the project name, as depicted below.
Click Next and the wizard asks what modules we want in our project, the defaults are good for us, click Finish to create the project.
At this point, if you never build any Mobicents JAIN SLEE project, you may have build path errors in Eclipse, due to the lacking of referenced libraries, you can fix this opening a shell in ide/workspace/hello-slee-world, execute mvn verify, and then refreshing the project in Eclipse.
Part 2 - JAIN SLEE Service Introduction
A SLEE is an application server, a container for software components, and traditional telco SLEEs were powerful, but proprietary, i.e., a big application refactoring is needed to move an application to another SLEE. JAIN SLEE was created to solve this problem, it is the specification of a SLEE for Java applications, allowing applications to easily run in different JAIN SLEE implementations.
The idea of a Java SLEE is to provide an rich environment to execute Java applications, exposing facilities with common functionality used by applications, and managing the runtime resources, such as Java threads. In such environment the application logic becomes much simpler, for instance in a standalone Java application, the application would need to setup and manage the execution of parallel instances of logic, efficiently and correctly share resources such as threads and network protocol listeners, the actual application logic would be just a small part of the Java code. Now imagine an environment where the application just needs to define what are the events that create a new application logic instance, for each event the actual application logic, have simple means to store and retrieve state for that particular instance, and have a rich set of commonly needed features (provided by facilities) such as timers and logging already available, that is the JAIN SLEE application model.
JAIN SLEE is designed and optimized for event driven services (applications), also known as asynchronous applications. A JAIN SLEE event represents an occurrence that requires application processing. Each event has a specified event type (name,vendor and version) ID, and all applications define the event types they want to handle, on the application XML descriptors. For each event type of interest an event handler method must be provided in the application.
Events occur in a resource, inside or outside of the container. We call "event firing" to the action of posting of an event into the container, and when this happens the container will route the event to all applications interested on it, that is, all application instances (entities) attached to the context of that event, in JAIN SLEE this context is named activity. This attachment can be explicit (let's leave that for another article) or implicit, when the application defines the event type of the event being routed as an initial event. An event being initial means that it is a starting point for the service logic, then, if an application defines an event type as "initial", all events of that type will be handled by the application.
So JAIN SLEE applications, also known as Services, are pure logic, which is executed by the container when events are fired in the container, which means they don't have any active resources. In that sense, a JAIN SLEE service is no different than a web page script executed by the browser. When SLEE needs to deliver an event to a Service, it loads it's logic, sets the instance context, such as the state associated to it (called CMP fields), and passes the event to the service event handler method.
Going deeper, a JAIN SLEE Service is a tree of Service Building Blocks (SBB), containing at least one - the root SBB - which then can declare others as child SBBs, which then can have their own children, and so on. Each SBB is mainly a Java abstract class, and includes the following logic:
- implementation of the event handler methods
- implementation of an entity/instance life-cycle
- implementation of methods to manage persistence of instance data
Since SBBs may also refer and invoke other SBBs, the developer may also define an interface for such invocations, the SBB Local Object interface, naturally the methods contained in such interface are implemented in the SBB abstract class too, getting the picture?
Each SBB must additionally have an XML descriptor, to define the SBB metadata, such as what is the SBB ID, what is the abstract class, the local interface, which events it handle (and what methods handle each), etc. JAIN SLEE still has no use for annotations, but that may come soon.
Now a well designed JAIN SLEE application has a root SBB which declares a single initial event, since each event of that type creates a new logical and independent instance of the application. And when an SBB declares an initial event it must also define the variables that SLEE will use to compute the instance ID, which is called service convergence name, for instance the activity id where the event occurred, the event type, a custom string, etc.
Finally, since SBBs may be used by different Services - JAIN SLEE really promotes high component reusage - the Service itself is just an XML descriptor, which defines its ID and what is the root SBB.
Ok, enough about JAIN SLEE, hopefully the reader got what it is about in a Service point of view, so what we want for our service, is that when it is activated a message "Hello SLEE World" will be printed on the console. To accomplish this our service needs to know when it is activated, but the SLEE container fires a special event, named ServiceStartedEvent, each time a service is activated, so what we need is an SBB that declares interest for such event type, and of course, since that is the starting point of our service logic, that event type must be declared as initial event.
Part 3 - Creating the Hello SLEE World SBB
The project we created includes an SBB module, so we just need to add a new SBB to it, please right click the module, and choose New > Other, as shown below:
Expand JAIN SLEE, select SBB and click the Next button...
The wizard to create a new SBB starts, define the package name and the SBB class name, as depicted below:
Click Next and the wizard asks the ID for the new component, fill the Name, Vendor and Version fields like in the picture below, this ID is used by other JAIN SLEE components to reference the SBB
Click Next till the dialog with Available events appears, as shown below, the plugin automatically displays all event types it knows about (standard events, custom events in the project, etc.)
Find and select the ServiceStartedEvent 1.1 event type, which is the event we want our SBB to handle, then click the Modify button
A dialog to configure the event shows up, we want our event to only be received and initial, being Activity Context the only initial event selector variable selected. As mentioned in the JAIN SLEE intro, such variables are used to compute the ID of the service logic instance, the service convergence name.
Click OK and Finish and the plugin creates the abstract SBB Java class (in sbb/src/main/java), and its XML descriptor (in sbb/src/main/resources), to complete the SBB we just need to add the actual service logic, which is the print of a Hello SLEE World message in the server console, when the ServiceStartedEvent 1.1 is received.
The onServiceStartedEvent(...) method is the event handler we need to code, its parameters are the event object and the interface for interacting with the activity where the event occurred, the ActivityContextInterface. Since we want to print a message in the server console, it could be done with a simple System.out.println(...) call, but being a JAIN SLEE tutorial article, let's do it the right way...
JAIN SLEE standard includes the Tracer concept, a feature rich logger, which interface is very similar to JDK's Logger. The most important feature of the Tracer is the notification of traces to management clients, such as remote consoles, through JMX. Tracers can be retrieved from the SbbContext, and usually are stored in a class field when SLEE creates a SBB class object instance and provides it the SbbContext.
So, now that you know about JAIN SLEE Tracer, let's code 3 lines:
- add a Tracer field to the class
- get the Tracer from SbbContext in the setSbbContext(...) method
- last, our great service logic, do a trace of level INFO with message Hello SLEE World!
The 3 code lines are shown in the picture above, don't forget to save the changes in the SBB class.
Before moving on to the next tutorial section, lets have a look at SBB XML descriptor created by EclipSLEE, open the sbb-jar.xml file in sbb/src/main/resources element in the package explorer:
The XML content should now be clear, it defines the SBB ID (name,vendor,version), it defines what is the SBB abstract class, and declares the interest in handling ServiceStartedEvent 1.1 events, as initial.
Part 4 - Creating the Hello SLEE World Service
To finish our service we need to add the concrete JAIN SLEE Service component, which as mentioned before in this article, is nothing more than an XML descriptor, but the EclipSLEE once again comes to rescue the developer and includes a simple wizard to do it, but before using it, time to introduce another JAIN SLEE concept, the Deployable Unit. The JAIN SLEE Deployable Unit, or simply DU, is a special Java Archive (JAR) used to package JAIN SLEE components, such as SBBs and Services, for deployment in the SLEE. EclipSLEE, upon project creation, creates a Maven module named du that is responsible for building it, and for that it uses the Maven DU Plugin, also developed by the Mobicents team.
OK, lets then add our JAIN SLEE Service to the project DU, please right click on the du/src/main/resources element in the package explorer, and select New > Other, as depicted below:
Find and expand JAIN SLEE, select JAIN SLEE Service, and click Next:
The wizard asks for the service file name, define it as hello-service.xml, click Next, and the wizard now asks the Service ID fields, define these as in the picture below:
Click Next and now the wizard asks what is the root SBB, displaying the SBBs currently present in the project, which should be just one, the SBB we created in the previous article section, select it...
Click the Finish button, the plugin now creates the concrete service XML descriptor in the du maven module resource, lets open it and have a look of what is inside:
The content is actually pretty simple, it should not be difficult to understand and match it against the input that EclipSLEE plugin wizard requested.
Part 5 - Deploying and running the Hello SLEE World Service
The end is near, let's start Mobicents JAIN SLEE Server, in case you don't see the Servers tab anywhere in the Eclipse Java perspective, lets open it using the Window > Show View > Other ... Eclipse Menu option. Find and expand Servers, select Servers, press OK, and now the Servers tab should be visible, right click on it and select Start. You may want to double click the Console tab, to maximize its window and see in detail the startup process progress.
It shouldn't take long for the server to finish startup, when it does, open a shell in the ide/workspace/hello-slee-world directory, and lets build and deploy our service's DU with a single command:
Maven should then start the build process, if it succeeds, as expected, you should see:
[INFO] Reactor Summary:
[INFO] Mobicents :: hello-slee-world v1.0 .................... SUCCESS [3.056s]
[INFO] Mobicents :: hello-slee-world-sbb v1.0 ................ SUCCESS [2.764s]
[INFO] Mobicents :: hello-slee-world-DU v1.0 ................. SUCCESS [3.971s]
[INFO] BUILD SUCCESSFUL
[INFO] Total time: 10 seconds
[INFO] Finished at: Sat May 07 13:06:09 WEST 2011
[INFO] Final Memory: 35M/486M
Cool, now look at Eclipse Console, you should now see the install of the service's DU, and the service activation message printed:
13:13:18,647 INFO [DeploymentMBeanImpl] Installing DeployableUnitID[url=file:/Users/martins/mobicents/slee/binary/2.4.0.FINAL/jboss-5.1.0.GA/server/default/deploy/hello-slee-world-DU-1.0.jar/]
13:13:18,805 INFO [DeploymentMBeanImpl] Installed SbbID[name=Hello SLEE World,vendor=org.mobicents,version=1.0]
13:13:18,898 INFO [DeploymentMBeanImpl] Installed ServiceID[name=Hello SLEE World,vendor=org.mobicents,version=1.0]. Root sbb is SbbID[name=Hello SLEE World,vendor=org.mobicents,version=1.0]
13:13:18,899 INFO [DeploymentMBeanImpl] Installed DeployableUnitID[url=file:/Users/martins/mobicents/slee/binary/2.4.0.FINAL/jboss-5.1.0.GA/server/default/deploy/hello-slee-world-DU-1.0.jar/]
13:13:19,215 INFO [ServiceManagementImpl] Activated ServiceID[name=Hello SLEE World,vendor=org.mobicents,version=1.0]
13:13:19,261 INFO [HelloSleeWorldSbb] Hello SLEE World!
Voila, welcome to SLEE world ;-)
Part 6 - The Service build and deployment by Maven
The EclipSLEE plugin is fun to use, but it may be important to understand what is does, specially what is the underlying Maven project setup, and how its building and deployment of the Service DU works.
The Maven project is multi module, which means it has a root pom.xml, which then declares child modules to build the concrete artifacts. The root pom.xml is depicted below:
The root pom.xml references the mobicents-parent artifact as its parent, that is a special pom.xml used by Mobicents to define the shared build enviroment of all Mobicents projects, for instance it defines the meta data to be added in each jar built, who are the developers, the license, the version of each plugin used, etc. It also references the JBoss Maven repository, this is essential for Maven to be able to download Mobicents artifacts, which are not stored in the central Maven repository managed by Apache Foundation.
Now what matters most, is that the pom declares 2 child modules, sbb and du, when Maven executes the root pom, it will then look for an sbb and du directories, and execute the pom.xml on these directories.
The sbb pom.xml, seen above, is responsible for building the JAIN SLEE sbb jar, for that it declares dependencies on the artifacts containing the JAIN SLEE API, and also the JAIN SLEE extensions promoted by Mobicents JAIN SLEE project. Upon execution it compiles the Java classes in src/main/java directory, and packs these, along with the resources in src/main/resources, in the output jar artifact.
The du pom.xml, seen above, is a bit more complex, it is responsible for building and (un)deploy the JAIN SLEE DU containing the JAIN SLEE Service and the SBB jar.
To build the DU Maven relies on the Mobicents Maven DU Plugin. The plugin processes its configuration and the declared dependencies, retrieving such dependencies, in our case the sbb jar, and generates the JAIN SLEE DU XML descriptor. It leaves then to Maven standard jar plugin to package the services (by default these must be in src/main/resources/services directory), the dependencies, and the XML descriptor, in a jar artifact.
Deployment is done through the usage of Apache Ant Maven plugin, Mobicents JAIN SLEE includes a file deployer scanner, with eyes on the $JBOSS_HOME/server/default/deploy directory, any DU jar copied to that directory is deployed automatically, and undeployed when deleted. Maven Apache plugin simply copies the DU jar to the deploy directory when the mvn command includes the install phase, for instance mvn install, and deletes when it includes the clean phase, for instance mvn clean.
Part 7 - What do and read next
That's it, you can have more fun now with the execution of Mobicents JAIN SLEE bundled examples, and of course, a reference to important documents, to evolve your JAIN SLEE experience:
- Mobicents JAIN SLEE User Guide (container/user-guide in slee/binary/.../docs directory)
- EclipSLEE User Guide (tools/eclipslee/user-guide in slee/binary/.../docs directory)
- JAIN SLEE 1.1 Specification (the JAIN SLEE bible) (get it here)