Which is better, Seam or Spring? Learn why you don't have to choose An excerpt from Seam in ActionBy Dan AllenPublished by Manning PublicationsISBN: 1933988401 JBoss Seam is an intriguing framework that unifies JSF, EJB 3, JPA, and JAAS under an accessible component-based model. But adopting Seam doesn’t mean that you have to lose the advantages of other frameworks, such as Spring. In this series, excerpted from Seam in Action (forthcoming from Manning Publications), author Dan Allen shows you how — and why — Seam and Spring can work together. In this first part, learn how to build Seam-Spring hybrid components that benefit from functionality provided by both Seam and Spring containers.If you look inside the golf bag of any non-sponsored golfer, you are likely to find a wide variety of equipment brands. A golfer may feel that a Nike putter provides the best touch around the green, that a TaylorMade driver helps stay out of the woods, and that Cleveland irons are the most forgiving of a bad swing. Perhaps some of it is mental. But the true reason behind this diversity is the fact that equipment companies specialize in different products. One company may not have the same passion for designing great putters that they have for designing big shot drivers. For a golfer, one brand doesn’t always suffice. The same can be said of a developer’s toolbox.To foster such diversity, JBoss Seam provides a module for integrating the Spring Framework into your Seam application — and trust me, this is more than just an academic exercise. Seam unifies JavaServer Faces, Enterprise JavaBeans 3, the Java Persistence API, and the Java Authentication and Authorization Service under an accessible component-based model, empowering you to create stateful enterprise applications with tremendous agility. Still, Spring sports many features that you won’t find in Seam. It’s likely that these features — such as lightweight remoting, advanced aspect-oriented programming (AOP) declarations, framework template classes, and emulated container resource injections, to mention a few — simply aren’t the passion of Seam. This disparity is not necessarily a shortcoming. You don’t have to throw out Seam, along with its stateful architecture and many enterprise integrations, just because it is missing a feature that Spring boasts. Instead, you should recognize that these differences translate into more tools for your toolbox, assuming that you decide to intermix the two frameworks. For that purpose, Seam fully sanctions this integration and encourages the two containers to share both components and low-level resources. In this three-part series (an excerpt from my upcoming book, Seam in Action), you’ll learn how to leverage the Spring container from Seam and vice-versa. This series of articles is designed for developers who are using Seam or JSF and would like to be able to take advantage of capabilities unique to Spring, or those who are contemplating a switch to Seam as a primary platform but don’t want to give up their investment in Spring. The text is phrased with the assumption that you understand the basic concepts of Seam and Spring, with limited references to JSF. However, even without this background, you should be able to appreciate the aim of the Spring-Seam integration from a technology evaluation standpoint. The motivation for writing this series is to let community know that Seam and Spring are not mutually exclusive technologies and that it is quite possible their combination offers more value than either one standing alone.In this first article in the series, you’ll be introduced to the Spring-Seam hybrid component, which is a managed object that benefits from functionality provided by both the Seam and Spring containers. In Part 2, you’ll learn how to infuse state into traditionally stateless Spring beans by allowing them to reside in Seam contexts, and how to inject stateful Seam components into Spring beans. Finally, in Part 3, you’ll learn how to integrate Seam and Spring at the most basic level by having them share a persistence manager.By the end of the series, you will walk away as an enlightened developer, no longer interested in the trite Spring versus Seam debates, but rather looking for more ways to extract value out of the unmatched features of both frameworks. To you, it’s all gravy! Let’s start by learning how to get the two containers to play nice with one another. Seam and Spring, working togetherOne way to integrate Spring beans into a Seam application is by having the Seam container communicate with Spring indirectly through the use of a custom EL (expression language) resolver. This approach is commonly used for integrating Spring with JSF, which in turn gives Seam access to Spring beans. When the EL resolver processes an expression (e.g., #{tournamentManager.tournaments}), it attempts to resolve the base object by scanning both the Spring and Seam containers for a component with a name that matches the expression root (e.g., tournamentManager), falling back to the JSF-managed bean container if the search comes up empty. While this technique may suffice for simple use cases, there is a lot to gain by establishing a genuine integration between the two containers. The goal is to have the components recognize the presence of one another, rather than having the EL resolver mediate their interaction.In order to allow cross-breeding to occur, it is essential to have the two containers start up simultaneously rather than in isolation. Otherwise, you could face an impossible situation where each container has a dependency on a startup component from the other, preventing either container from being able to load first. Fortunately, Seam can facilitate a tandem startup, taking care of resolving any circular prerequisites.Bootstrapping Spring and Seam simultaneouslyBoth Seam and Spring provide servlet context listeners that are used to bootstrap the respective containers. If you register both listeners in the same Web application, then the associated containers are loaded based on the relative order of the listener stanzas in the web.xml descriptor. Instead of hedging a bet that load order alone can guarantee a successful startup, it is better to give one container the responsibility of booting the other. Seam steps forward and offers the ContextLoader (<spring:context-loader>) component to handle this task. This built-in Seam component performs the same work as Spring’s ContextLoaderListener, so the Spring container won’t even recognize that it is being started through a different mechanism. If you are going to be using Spring and Seam together in an application, I strongly recommend that you leverage this boot configuration. The ContextLoader component allows one or more Spring configuration file locations to be specified in the config-locations property of the <spring:context-loader> tag, defined in the Seam component descriptor. The config-locations property is a String array and can be configured in the typical way for a multi-valued component property. Mimicking the behavior of the ContextLoaderListener, if no configuration locations are specified on <spring:context-loader>, the Spring configuration is assumed to be present at the resource path /WEB-INF/applicationContext.xml. With Seam assuming control of the Spring startup, the contextConfigLocation servlet context parameter in the web.xml descriptor is no longer needed.Here are two examples of the ContextLoader configuration in the Seam component descriptor, /WEB-INF/components.xml (or /META-INF/components.xml). Listing 1 uses a single Spring configuration file in a non-default location.Listing 1. Loading a single Spring configuration file<spring:context-loader config-locations="/WEB-INF/spring-beans.xml"/> Listing 2 divides the Spring configuration files up into layers and positions them on the classpath rather than in the Web configuration directory. Listing 2. Loading multiple Spring configuration files<spring:context-loader config-locations="classpath:spring-beans-persistence.xml classpath:spring-beans-service.xml"/> As Listing 3 illustrates, you could also break the config-locations property value up into child elements.Listing 3. Multiple Spring configuration files, itemized explicitly<spring:context-loader> <spring:config-locations> <value>classpath:spring-beans-persistence.xml</value> <value>classpath:spring-beans-service.xml</value> </spring:config-locations> </spring:context-loader> To use this component definition, you must register the XML namespace for the Spring module at the top of the Seam component descriptor, as shown in Listing 4. Note that the namespaces shown here are different from the XML namespaces used in your Spring configuration file.Listing 4. Registering the Spring XML namespace<components xmlns="http://jboss.com/products/seam/components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:spring="http://jboss.com/products/seam/spring" xsi:schemaLocation=" http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.0.xsd http://jboss.com/products/seam/spring http://jboss.com/products/seam/spring-2.0.xsd"> <!-- component declarations --> </components> Putting Seam in charge of loading the Spring container also makes it easy to integration-test Seam applications that rely on Spring beans. When Seam’s integration test infrastructure loads the Seam container, it transitively loads the Spring container. Seam’s integration test infrastructure is activated by writing tests that extend the SeamTest base class. Using Seam and Spring in the same application goes beyond just divvying up your managed objects between two containers. What this integration affords you is the possibility of promoting Spring beans into Seam components at the level of the configuration metadata to form a Spring-Seam hybrid component, which you’ll learn about in the next section. The simultaneous loading of the two containers permits this type of integration because the Seam container is active and ready to register additional components at the time the Spring configuration file is parsed.Spring-Seam hybrid componentsThere is a certain amount of magic behavior that Spring adds to its beans, in the form of BeanPostProcessors. If you register a Spring framework class that relies on functionality provided by a postprocessor directly as a Seam component, you take on the burden of emulating the work done by the Spring container. It would be better to let Spring do the necessary prep work and then have Seam come along and consume the final product.That perfectly describes the behavior of a Spring-Seam hybrid component. Seam provides an XML tag that is used in a Spring bean definition to augment the Spring bean so that it can be treated as a first-class Seam component. Like other Seam components, the hybrid is given a name, registered with the Seam container, and wrapped with Seam interceptors when instantiated. Let’s see how Seam permits you to weave this functionality into the definition of a Spring bean. Preparing Spring to give away beansTo get started with creating Spring-Seam hybrid components, there are two requirements your application must meet. You must first include the Seam IoC integration library, jboss-seam-ioc.jar, on your classpath. Next, as illustrated in Listing 5, you must register the Seam XML namespace in the Spring configuration file in order to use custom tags from the Seam namespace (e.g., <seam:component>). Note that we are now dealing with Spring namespaces that are used in the Spring configuration file, not the Seam namespaces that were shown earlier.Listing 5. Registering the Seam XML namespace<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:seam="http://jboss.com/products/seam/spring-seam" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://jboss.com/products/seam/spring-seam http://jboss.com/products/seam/spring-seam-2.0.xsd"> <!-- bean definitions --> </bean> XML Schema and type-safe configurationOne of the most anticipated features of Spring 2.0 was the introduction of custom XML namespace support. XML Schema-based configuration allows for the use of domain-specific tags (e.g., <jee:jndi-lookup>) instead of the generic and more verbose <bean> tags. Seam made a similar move from generic <component> tags to schema-based component declarations (e.g., <core:manager>). The custom tags offer a sort of “type-safe” XML that simplifies the definition, makes it easier to read, and limits the available property names and property types to what the underlying class supports.Unfortunately, to a newcomer, the XSD declarations at the top of the XML file are downright daunting. Normally, I prefer to do without such XML-hell. However, in this case, the benefits outweigh the negatives because any XSD-aware tool can immediately provide code completion of XML tags without any knowledge of the framework. That sure beats waiting for a vendor to create a tool! The custom tags in the seam namespace do more than just reduce keystrokes and provide implicit validation of property names. The key feature of using custom tags in a Spring configuration file is the bean creation hook captured by an implementation of Spring’s NamespaceHandler class. This implementation is bound to a particular XML namespace prefix. The NamespaceHandler parses the XML elements that it matches, either to produce a Spring bean, decorate an existing bean, or register functionality with the Spring container.Seam supplies a NamespaceHandler implementation to process tags in the Spring configuration file that use the Seam namespace. One such tag, <seam:component>, is used to decorate a Spring bean as a SpringComponent, the formal class name of a Spring-Seam hybrid. This component is then offered as an authentic Seam component to the Seam container. Seam uses the SpringComponent as a wrapper that tunnels through to the Spring container to locate the underlying Spring bean instance. The NamespaceHandler can also handle the <seam:instance> and <seam:configure-scopes> tags, which are addressed in Part 2 of this series. An important point to keep in mind: If you are not using Seam to start Spring (although I cannot think of why you would resist doing so) and you plan to use Spring-Seam hybrid components, you have to be certain that the SeamListener declaration appears before the ContextLoaderListener in the web.xml descriptor. This ordering is necessary so that the Seam container is active and ready to handle the callbacks from its custom NamespaceHandler when the Spring configuration file is processed. However, you may still encounter other unrelated reference problems during startup. Therefore, I strongly urge you to use Seam to start the Spring container.Let’s see how to incorporate the <seam:component> tag into a Spring bean definition.Dressing up a Spring bean as a Seam componentSeam is able to decorate a Spring bean as a Seam component by nesting a <seam:component> inside the <bean> element that defines the Spring bean. This setup is different from the EL resolver approach mentioned earlier because it allows the Spring bean to become a first-class citizen in the Seam container. This gives you much more control over how the Spring bean behaves under the Seam runtime. Let’s explore this integration by putting it into practice. The Spring bean definition of tournamentManager is shown in Listing 6. This bean acts as the business interface to manage a collection of golf tournaments. The golf tournament data is maintained by a partner (hence the org.open18.parter package name) and exposed to the Open 18 application, a golf community portal, through a Web service endpoint. The focus of the sample Web application used in this article is on the back-end management of the tournament data. Notice that the tournamentManager bean has been promoted to a Seam component through the use of the <seam:component> tag.Listing 6. Defining a Spring-Seam hybrid component<bean id="tournamentManager" class="org.open18.partner.business.impl.TournamentManagerImpl"> <seam:component/> </bean> Seam derives the context variable name used to reference the Seam component from the Spring bean identifier, which may be supplied as either the id or name attribute of the <bean> element. If for some reason you do not want to use the ID of the Spring bean as the name of the Seam component, you can provide an alternative name using the name attribute of the <seam:component> tag, as in Listing 7.Listing 7. Providing an alternate Seam component name<bean id="tournamentManager" class="org.open18.partner.business.impl.TournamentManagerImpl"> <seam:component name="tournamentManagerSpring"/> </bean> By default, the Seam component is scoped to the ScopeType.STATELESS context. The stateless context is selected as the default Seam scope because, more times than not, the Spring bean is a singleton. Thus, there is no benefit in storing the bean in a real Seam scope, as it already lives for the duration of the container’s lifetime. The stateless context is also used to step aside and let Spring manage the scope of the bean, if the bean happens not to be a singleton. Spring now supports custom scopes, such as the flow scope from Spring Web Flow. Use of the stateless context prevents Seam from interfering with Spring’s plans for the bean and avoids the case where Seam is holding a stale reference to a bean. Keep in mind, though, that by using the stateless context, Seam will request the bean from the Seam container every time the corresponding context variable is resolved. This same recurrent lookup would occur if the Spring bean were accessed through the EL resolver bridge. You do not need to be concerned about the added overhead unless the Spring bean is a prototype, in which case you should know that the bean will be instantiated on each lookup.If you intend on making the Spring bean stateful (as opposed to a singleton), it’s best to have it stored in a Seam scope. The Seam scope is supplied using the scope attribute on the <seam:component> tag. To store a Spring bean in a Seam scope, the Spring bean must also be assigned the Spring prototype scope.To demonstrate this capability, let’s define a search criteria bean, shown in Listing 8, that is used in conjunction with the tournamentManager bean to filter the collection of tournaments that are displayed in the user interface. The choice of the conversation scope ensures that the search criteria is held in memory for the duration of the user’s interaction with the search form. Listing 8. A conversation-scope Spring bean<bean id="tournamentSearchCriteria" class="org.open18.partner.business.TournamentSearchCriteria" scope="prototype"> <seam:component scope="CONVERSATION"/></bean> Each time a prototype bean is requested from the Spring container, Spring allocates a new instance. But, because the resolved bean is stored in a conversation-scoped context variable in this case, Seam only asks Spring to create an instance once per user conversation. It’s an ideal marriage of the functionality from each container. In the next article in this series, you will learn about another way to scope the Spring bean to a Seam context using Spring’s custom scoping mechanism, and you’ll also study the dangers of scope impedance.Dealing with AOP proxies and covert beansThe definition of tournamentManager above is oversimplified because it does not have transactional capabilities. Spring prides itself on providing declarative services, such as transactions, that are completely transparent to the bean on which they are registered. However, it’s important to understand the mechanism by which these services are applied because Spring’s proxy mechanism has the potential to throw a wrench into the Spring-Seam integration. We are going to see an example of this problem and learn how to work around it. In Listing 9, let’s start by adding some transaction advice to this bean using Spring’s AOP configuration. The transaction manager definition is also shown in this listing.Listing 9. Adding transaction advice with AOP<aop:config proxy-target-class="true" > <aop:advisor id="courseManagerTx" advice-ref="defaultTxAdvice" pointcut="execution(* org.open18.partner.business.TournamentManager.*(..))"/> </aop:config> <tx:advice id="defaultTxAdvice"> <tx:attributes> <tx:method name="get*" read-only="true"/> <tx:method name="*"/> </tx:attributes> </tx:advice> <bean id="transactionManger" class="org.springframework.orm.jpa.JpaTransactionManager"> <!-- entityManagerFactory defined elsewhere --> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> <bean id="tournamentManager" class="org.open18.partner.business.impl.TournamentManagerImpl"> <seam:component/> </bean> Why doesn’t Seam support JDK dynamic proxies?A JDK dynamic proxy is a dynamically generated class that implements a set of interfaces specified at runtime. A dynamic proxy class cannot be cast to the target bean’s class, nor does it provide access to the target bean (i.e., the proxied object). The proxy just happens to implement the same interface(s) as the target bean. Cglib proxies, on the other hand, can be treated more or less like the target bean itself. Cglib creates a new concrete class on the fly that is a subclass (in other words, a class that extends) the target bean’s class. Because Seam needs direct access to the target bean to expose it as a Seam component, it is mandatory that the target bean be enhanced using Cglib rather than act through a JDK dynamic proxy. You may not be a big fan of AOP pointcuts, but bear with me for the time being. This configuration essentially tells the PlatformTransactionManager implementation, which in this case is the JpaTransactionManager, to apply transactions around all of the methods of classes that implement the TournamentManager interface. Any method beginning with get uses a read-only transaction (no flushing), whereas the remaining transactions force a flush of the persistence context before committing. So far, this is just standard Spring behavior and does not affect how the Seam component is derived from the target bean. The setting that does affect how the Seam component is created is the proxy-target-class attribute on the <aop:config> element, highlighted in Listing 9 in bold. This point I am about to make is very important. Seam cannot adopt JDK proxied Spring beans. Seam can only deal with Cglib and Javassist instrumented classes.Huh? If you are new to dynamic proxying and bytecode manipulation, this may sound like Greek to you. Basically, as part of the AOP mechanism, Spring wraps your Spring bean in a layer that can intercept method calls and add functionality before and after each invocation. This technique is exactly what Seam does to add capabilities such as bijection to its components. However, Seam weaves in this behavior using runtime bytecode enhancement provided by the Javassist library. Spring, on the other hand, uses JDK dynamic proxies by default. The JDK proxying infrastructure is only capable of creating proxies for interfaces, whereas the bytecode enhancement libraries, including Javassist and Cglib, can work directly on classes.Suffice to say, Seam cannot work with the Spring bean if it uses JDK dynamic proxying. This issue doesn’t come up when accessing a Spring bean through the EL resolver because Seam only calls on the methods. Here, the Spring bean is being converted into a Seam component, so Seam is involved in the internals of the bean creation process and needs the extra level of visibility. The situation is this: Seam cannot handle JDK proxies. Spring cannot enhance beans using Javassist. To meet in the middle, Spring can use runtime bytecode enhancement provided by Cglib, which is enough to make Seam happy. The switch to this alternate proxy provider happens on a per-bean basis. In the case of the <aop:confg> element, that switch is made using the proxy-target-class attribute. Despite the horrible name for this attribute, a value of true enables Cglib proxies rather than dynamic JDK proxies. If you do not make this switch, you will get the following exception when you try to make a proxied Spring bean into a Spring-Seam hybrid:Caused by: java.lang.RuntimeException: Seam cannot wrap JDK proxied IoC beans. Please use CGLib or Javassist proxying instead at org.jboss.seam.ioc.ProxyUtils.enhance(ProxyUtils.java:52) What if pointcuts just aren’t your cup of tea? You can opt, instead, to use Spring’s TransactionProxyFactoryBean to wrap your service layer object in transactions. This bean has a similar switch for its proxy setting, but that isn’t the only issue you will encounter. You now have a new problem. When you use a proxy factory bean, the class name of the target object is no longer on the <bean> definition. Listing 10 offers a look.Listing 10. Using a proxy factory bean to avoid pointcuts<bean id="tournamentManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <seam:component class="org.open18.partner.service.impl.TournamentManagerImpl"/> <property name="proxyTargetClass" value="true"/> <property name="transactionAttributes"> <props> <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="*">PROPAGATION_REQUIRED</prop> </props> </property> <property name="proxyInterfaces" value="org.open18.partner.service.TournamentManager"/> <property name="target"> <bean class="org.open18.partner.service.impl.TournamentManagerImpl"/> </property> </bean> This bean definition has the same transaction properties as the one in Listing 9, which used AOP pointcut expressions. It also sets the proxyTargetClass property to true to enable Cglib proxying. However, notice that the <seam:component> element is now using the class attribute to specify the name of the class that implements the service layer interface. This class is also supplied in the target property of the bean definition. Why specify it in both places?The implementation class must be stated explicitly so that Seam knows what type of object the Spring factory bean produces. This information is buried deep inside the <bean> definition, where Seam is unable to find it. Without this information, Seam cannot perform operations that require knowledge of the hybrid component’s type, such as injecting it into the property of another component. What’s worse is that without this hint, Seam actually gets the type wrong, given that the class attribute on the <bean> definition is consulted to determine the component’s type. In this example, Seam assumes that the class of the tournamentManager component is TransactionFactoryProxyBean. This problem also comes up when using Spring’s bean definition inheritance feature (the parent attribute on the <bean> definition). When the <seam:component> is used in a child bean definition, you once again have to educate Seam about which type to expect. This incompability with bean inheritence will likely be resolved soon, since all of the information Seam needs is there in the bean definition hierarchy — it’s just a matter of Seam looking for it. However, the point remains that if there is ever a case where Seam cannot determine the type, or gets the type wrong, you can supply an override using the class attribute.Although the class attribute is required to get the hybrid component registered properly, Seam has no problem working with a Spring factory bean once the hybrid component is setup. When you inject the tournamentManager component into a TournamentManager property on another Seam component, Seam correctly unwraps the factory bean to get to the underlying proxied target object, as opposed to trying to inject the factory bean itself. What you also might find interesting is that Seam can correctly apply component configuration properties to the target bean.That gets us started with creating Seam components with the <seam:component> tag. Let’s give more thought to the significance of a Spring bean becoming a Seam component and learn how to fine-tune the behavior of the Seam component that it generates.On becoming a Seam componentAs was mentioned earlier, when a tag is detected inside of a element, Seam’s NamespaceHandler implementation wraps the Spring bean in an instance of SpringComponent and registers it with the Seam container, making the Spring bean a full-fledged Seam component. That means that when a method is invoked on the Spring bean, all the normal Seam interceptors are applied. Think about that for a moment. You can now use all of Seam’s bijection goodness in your Spring beans! Let’s assume that a Spring bean named tournamentDao, responsible for performing searching against the database, is also setup as a Spring-Seam hybrid component as explained above. Listing 11 shows how this data access object can be injected into the tournament manager business object using Seam’s @In annotation, an alternative to using Spring’s dependency injection mechanism. Additionally, Seam’s @Logger annotation is used to instantiate and inject a logger.Listing 11. Using bijection in a Spring beanpublic class TournamentManagerImpl implements TournamentManager { <b>@Logger</b> private Log log; <b>@In</b> private TournamentDao tournamentDao; public List<Tournament> findTournaments(TournamentSearchCriteria searchCriteria) { if (searchCriteria == null) { log.debug("Fetching all tournaments"); return tournamentDao.getAllTournaments(); } else { log.debug("Performing a criteria-based search for tournaments"); return tournamentDao.searchTournaments(searchCriteria); } } public void setTournamentDao(TournamentDao tournamentDao) { this.tournamentDao = tournamentDao; } } Now we need to supply the search criteria argument to the finder method and capture the result. That is done through the use of a factory defined in the Seam component descriptor (components.xml). The finder method is referenced as a value expression and the return value is bound to a Seam context variable using<factory name="tournamentResults" value="#{tournamentManager.findTournaments(tournamentSearchCriteria)}"/> Notice that the value expression takes advantage of the JBoss EL, which allows a parameter to be passed to a method, in this case the conversation-scoped search criteria. It’s now possible to iterate over the search results in the user interface by referencing the value expression #{tournamentResults}. You could also take advantage of additional Seam annotations, such as @Factory, @Restrict, @RaiseEvent, @Observer, and @Transactional, to name a few. If you would rather not dirty your Spring beans with Seam interceptors, preferring to leave your Spring beans pristine, you can disable Seam interceptors by setting the intercept attribute of <seam:component> to false. Disabling interceptors can improve performance, especially if you aren’t going to be using any of the functionality they provide anyway. The change to the definition is shown in bold in Listing 12.Listing 12. Disabling Seam interceptors<bean id="tournamentManager" class="org.open18.partner.business.impl.TournamentManagerImpl"> <seam:component intercept="false"/></bean> Auto-create components and container initializationWhen the two containers are started in isolation, the load order again reaches a deadlock when auto-create hybrid components are formed from Spring singleton beans. If the Spring container is started first, then when the auto-create variable is registered, an error will be thrown that complains that you are attempting to invoke a Seam component outside of an initialized application. If the Seam container is started first, then when the auto-create variable is registered, an error will be thrown stating that the application scope is not active. In both cases, the Spring initialization process is operating outside of the boundaries of the Seam initialization process. To remedy this problem, and any other intercontainer dependencies, it is best to allow Seam to start Spring. With or without interception enabled, you can still use Seam’s component configuration mechanism to set initial property values on a Spring-Seam hybrid component. This includes log injection for the field or property accessor decorated with @Logger. However, customizing properties through Seam should probably be used sparingly (perhaps only for environment-specific overrides) since it can confuse other developers — or perhaps even you, down the road — when attempting to get a complete picture of the component definition. The recommendation is to use Spring’s property configuration mechanism instead.Spring-Seam hybrid components, by default, are configured to be auto-created. However, in this case, the term is a bit misleading. That’s because the Spring bean may already be initialized at the time the context variable is first requested, perhaps because it was created when the Spring container started. But Seam still considers the context variable uninitialized at this point, because Seam hasn’t yet consulted the Spring container to determine if the bean has been created. Thus, the auto-create attribute on <seam:component> really means “attempt to resolve the Spring bean without being told to do so.” If this is not the desired behavior, you can disable it by changing the value of the auto-create attribute of <seam:component> to false, as in Listing 13.Listing 13. Disabling automatic lookup<bean id="tournamentManager" class="org.open18.partner.business.impl.TournamentManagerImpl"> <seam:component auto-create="false"/> </bean> The auto-create setting is especially relevant considering that most Spring-Seam hybrid components are stateless, resulting in a context variable that is never permanently initialized. Thus, you will likely always want the value of the auto-create attribute to be true. If its value is false, then it necessitates the use the create flag on the @In annotation when referencing the corresponding context variable. EL value expressions that reference the context variable are not affected, since they perform the lookup implicitly.Upon the context variable being requested, if the create flag is true and if the Spring bean exists, it will be returned to Seam. If the create flag is true and the Spring bean doesn’t exist, the Spring container will attempt to create it, and then return the instance to Seam. If the create flag is false, no attempt will be made to communicate with the Spring container.The best of both worldsYou can now use Spring beans as needed in your Seam application. The Spring Framework is filled with potential Seam components and convenient functionality. I would be a fool to tell you otherwise. Supplementing Seam with Spring will likely prove to be very valuable to the success of your application. Why choose?In fact, Seam can even make Spring beans better by teaching them a thing or two about maintaining application state — and you’ll learn how that works in the next article in this series. Until then, you can try building your own Spring-Seam hybrid components to get a feel for how the two frameworks complement each other.Dan Allen is an independent software consultant, author, and open source advocate. After graduating from Cornell University with a degree in Materials Science and Engineering in 2000, Dan became captivated by the world of free and open source software, which is how he got his start in software development. He soon discovered the combination of Linux and the Java EE platform to be the ideal blend on which to build his professional career. In his search for a robust Web framework, Dan happened upon JBoss Seam, which was quickly granted this most coveted spot in his development toolbox. Excited about Seam, Dan decided to share his thoughts with the world. He is now the author of Seam in Action, published by Manning Publications, a project which he picked up immediately after completing his three-part series on Seam for IBM developerWorks. Dan is also a committer on the Seam project, an active participant in the Seam community, and a Java blogger. You can keep up with Dan’s development experiences by subscribing to his blog at www.mojavelinux.com. Open SourceSoftware DevelopmentWeb DevelopmentJava