Spring Web Flow + Thymeleaf - spring

I want to use Spring Web Flow along with Thymeleaf, which was previously configured with Spring MVC. It works, however I get "org.springframework.webflow.definition.registry.NoSuchFlowDefinitionException" on every page. I want to use SWF on certain pages and leave the rest as it was - handled by controllers without flow. Is it possible?
Here's my view config:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oxm="http://www.springframework.org/schema/oxm"
xmlns:webflow="http://www.springframework.org/schema/webflow-config"
xsi:schemaLocation="http://www.springframework.org/schema/oxm
http://www.springframework.org/schema/oxm/spring-oxm.xsd
http://www.springframework.org/schema/webflow-config
http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.3.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="templateResolver"
class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
<property name="prefix" value="/WEB-INF/thymeleaf/" />
<property name="suffix" value=".html" />
<property name="templateMode" value="HTML5" />
<!-- Template cache is set to false (default is true). -->
<property name="cacheable" value="false" />
</bean>
<bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver" />
<property name="additionalDialects">
<set>
<bean class="org.thymeleaf.extras.springsecurity3.dialect.SpringSecurityDialect" />
</set>
</property>
</bean>
<webflow:flow-executor id="flowExecutor"></webflow:flow-executor>
<bean name="/*"
class="org.springframework.webflow.mvc.servlet.FlowController">
<property name="flowExecutor" ref="flowExecutor" />
</bean>
<webflow:flow-registry id="flowRegistry"
flow-builder-services="flowBuilderServices">
<webflow:flow-location-pattern value="/**/*-flow.xml" />
</webflow:flow-registry>
<webflow:flow-builder-services id="flowBuilderServices"
view-factory-creator="mvcViewFactoryCreator" />
<bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="contentNegotiationManager" ref="cnManager" />
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
<property name="order" value="1" />
</bean>
<bean id="thymeleafViewResolver" class="org.thymeleaf.spring4.view.AjaxThymeleafViewResolver">
<property name="viewClass"
value="org.thymeleaf.spring4.view.FlowAjaxThymeleafView" />
<property name="templateEngine" ref="templateEngine" />
<property name="order" value="2" />
</bean>
</list>
</property>
</bean>
<bean id="mvcViewFactoryCreator"
class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">
<property name="viewResolvers" ref="thymeleafViewResolver" />
</bean>
<bean id="thymeleafViewResolver" class="org.thymeleaf.spring4.view.AjaxThymeleafViewResolver">
<property name="viewClass"
value="org.thymeleaf.spring4.view.FlowAjaxThymeleafView" />
<property name="templateEngine" ref="templateEngine" />
</bean>
<!-- Simple strategy: only path extension is taken into account -->
<bean id="cnManager"
class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="true" />
<property name="ignoreAcceptHeader" value="true" />
<property name="defaultContentType" value="text/html" />
<property name="mediaTypes">
<map>
<entry key="html" value="text/html" />
<entry key="xml" value="application/xml" />
<entry key="atom" value="application/atom+xml" />
</map>
</property>
</bean>

Related

Spring-Batch MongoDB : Skip functionality is not working properly in MongoItemReader scenario

