Java IoT Authors: Zakia Bouachraoui, Pat Romanski, Elizabeth White, Liz McMillan, Yeshim Deniz

Related Topics: Java IoT, IBM Cloud

Java IoT: Article

Spring and EJB 3.0 in Harmony

In search of the best of both worlds

The new EJB 3.0 specification supports some notion of dependency injection via annotations. As an avid Spring user, I'm used to configuring fine-grained beans with Spring bean factories and XML. How does EJB 3.0 compare? More importantly, can we use EJB 3.0 POJOs and Spring POJOs side-by-side in applications? In this article, I'll try to answer those questions based on my own investigations and experiences. As it turns out, using a versatile application server like the JBoss Application Server (AS), Spring and EJB 3.0 POJOs can co-exist in harmony in your applications.

EJB3 Dependency Injection
In EJB 3.0 it's fairly easy to inject Java EE components into an EJB object using various annotations provided by the specification. @Resource is available to inject things like datasources and JMS destinations. @EJB is there to get references to other EJBs. @PersistenceContext can get you a reference to the EntityManager service. You can use these annotations to inject directly into the field of your EJB, or you can apply them on setter methods. Here are some examples:

public class ShoppingCartBean implements ShoppingCart {
    @Resource(name="DefaultDS") private DataSource ds;
    @EJB private CreditCardProcessor ccp;

    EntityManager em;

