JBoss.orgCommunity Documentation
This chapter details how to use each of the components included in Snowdrop.
From Spring 3.0 onward, the ApplicationContext
implementations shipped with the Spring framework are VFS-compatible.
The components described in this section are included with Snowdrop
to provide backwards compatibility, but are not necessarily required.
The snowdrop-vfs.jar
library supports resource
scanning in the JBoss Virtual File System (VFS). It must be included
in Spring-based applications that use classpath and resource
scanning.
When the Spring framework performs resource scanning, it assumes that resources are either from a directory or a packaged JAR, and treats any URLs it encounters accordingly.
This assumption is not correct for the JBoss VFS, so Snowdrop provides
a different underlying resource resolution mechanism by amending the
functionality of the PathMatchingResourcePatternResolver
.
This is done by using one of two ApplicationContext
implementations provided by snowdrop-vfs.jar
:
org.jboss.spring.vfs.context.VFSClassPathXmlApplicationContext
Replaces the Spring
org.springframework.context.support.ClassPathXmlApplicationContext
.
org.jboss.spring.vfs.context.VFSXmlWebApplicationContext
Replaces the Spring
org.springframework.web.context.support.XmlWebApplicationContext
.
In many cases, the
VFSClassPathXmlApplicationContext
is
instantiated on its own, using something like:
ApplicationContext context = new VFSClassPathXmlApplicationContext("classpath:/context-definition-file.xml");
The XmlWebApplicationContext
is not
instantiated directly. Instead, it is bootstrapped by either the
ContextLoaderListener
or the
DispatcherServlet
. Both classes have
configuration options that allow users to replace the default
application context type with a custom application context type.
To change the type of application context created by the
ContextLoaderListener
, add the
contextClass
parameter as shown in the
following example code:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring-contexts/*.xml</param-value>
</context-param>
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.jboss.spring.vfs.context.VFSXmlWebApplicationContext
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
To change the type of application context created by the
DispatcherServlet
, use the same
contextClass
parameter on the
DispatcherServlet
definition as shown:
<servlet>
<servlet-name>spring-mvc-servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-config.xml</param-value>
</init-param>
<init-param>
<param-name>contextClass</param-name>
<param-value>
org.jboss.spring.vfs.context.VFSXmlWebApplicationContext
</param-value>
</init-param>
</servlet>
ZipException
If you encounter the ZipException
when
attempting to start the application, you need to replace the default
ApplicationContext
with one of the VFS-enabled
implementations.
Caused by: java.util.zip.ZipException: error in opening zip file ... at org.springframework.core.io.support.PathMatchingResourcePatternResolver .doFindPathMatchingJarResources(PathMatchingResourcePatternResolver.java:448)
Starting with version 1.2, Snowdrop includes a custom Spring namespace for JBoss AS. The goals of this custom namespace is to simplify the development of Spring applications that run on JBoss, by reducing the amount of proprietary code and improving portability.
The amount of proprietary code is reduced because of replacing bean definitions that include references to specific JBoss classes with namespace-based constructs. All the knowledge about the proprietary classes is encapsulated in the namespace handlers.
The applications are more portable because certain proprietary classes may change when upgrading to a different version of the application server. In such cases, the runtime will be detected automatically by Snowdrop which will set up beans using the classes that are appropriate for that specific runtime.
The custom namespace can be set up as follows:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:jboss="http://www.jboss.org/schema/spring" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.jboss.org/schema/snowdrop http://www.jboss.org/schema/snowdrop/snowdrop.xsd">
The default MBean server of JBoss AS can be accessed as follows:
<jboss:mbean-server/>
The bean will be installed with the default id 'mbeanServer'. If necessary, developers can specify a different bean name:
<jboss:mbean-server id="customName"/>
Spring JMS message listeners (including message-driven POJOs) can use a JCA-based MessageListenerContainer. The configuration of a JCA-based listener container in Spring requires the setup of a number of beans based on application-server specific classes. Using the JBoss custom namespace, the ResourceAdapter and ActivationSpec configuration can be set up as follows:
<jboss:activation-spec-factory id="activationSpecFactory" subscriptionName="jca-example" useDLQ="false"/> <jboss:resource-adapter id="resourceAdapter"/>
which can be further used in a JCA message listener configuration:
<jms:jca-listener-container resource-adapter="resourceAdapter" acknowledge="auto" activation-spec-factory="activationSpecFactory"> <jms:listener destination="/someDestination" ref="messageDrivenPojo" method="pojoHandlerMethod"/> </jms:jca-listener-container>
From Spring 3.0 onward, load-time weaving on JBoss AS 5 and JBoss AS 6 is supported out of the box. However, on JBoss AS7 it is necessary to use the load-time weaver provided by Snowdrop. The component described in this section should be used with Spring 2.5 on any of the servers or when using Spring 2.5 and Spring 3.0 with JBoss AS7. In other cases, it is optional, but can be used to facilitate backwards compatibility.
Load-time weaving support is provided by the
snowdrop-weaving.jar
library.
To perform load-time weaving for the application classes in Spring
(either for using load-time support for AspectJ or for JPA support),
the Spring framework needs to install its own transformers in
the classloader. For JBoss Enterprise Application Platform,
JBoss Enterprise Web Platform and JBoss Enterprise Web Server,
a classloader-specific LoadTimeWeaver
is necessary.
Define the JBossLoadTimeWeaver
in the
Spring application context as shown here:
<context:load-time-weaver weaver-class="org.jboss.instrument.classloading.JBossLoadTimeWeaver"/>
The Spring deployer allows you to bootstrap a Spring application context, bind it in JNDI, and use it to provide Spring-configured business object instances.
Snowdrop contains a JBoss deployer that supports Spring
packaging in JBoss AS. This means that it is possible to create JAR archives with a
META-INF/jboss-spring.xml
file to have your
Spring bean factories deploy automatically.
EJB 3.0 integration is also supported. You can deploy Spring archives
and inject beans created in these deployments directly into an EJB by
using the @Spring
annotation.
To install the Spring deployer, unzip the deployer archive
in the $JBOSS_HOME/server/$PROFILE/deployers
directory of your JBoss Application Server installation.
The Snowdrop Spring deployer requires the inclusion of the Spring libraries.
If you are installing a version without dependencies or you want to include your
own Spring version, you must ensure that you are including one of the following sets
of Spring libraries in the $JBOSS_HOME/server/$PROFILE/deployersspring.deployer
folder.
Please include at least the following jars from either the Spring 2.5.6.SEC03 or Spring 3.0.6.RELEASE distribution:
To install the Snowdrop Deployment subsystem, unzip the
jboss-spring-subsystem-as7.zip
file. Create the subsystem
and Spring modules in JBoss AS7 by copying the
contents of the module-deployer
folder and one of the module-spring-2.5
or spring-3
folders in the
$JBOSS_HOME/modules
directory of your JBoss
Application Server installation.
The above step will create two modules inside JBoss AS7:
org.jboss.snowdrop:main
The module that contains the JBoss AS7 subsystem proper
org.springframework.spring:snowdrop
A module that contains the Spring JARs that are required by Snowdrop. It can contain
Spring 2.5 or Spring 3 JARs, dependending the which of the two modules has been copied in the step above.
Users may add other JARs to the module, case in which they need to adjust the module.xml
file accordingly. It is a dependency of org.jboss.snowdrop:main
If you are using the distribution without dependencies, or you wish to create your own version of the
Spring module, then create a $JBOSS_HOME/modules/org/springframework/spring/main
directory and copy one
of the two module.xml
files (from either the module-spring-2.5
or the
module-spring-3
directory of the distribution and copy one of the following sets of files
from the corresponding Spring distribution (either Spring 2.5.6.SEC03 or Spring 3.0.6.RELEASE).
For Spring 2.5:
For Spring 3:
The final step in the installation is to change
$JBOSS_HOME/standalone/configuration/standalone.xml
by including
<extension module="org.jboss.snowdrop"/>
inside the
<extensions>
element, as well as including
<subsystem xmlns="urn:jboss:domain:snowdrop:1.0"/>
inside
the <profile>
element.
You can create Spring deployments that work similarly to JARs, EARs, and WARs with the JBoss Spring deployer. Spring JARs are created with the following structure:
my-app.spring/ org/ acme/ MyBean.class MyBean2.class META-INF/ jboss-spring.xml
my-app.spring
is a JAR that contains classes. A
jboss-spring.xml
file exists in the
META-INF
directory of the JAR. By default, the
JBoss Spring deployer registers the bean factory defined in
jboss-spring.xml
into JNDI in a non-serialized
form. The default JNDI name is the short name of the deployment file —
in this case, my-app
.
You can also place JAR libraries under $JBOSS_HOME/server/$PROFILE/lib
and
add an XML file of the form <name>-spring.xml
,
for example, my-app-spring.xml
, into the
deploy
directory of your JBoss Enterprise Application
Platform or JBoss Enterprise Web Platform installation. The default JNDI
name will be the short name of the XML file; in this case,
my-app
.
Once you have created a .spring
or a
-spring.xml file, copy it into the
deploy
directory of your JBoss AS installation to
deploy it into the JBoss runtime. You can also embed these deployments
in an EAR, EJB-SAR, SAR, and so on, since JBoss AS supports nested
archives.
You can specify the JNDI name explicitly by putting it in the description element of the Spring XML.
<beans> <description>BeanFactory=(MyApp)</description> ... <bean id="springBean" class="example.SpringBean"/> </beans>
MyApp
will be used as the JNDI name in this example.
Sometimes you want your deployed Spring bean factory to be able to reference beans deployed in another Spring deployment. You can do this by declaring a parent bean factory in the description element in the Spring XML, like so:
<beans> <description>BeanFactory=(AnotherApp) ParentBeanFactory=(MyApp)</description> ... </beans>
Once an ApplicationContext
has been successfully bootstrapped,
the Spring beans defined in it can be used for injection into EJBs.
To do this, the EJBs must be intercepted with the
SpringLifecycleInterceptor
, as in the following example:
@Stateless @Interceptors(SpringLifecycleInterceptor.class) public class InjectedEjbImpl implements InjectedEjb { @Spring(bean = "springBean", jndiName = "MyApp") private SpringBean springBean; /* rest of the class definition ommitted */ }
In this example, the EJB InjectedEjbImpl
will be
injected with the bean named springBean
, which is defined in
the ApplicationContext
.