Skip exception class functionality is not working properly when MongoItemreader is being used.
Issues:
1. Spring batch is stuck at a particular data row (in my case 15). It calls MessageContextReadConverter and onReadError for same row number 15 -- 3 times.
2. skiplistener is never invoked.
Scenario:
Suppose 20 rows are fetched from MongoDB and at row number 15 configurable exception ".ConversionFailedException" is thrown from a custom class derived from Converter, (MessageContextReadConverter implements Converter)
. MessageContextReadConverter is set during mongoTemplate creation,.
Now, exception thrown at row number 15 is received in custom readlistener (public void onReadError(Exception ex)).
Configuration XML:
<context:property-placeholder location="classpath:application.properties" />
<context:component-scan base-package="com.XXX.YYY.batch.kernel" />
<context:component-scan base-package="com.XXX.YYY.batch.dao" />
<context:annotation-config />
<!-- Enable Annotation based Declarative Transaction Management -->
<tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager" />
<!-- Creating TransactionManager Bean, since JDBC we are creating of type DataSourceTransactionManager -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<batch:job id="txnLogJob" restartable="false">
<batch:step id="txnload">
<tasklet allow-start-if-complete="true" transaction-manager="transactionManager">
<chunk reader="txnLogReader" processor="txnLogProcessor"
writer="txnLogItemWriter" commit-interval="10" skip-limit="3">
<skippable-exception-classes>
<include class="org.springframework.core.convert.ConversionFailedException" />
</skippable-exception-classes>
</chunk>
<listeners>
<listener ref="stepListener" />
<listener ref="chunklistener" />
<listener ref="readlistener" />
<listener ref="skiplistener" />
</listeners>
</tasklet>
</batch:step>
<batch:listeners>
<batch:listener ref="completionListener" />
</batch:listeners>
</batch:job>
<bean id="txnLogReader" class="org.springframework.batch.item.data.MongoItemReader"
scope="step">
<property name="template" ref="mongoTemplate" />
<property name="query" value=" { }" />
<property name="pageSize" value="50" />
<property name="sort">
<map>
<entry key="audit_info.created_on"
value="#{T(org.springframework.data.domain.Sort.Direction).ASC}" />
</map>
</property>
<property name="collection" value="txnlog" />
<property name="targetType" value="com.XXX.YYY.kernel.msg.MessageContext" />
</bean>
<bean id="completionListener"
class="com.XXX.YYY.batch.listeners.JobCompletionNotificationListener" />
<bean id="stepListener"
class="com.XXX.YYY.batch.listeners.StepExecutionListener" />
<bean id="chunklistener"
class="com.XXX.YYY.batch.listeners.ChunkExecutionListener" />
<bean id="readlistener"
class="com.XXX.YYY.batch.listeners.ReadExecutionListener" />
<bean id="skiplistener"
class="com.XXX.YYY.batch.listeners.SkipExecutionListener" />
<bean id="jobParametersDAOImpl" class="com.XXX.YYY.batch.dao.JobParametersDAOImpl" />
<bean id="batchLoader" class="com.XXX.YYY.batch.kernel.BatchLoader" />
<bean id="batchjobParameter" class="com.XXX.YYY.batch.dao.Batch_Job_Parameters" />
<!-- <bean id="reportWriter" class="org.springframework.batch.item.data.MongoItemWriter">
<property name="template" ref="mongoTemplate" /> <property name="collection"
value="txnlog" /> name of the collection to write </bean> -->
<bean id="txnLogItemWriter" class="org.springframework.batch.item.file.FlatFileItemWriter"
scope="step">
<property name="shouldDeleteIfExists" value="true" />
<property name="resource" value="file:target/test-outputs/output.txt" />
<property name="lineAggregator">
<bean
class="org.springframework.batch.item.file.transform.PassThroughLineAggregator" />
</property>
</bean>
<bean id="txnLogProcessor"
class="com.XXX.YYY.batch.processor.MessageContextItemProcessor" />
<bean id="jobLauncher"
class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
<property name="databaseType" value="MYSQL" />
<property name="dataSource" ref="dataSource" />
<property name="transactionManager" ref="transactionManager" />
</bean>
<bean id="dataSource" class="com.XXX.YYY.common.DataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="connectionProperties" value="${jdbc.connectionProperties}" />
<property name="initialSize" value="${jdbc.initialSize}" />
<property name="maxTotal" value="${jdbc.maxTotal}" />
<property name="maxIdle" value="${jdbc.maxIdle}" />
<property name="minIdle" value="${jdbc.minIdle}" />
<property name="maxWaitMillis" value="${jdbc.maxWaitMillis}" />
<property name="testOnBorrow" value="${jdbc.testOnBorrow}" />
<property name="testWhileIdle" value="${jdbc.testWhileIdle}" />
<property name="testOnReturn" value="${jdbc.testOnReturn}" />
<property name="validationQuery" value="${jdbc.validationQuery}" />
</bean>

spring batch admin showing jobs as not launchable