    public void setEntityManager(EntityManager em) {
      this.em = em;

For developers who don't want to use annotations to inject components, EJB 3.0 provides an XML alternative to injection annotations:


Great! So we have two ways of injecting dependencies in EJB 3.0. However, one big problem with EJB 3.0 dependency injection is that there's no way of configuring, defining, and injecting plain Java beans. You can only inject Java EE component types and <env-entry> only lets you inject primitive types. Sure, EJBs look a lot like POJOs and JBoss has the concept of a @Service bean, which is a singleton, but do we really have to define and inject these component objects that have to run in containers? And what about beans from third-party libraries and pre-existing code. There must be something better! Could it be JNDI registration? Maybe, but who will instantiate and construct our beans? Really this is what Spring's dependency injection is all about. But how do we get Spring's beans into an EJB3 container?

Spring and EJB3 - Synergy or Superfluous?
To integrate Spring beans with EJBs, the application server plays the central role since it can deploy both components. JBoss AS seems to be the best platform here because it was the first application server to support EJB 3.0 and it is an Open Source product. More importantly, JBoss AS's microkernel architecture is flexible enough to create any package/component type that can be deployed in the JBoss runtime. JBoss AOP and interceptor technology could be used to glue custom behavior into POJOs and/or EJBs.

So I decided to write a Spring deployer for JBoss AS. In the rest of the article, I'll discuss exactly what I did and how you can use the deployer. As it turns out, there really is synergy between Spring and JBoss EJB 3.0. Developers can have the best of both worlds.

JBoss AS Deployers
The first challenge is to package Spring into a deployable unit to eliminate the bootstrapping code that's required in most Spring applications. The deployer should work with a custom Spring archive type in much the same way Java EE has .EARs and .WARs. You can define new archive types in JBoss by writing a JBoss Deployer.

When JBoss boots up, it scans the deploy directory for available packaged components that are JBoss services or your packaged applications. JBoss Deployers are responsible for managing these packaged components. Their purpose is to understand deployment descriptors and archive formats so they can be deployed into the JBoss application server at runtime. Deployers are also responsible for creating classloaders for packaged component and managing hot deployment. There's a specific deployer service for each component type in JBoss: enterprise archives (.ear), Web archives (.war), EJB archives (.jar), datasources (-ds.xml), Hibernate archives (.har), etc. I wanted to be able to define a Spring archive (.spring) that would look like this:


It would really look like an EJB jar, but instead of a ejb-jar.xml deployment descriptor, one would be specific to Spring. The JBoss Spring deployer recognizes the myapp.spring deployment, parses the deployment descriptor to create a Spring bean factory, and registers that Spring bean factory under some JNDI name so that it can be looked up and used by other applications. And if this archive was removed, JBoss should destroy the bean factory and unregister it from JNDI. Basically, the goal is to let Spring bean factories be hot-deployable in a JBoss environment.

JBoss has an abstract API for writing new deployers and it was very simple to write a Spring-based archive type. JBoss's deployer API provides a simple abstract class - org.jboss.deployment.SubDeployerSupport - that I used to implement my Spring Deployer. One simply has to implement or override a few methods to get things working. Let's look at those methods:

   protected void initializeMainDeployer() {
     setSuffixes(new String[]{".spring", "-spring.xml"});

   /* @return True if this deployer
   * can deploy the given DeploymentInfo.
   * @jmx:managed-operation
   public boolean accepts(DeploymentInfo di) {
     String urlStr = di.url.toString();
     return urlStr.endsWith(".spring") || urlStr.endsWith(".spring/") ||

This code is trivial but it's the core of determining if a deployed component is a Spring component. Each JBoss deployer is asked if it accepts a given archive for deployment. This code specifies that the Spring Deployer excepts file names that end with .spring or -spring.xml. JBoss has a default ordering schema when it deploys packages. Since deployers are themselves packaged components, they tell the JBoss runtime what relative order their component type should be deployed in as shown in Listing 1.

As I said before, JBoss deployers support the hot redeployment of your custom component type at runtime. To enable this, you have to give JBoss a URL to watch to see if the timestamp on this file changes at runtime. Our deployer will support raw Spring XML files, .spring JAR archives, and exploded .spring archives. The init() method above sets up the watch URL as shown in Listing 2.

Deployers create() method calls BeanFactoryLoader's create method, which is responsible for managing our different Spring bean factories. When instantiating beans in a new bean factory we make sure that newly created beans are loaded by a global scope classloader. Normal JNDI bindings require a serializable object, which is unusable for our Spring bean factory. JBoss provides a JNDI ObjectFactory implementation that lets us store objects in a non-serializable form in a local JNDI context. The binding will only be valid as long as our bean factory is deployed.

Since we'd like to hot deploy many different Spring archives, each of them must be uniquely represented in our environment. For that purpose, JNDI will be used as a registry for these deployments. But where can we get our local JNDI name? By default, this JNDI name is obtained from the archive's file name: <name>.spring or <name>-spring.xml. But since it's also possible for each bean factory to have parent bean factory, there should be a way to define this parent's name too. This can be done in Spring's beans xml descriptor in description tag as shown in Listing 3.

We are parsing this description tag and looking for a regular expression pattern of 'BeanFactory=(<name>)' and 'ParentBeanFactory=(<name>)' so see Listing 4.

Every time a Spring component is undeployed, we get the corresponding Bean factory through the URL string key in our bean factory map. We remove the map entry, destroy the bean factory singletons, and unbind it from JNDI. When undeploying components be careful of the bean factory hierarchy; don't undeploy some other component's parent bean factory. When shutting down, JBossAS undeploys components in reverse order, which is the right behavior for our child-parent bean factory hierarchy.

More Stories By Ales Justin

Ales Justin is a Java developer at Genera Lynx d.o.o. He's also a JBoss contributor and committer.

Comments (1)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.

IoT & Smart Cities Stories
Moroccanoil®, the global leader in oil-infused beauty, is thrilled to announce the NEW Moroccanoil Color Depositing Masks, a collection of dual-benefit hair masks that deposit pure pigments while providing the treatment benefits of a deep conditioning mask. The collection consists of seven curated shades for commitment-free, beautifully-colored hair that looks and feels healthy.
The textured-hair category is inarguably the hottest in the haircare space today. This has been driven by the proliferation of founder brands started by curly and coily consumers and savvy consumers who increasingly want products specifically for their texture type. This trend is underscored by the latest insights from NaturallyCurly's 2018 TextureTrends report, released today. According to the 2018 TextureTrends Report, more than 80 percent of women with curly and coily hair say they purcha...
The textured-hair category is inarguably the hottest in the haircare space today. This has been driven by the proliferation of founder brands started by curly and coily consumers and savvy consumers who increasingly want products specifically for their texture type. This trend is underscored by the latest insights from NaturallyCurly's 2018 TextureTrends report, released today. According to the 2018 TextureTrends Report, more than 80 percent of women with curly and coily hair say they purcha...
We all love the many benefits of natural plant oils, used as a deap treatment before shampooing, at home or at the beach, but is there an all-in-one solution for everyday intensive nutrition and modern styling?I am passionate about the benefits of natural extracts with tried-and-tested results, which I have used to develop my own brand (lemon for its acid ph, wheat germ for its fortifying action…). I wanted a product which combined caring and styling effects, and which could be used after shampo...
The platform combines the strengths of Singtel's extensive, intelligent network capabilities with Microsoft's cloud expertise to create a unique solution that sets new standards for IoT applications," said Mr Diomedes Kastanis, Head of IoT at Singtel. "Our solution provides speed, transparency and flexibility, paving the way for a more pervasive use of IoT to accelerate enterprises' digitalisation efforts. AI-powered intelligent connectivity over Microsoft Azure will be the fastest connected pat...
There are many examples of disruption in consumer space – Uber disrupting the cab industry, Airbnb disrupting the hospitality industry and so on; but have you wondered who is disrupting support and operations? AISERA helps make businesses and customers successful by offering consumer-like user experience for support and operations. We have built the world’s first AI-driven IT / HR / Cloud / Customer Support and Operations solution.
Codete accelerates their clients growth through technological expertise and experience. Codite team works with organizations to meet the challenges that digitalization presents. Their clients include digital start-ups as well as established enterprises in the IT industry. To stay competitive in a highly innovative IT industry, strong R&D departments and bold spin-off initiatives is a must. Codete Data Science and Software Architects teams help corporate clients to stay up to date with the mod...
At CloudEXPO Silicon Valley, June 24-26, 2019, Digital Transformation (DX) is a major focus with expanded DevOpsSUMMIT and FinTechEXPO programs within the DXWorldEXPO agenda. Successful transformation requires a laser focus on being data-driven and on using all the tools available that enable transformation if they plan to survive over the long term. A total of 88% of Fortune 500 companies from a generation ago are now out of business. Only 12% still survive. Similar percentages are found throug...
Druva is the global leader in Cloud Data Protection and Management, delivering the industry's first data management-as-a-service solution that aggregates data from endpoints, servers and cloud applications and leverages the public cloud to offer a single pane of glass to enable data protection, governance and intelligence-dramatically increasing the availability and visibility of business critical information, while reducing the risk, cost and complexity of managing and protecting it. Druva's...
BMC has unmatched experience in IT management, supporting 92 of the Forbes Global 100, and earning recognition as an ITSM Gartner Magic Quadrant Leader for five years running. Our solutions offer speed, agility, and efficiency to tackle business challenges in the areas of service management, automation, operations, and the mainframe.