I have a spring mvc webapp with spring batch built into it. I am having some issues getting my spring batch jobs to be launchable in the spring batch admin console. This is what I see when I go to the jobs page...
All of my jobs are coming up as launchable=false. I was wondering how I can fix this. I read some documentation about why this would be so and it said that I need to use a AutomaticJobRegistrar.
I tried this but it didn't change anything. I've put my spring batch job configuration below. Would appreciate it someone could tell me what is missing.
thanks
<beans profile="pre,prod">
<bean id="jobLauncher"
class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"
parent="abstractCustDbJdbcDao">
<property name="transactionManager" ref="custDbTransactionManager" />
<property name="databaseType" value="db2" />
<property name="tablePrefix" value="REPMAN.BATCH_" />
</bean>
<bean id="jobExplorer"
class="org.springframework.batch.core.explore.support.JobExplorerFactoryBean"
parent="abstractCustDbJdbcDao" />
<bean class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
<property name="jobRegistry" ref="jobRegistry" />
</bean>
<bean id="jobLoader" class="org.springframework.batch.core.configuration.support.AutomaticJobRegistrar">
<property name="applicationContextFactories">
<bean class="org.springframework.batch.core.configuration.support.ClasspathXmlApplicationContextsFactoryBean">
<property name="resources" value="classpath*:/META-INF/spring/jobs/*.xml" />
</bean>
</property>
<property name="jobLoader">
<bean class="org.springframework.batch.core.configuration.support.DefaultJobLoader">
<property name="jobRegistry" ref="jobRegistry" />
</bean>
</property>
</bean>
<bean id="jobRegistry"
class="org.springframework.batch.core.configuration.support.MapJobRegistry" />
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="jobDetails">
<list>
<ref bean="dailyTranCountJobDetail" />
<ref bean="bulletinBarMsgUpdateJobDetail" />
<ref bean="updateLovCacheJobDetail" />
</list>
</property>
<property name="triggers">
<list>
<ref bean="dailyTranCountCronTrigger" />
<ref bean="bulletinBarMsgUpdateCronTrigger" />
<ref bean="updateLovCacheCronTrigger" />
</list>
</property>
</bean>
<!-- scheduling properties -->
<util:properties id="batchProps" location="classpath:batch.properties" />
<context:property-placeholder properties-ref="batchProps" />
<!-- triggers -->
<bean id="dailyTranCountCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="dailyTranCountJobDetail" />
<property name="cronExpression" value="#{batchProps['cron.dailyTranCounts']}" />
</bean>
<bean id="bulletinBarMsgUpdateCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="bulletinBarMsgUpdateJobDetail" />
<property name="cronExpression" value="#{batchProps['cron.bulletinBarUpdateMsg']}" />
</bean>
<bean id="updateLovCacheCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="updateLovCacheJobDetail" />
<property name="cronExpression" value="#{batchProps['cron.updateLovCache']}" />
</bean>
<!-- job detail -->
<bean id="dailyTranCountJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.myer.reporting.batch.JobLauncherDetails" />
<property name="group" value="quartz-batch" />
<property name="jobDataAsMap">
<map>
<entry key="jobName" value="job-daily-tran-counts" />
<entry key="jobLocator" value-ref="jobRegistry" />
<entry key="jobLauncher" value-ref="jobLauncher" />
</map>
</property>
</bean>
<bean id="bulletinBarMsgUpdateJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.myer.reporting.batch.JobLauncherDetails" />
<property name="group" value="quartz-batch" />
<property name="jobDataAsMap">
<map>
<entry key="jobName" value="job-bulletin-bar-msg-update" />
<entry key="jobLocator" value-ref="jobRegistry" />
<entry key="jobLauncher" value-ref="jobLauncher" />
</map>
</property>
</bean>
<bean id="updateLovCacheJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.myer.reporting.batch.JobLauncherDetails" />
<property name="group" value="quartz-batch" />
<property name="jobDataAsMap">
<map>
<entry key="jobName" value="job-update-lov-cache" />
<entry key="jobLocator" value-ref="jobRegistry" />
<entry key="jobLauncher" value-ref="jobLauncher" />
</map>
</property>
</bean>
</beans>
There are a few things this could be:
Where is the XML file you reference above located? It needs to be the META-INF/spring/batch/jobs directory in your WAR file (that's where Spring Batch Admin will look).
Don't configure common components in your XML file. That includes the jobLauncher, jobRepository, jobExplorer, jobLoader, or jobRegistry. That being said, I don't see an actual job defined in your XML file. The XML file needs one of those ;)
You can read more about adding your own job definitions to Spring Batch Admin: http://docs.spring.io/spring-batch-admin/reference/jobs.html#Add_your_Own_Jobs_For_Launching_in_the_UI

Spring JMS message redelivery is not working

I am not sure what i am missing, when consumer is not able to process messsage it throws JMSException but i see failed messages are not getting redeliver otherwise below code is working fine , please help me what i am missing ?
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms-3.0.xsd">
<!-- Use Springs JNDI support to look up JMS Connection Factory and Queue definitions from the
container. This means that specific connection details are not embedded in the application
-->
<bean id="mqConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop">
<property name="connectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL">
<value>vm://localhost:61616</value>
</property>
<property name="nonBlockingRedelivery" value="true"/>
<property name="redeliveryPolicy">
<bean class="org.apache.activemq.RedeliveryPolicy">
<property name="initialRedeliveryDelay" value="5000" />
<property name="backOffMultiplier" value="2" />
<property name="queue" value="*" />
<property name="useExponentialBackOff" value="true" />
<property name="redeliveryDelay" value="5000" />
<property name="maximumRedeliveries" value="20"/>
</bean>
</property>
</bean>
</property>
</bean>
<bean id="mqProducerConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop">
<property name="connectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL">
<value>vm://localhost:61616</value>
</property>
</bean>
</property>
</bean>
<bean id="test_queue" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="test_queue" />
</bean>
<bean id="testConsumer" class="com.test.jms.listener.TestConsumer">
</bean>
<bean id="poiMessageListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref ="mqConnectionFactory" />
<property name="destination" ref ="test_queue"/>
<property name="messageListener" ref ="testConsumer"/>
<property name="concurrentConsumers" value="1" />
<property name="sessionTransacted" value="true"/>
</bean>
<bean id="testProducer" class="com.test.jms.producer.testProducer">
<property name="destination" ref="test_queue"/>
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="mqProducerConnectionFactory" />
</bean>
<jms:listener-container
container-type="default"
connection-factory="mqConnectionFactory"
acknowledge="transacted">
<jms:listener destination="test_queue" ref="testConsumer" method="onMessage" />
</jms:listener-container>
</beans>
Above code is working fine but it does not work for message re-delivery

Spring - JUnit - No bean named 'transactionManager' is defined

i get a NoSuchBeanDefinitionException - "No bean named 'transactionManager' is defined" with my configuration.
My configuration is running in case of normal webapp start.
JUnit Class
#RunWith(SpringJUnit4ClassRunner.class)
#TestExecutionListeners({ TransactionalTestExecutionListener.class, DependencyInjectionTestExecutionListener.class })
#ContextConfiguration(locations = {"classpath:**/applicationContext.xml", "classpath:**/datasource-config.xml"}) //,
#TransactionConfiguration(defaultRollback = true)
#Transactional
public class TestTripService {
TripService tripService;
#Test
public void addTrip() {
.
.
.
application-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans .......
spring-context-3.0.xsd">
<import resource="datasource-config.xml" />
<import resource="webflow-config.xml" />
<import resource="security-config.xml" />
<context:annotation-config/>
<context:component-scan base-package="de.wiegand.mytransport" />
<!-- DAO declarations -->
<bean id="userDao" class="de.wiegand.mytransport.dao.UserJpaDao" />
<bean id="shippingAgencyDao" class="de.wiegand.mytransport.dao.ShippingAgencyJplDao" />
<!-- Services declarations -->
<bean id="userService" class="de.wiegand.mytransport.services.impl.UserServiceImpl">
<property name="userDao" ref="userDao" />
<property name="shippingAgencyDao" ref="shippingAgencyDao" />
</bean>
<bean id="userAuthenticationProviderService"
class="de.wiegand.mytransport.services.impl.UserAuthenticationProviderServiceImpl">
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<bean id="tripService" class="de.wiegand.mytransport.services.impl.TripServiceImpl" />
<bean id="schedulerTask" class="org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean">
<property name="targetObject" ref="postCodeManager" />
<property name="targetMethod" value="init" />
</bean>
<bean id="postCodeManager" class="de.wiegand.mytransport.postcodeservice.PostCodeManager" />
<bean id="timerTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="timerTask" ref="schedulerTask" />
<property name="delay" value="1000" />
</bean>
<bean class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<ref local="timerTask" />
</list>
</property>
</bean>
datasource-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<context:property-placeholder location="classpath:datasource.properties" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/test2" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect" />
</bean>
</property>
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="dataSource" ref="dataSource" />
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
THX for your time.
Add below annotation to your testing class:
#TransactionConfiguration(transactionManager="txManager")
where txManager is the TranscationManager name defined in your Spring config file.

JMS queue with spring

My springcontext-notification XML:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd">
<bean
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="notificationJmsConnectionFactory" />
<property name="destinationName" value="${bpm.task.queue}" />
<property name="messageListener" ref="taskMessageReceiver" />
<property name="sessionTransacted" value="true" />
<property name="clientId" value="BPMTaskMessageLisetners" />
<property name="transactionManager" ref="transactionManager" />
<property name="maxConcurrentConsumers" value="${bpm.task.queue.listener.concurrency}" />
</bean>
<bean id="taskMessageReceiver"
class="com.sterling.ag.jms.impl.TaskMessageListenerImpl">
</bean>
<bean id="notificationJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="notificationJmsConnectionFactory" />
<property name="sessionTransacted" value="true" />
</bean>
<jee:jndi-lookup id="notificationJmsConnectionFactory"
jndi-name="java:/JmsXA">
<!--
<jee:environment>java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory</jee:environment>
-->
</jee:jndi-lookup>
<alias name="notificationJmsTemplate" alias="auditJmsTemplate" />
<alias name="notificationJmsTemplate" alias="historyExchangeJmsTemplate" />
</beans>
I have added another queue. How should i configure it in the above XML??
You need to create a separate container and listener
<bean
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="notificationJmsConnectionFactory" />
<property name="destinationName" value="${bpm.task.queue2}" />
<property name="messageListener" ref="taskMessageReceiver2" />
<property name="sessionTransacted" value="true" />
<property name="clientId" value="BPMTaskMessageLisetners" />
<property name="transactionManager" ref="transactionManager" />
<property name="maxConcurrentConsumers" value="${bpm.task.queue.listener.concurrency2}" />
</bean>
<bean id="taskMessageReceiver2"
class="com.sterling.ag.jms.impl.TaskMessageListenerImpl2">
</bean>

Resources