How to setup JMS configuration in Spring's applicationContext? - spring

How can I setup application for given below java code?
Hashtable<String, String> properties = new Hashtable<String, String>();
properties.put(Context.INITIAL_CONTEXT_FACTORY, "com.test.factory");
properties.put("com.domain", "DevelopmentDomain");
// properties.put(Context.PROVIDER_URL, "tcp://test:0506");
properties.put(Context.PROVIDER_URL, "tcp://10.00.0.00:0506");
properties.put(Context.SECURITY_PRINCIPAL, "aaa");
properties.put(Context.SECURITY_CREDENTIALS, "aaa");
javax.naming.Context context = new javax.naming.InitialContext(properties);
ConnectionFactory factory = (ConnectionFactory) context.lookup("ImpactPocQueueConnectionFactory");
Connection connection = factory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination queue = session.createQueue("test.producer");
I saw many examples here and there but none of them give complete picture.

If you want to translate this code literally to Spring configuration, consider taking advantage of #Configuration approach:
#Bean
public Destination queue() throws JMSException, NamingException {
return session().createQueue("test.producer");
}
#Bean
public Session session() throws JMSException, NamingException {
return connection().createSession(false, Session.AUTO_ACKNOWLEDGE);
}
#Bean(initMethod = "start")
public Connection connection() throws JMSException, NamingException {
return connectionFactory().createConnection();
}
#Bean
public ConnectionFactory connectionFactory() throws NamingException {
return (ConnectionFactory) context().lookup("ImpactPocQueueConnectionFactory");
}
#Bean
public Context context() throws NamingException {
return new javax.naming.InitialContext(properties());
}
#Bean
public Hashtable<String, String> properties() {
Hashtable<String, String> properties = new Hashtable<String, String>();
properties.put(Context.INITIAL_CONTEXT_FACTORY, "com.test.factory");
properties.put("com.domain", "DevelopmentDomain");
//properties.put(Context.PROVIDER_URL, "tcp://test:0506");
properties.put(Context.PROVIDER_URL, "tcp://10.00.0.00:0506");
properties.put(Context.SECURITY_PRINCIPAL, "aaa");
properties.put(Context.SECURITY_CREDENTIALS, "aaa");
return properties;
}
Technically you can do all of this using XML, but I found this approach much more readable and maintainable. Now you have connectionFactory and queue beans available in scope. You can easily integrate with Spring JMS support. Let us know if you need further assitance.

Below given Spring applicationContext xml configuration is tested and working fine for me.
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">com.test.factory</prop>
<prop key="com.sonicsw.jndi.mfcontext.domain">DevelopmentDomain</prop>
<prop key="java.naming.provider.url">tcp://10.00.0.00:0506</prop>
<prop key="java.naming.security.principal">aaa</prop>
<prop key="java.naming.security.credentials">aaa</prop>
</props>
</property>
</bean>
<bean id="jmsQueueConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate" ref="jndiTemplate"/>
<property name="jndiName" value="ImpactPocQueueConnectionFactory"/>
</bean>
<bean id="sonic" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory" ref="jmsQueueConnectionFactory"/>
</bean>
<route>
<from uri="seda:something"/>
<to uri="sonic:queue:queueName"/>
</route>

Related

How to convert XML configuration to Java configuration?

I want to convert this XML configuration to Java but I'm some having trouble finding the correct way to do it..
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject">
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass" value="java.lang.System"/>
<property name="targetMethod" value="getProperties"/>
</bean>
</property>
<property name="targetMethod" value="putAll"/>
<property name="arguments">
<util:properties>
<prop key="key1">value1</prop>
<prop key="key2">value2</prop>
<prop key="key3">value3</prop>
<prop key="key4">value4</prop>
<prop key="key5">value5</prop>
</util:properties>
</property>
</bean>
It is almost working fine but I get an error about the putAll method. It should be called on the Properties object but with my Java config (see below) it tries to call it on the MethodInvokingFactoryBean object.
#Bean
public MethodInvokingFactoryBean getMethodInvokingFactoryBean() throws IOException {
final MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean();
final MethodInvokingFactoryBean target = new MethodInvokingFactoryBean();
target.setTargetClass(System.class);
target.setTargetMethod("getProperties");
methodInvokingFactoryBean.setTargetObject(target);
methodInvokingFactoryBean.setTargetMethod("putAll");
final Properties properties = new Properties();
properties.put("key1", "value1");
properties.put("key2", "value2");
properties.put("key3", "value3");
properties.put("key4", "value4");
properties.put("key5", "value5");
final PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setProperties(properties);
methodInvokingFactoryBean.setArguments(propertiesFactoryBean);
return methodInvokingFactoryBean;
}
So the error I'm getting now is:
java.lang.NoSuchMethodException: org.springframework.beans.factory.config.MethodInvokingFactoryBean.putAll(org.springframework.beans.factory.config.PropertiesFactoryBean) because the putAll should be called on the Properties object.. what am I doing wrong here?
I'm might misunderstand what you want to do, but can it be done bye the following in the setup for your application?
Map<String, String> map = new HashMap<>();
map.put("key1", "value1");
map.put("key2", "value2");
map.put("key3", "value3");
map.put("key4", "value4");
map.put("key5", "value5");
java.lang.System.getProperties().putAll(map);

How to use HikariCP with JdbcTemplate in Springs MVC 4

I am new to Springs MVC and I tried to integrate HikariCP with JdbcTemplate. But got lot of errors any help, how to point JdbcTemplate to HikariCP DataSource.
in applicationContext.xml
<bean id="dataSource" class="com.zaxxer.hikari.HikariConfig">
<property name="poolName" value="springHikariCP" />
<property name="connectionTestQuery" value="SELECT 1" />
<property name="dataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" />
<property name="dataSourceProperties">
<props>
<prop key="url">${jdbc.url}</prop>
<prop key="user">${jdbc.username}</prop>
<prop key="password">${jdbc.password}</prop>
</props>
</property>
</bean>
<bean id="jdbcTemplate" class="com.zaxxer.hikari.HikariDataSource" destroy- method="close">
<property name="dataSource" ref="dataSource"></property>
</bean>
And in controller:
Controller
public class HandleWareHouse{
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource){
this.dataSource = dataSource;
}
#RequestMapping(value="/saveProduct_categories", method = RequestMethod.POST)
#ResponseBody
public String insertPc(#RequestParam Map<String,String> requestParams){
jdbcTemplate = new JdbcTemplate(dataSource);
String sql = "INSERT INTO product_categories(name,code,des,grp_name) VALUES(?,?,?,?)";
jdbcTemplate.update(sql, new Object[] {requestParams.get("pname"),requestParams.get("pcode"),requestParams.get("stext"),requestParams.get("pcategory")});
return "sucess";
}
}
But getting error as shown below:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jdbcTemplate' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'com.zaxxer.hikari.HikariConfig' to required type 'javax.sql.DataSource' for property 'dataSource'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [com.zaxxer.hikari.HikariConfig] to required type [javax.sql.DataSource] for property 'dataSource': no matching editors or conversion strategy found
I have used spring javaconfig to configure datasource and getting jdbctemplate. I think this is the best
#Bean
public DataSource getDataSource() {
private HikariDataSource dataSource() {
final HikariDataSource ds = new HikariDataSource();
ds.setMaximumPoolSize(100);
ds.setDriverClassName("oracle.jdbc.driver.OracleDriver");
ds.setJdbcUrl("jdbc:oracle:thin:#localhost:1521:XE"); ;
ds.setUsername("username");
ds.setPassword("password");
return ds;
}
}
#Bean
public JdbcTemplate getJdbcTemplate() {
return new JdbcTemplate(getDataSource());
}
I hope this works well to you.

No transactional EntityManager available Error

I have a below spring setup. Basically I am trying to configure two transaction managers here. One with hibernate and other with JPA. But somehow when I try to run JPA transaction manager, there I get "javax.persistence.TransactionRequiredException: No transactional EntityManager available" error. Appreciate if somebody finds the problem in below code.
data-context.xml file as below
<bean id="fundBO" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces" value="com.test.FundBo"/>
<property name="interceptorNames">
<list>
<idref bean="transactionInterceptor"/>
<idref bean="fundBOTarget"/>
</list>
</property>
</bean>
<bean id="fundBOTarget" class="com.test.FundBoImpl" />
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager">
<bean class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
</property>
</bean>
And AppConfig as Below.
#Configuration
#EnableWebMvc
#EnableTransactionManagement
#ComponentScan(basePackages = {"com.test.**"})
#ImportResource("classpath:data-context.xml")
public class AppConfig {
#Resource
DataSource dataSource;
#Bean
public JpaTransactionManager jpaTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
transactionManager.setJpaDialect(new HibernateJpaDialect());
transactionManager.setNestedTransactionAllowed(true);
transactionManager.afterPropertiesSet();
return transactionManager;
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setPersistenceProviderClass(HibernatePersistence.class);
factoryBean.setPackagesToScan("com.test.**");
factoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
Properties jpaProperties = new Properties();
jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.SQLServerDialect");
jpaProperties.put("hibernate.jdbc.batch_size", "20");
jpaProperties.put("hibernate.show_sql", "false");
jpaProperties.put("hibernate.hbm2ddl.auto", "validate");
jpaProperties.put("hibernate.autoReconnect", "true");
jpaProperties.put("hibernate.autoReconnectForPools", "true");
jpaProperties.put("hibernate.is-connection-validation-required", "true");
factoryBean.setJpaProperties(jpaProperties);
factoryBean.afterPropertiesSet();
return factoryBean;
}
}

why does mailSender always get as a null? spring/jsf

I tried to send mail with spring in managedbean(jsf).But I get a nullpointer exception.
MailServiceImpl.class
#Service("MailService")
public class MailServiceImpl implements MailService, Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Autowired
private JavaMailSender mailSender;
#Autowired
private SimpleMailMessage alertMailMessage;
Logger log = Logger.getLogger(getClass());
#Override
public void sendMail(String from, String to, String subject, String body) {
try {
final SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(from);
message.setTo(to);
message.setSubject(subject);
message.setText(body);
if (mailSender != null) {
mailSender.send(message);
} else {
log.info("mailSender is null." + mailSender);
}
} catch (final MailException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void sendAlertMail(String alert) {
final SimpleMailMessage mailMessage = new SimpleMailMessage(
alertMailMessage);
mailMessage.setText(alert);
mailSender.send(mailMessage);
}
public JavaMailSender getMailSender() {
return mailSender;
}
public void setMailSender(JavaMailSender mailSender) {
this.mailSender = mailSender;
}
}
\WEB-INF\application-context.xml
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="port" value="587" />
<property name="host" value="smtp.mail.yahoo.com" />
<property name="username" value="my#yahoo.com" />
<property name="password" value="mypassword" />
<property name="javaMailProperties">
<props>
<prop key="mail.transport.protocol">smtp</prop>
<prop key="mail.smtp.auth">true</prop>
<prop key="mail.smtp.starttls.enable">true</prop>
<prop key="mail.debug">true</prop>
</props>
</property>
</bean>
<bean id="alertMailMessage" class="org.springframework.mail.SimpleMailMessage">
<property name="from">
<value>my#yahoo.com</value>
</property>
<property name="to">
<value>my#yahoo.com</value>
</property>
<property name="subject"
value="Alert - Exception occurred. Please investigate" />
</bean>
<bean id="MailService" class="spring.service.MailServiceImpl">
<property name="mailSender" ref="mailSender"></property>
</bean>
ManagedBean.class
#ManagedProperty(value = "#{MailService}")
MailServiceImpl mailServiceImpl;
public void sendingEmail() {
mailServiceImpl.sendMail("my#yahoo.com", "my#yahoo.com",
"Hi look at me!", "Bla bla bla..");
}
pom.xml
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.3</version>
</dependency>
and web.xml for application-context.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/application-context.xml
/WEB-INF/security-context.xml
</param-value>
</context-param>
mailSender always gets as a null.Why?How can I send an email properly?Thanks in advance.
I suspect in this case in the JSF bean you get an instance of the MailServiceImpl injected, which was created by the CDI container (or maybe JSF itself) and not Spring, so the fields in the object are null (obviously, because the CDI container doesn't know anything about Spring annotations).
If you want to inject Spring beans in a JSF managed bean, you have to put the following snippet in the faces-config class:
<application>
<el-resolver>
org.springframework.web.jsf.el.SpringBeanFacesELResolver
</el-resolver>
</application>

No bean named 'errorNotifier' is defined

I'm trying to setup a bean factory in spring, something which should be really simple to do, but I just can't figure out why it's not working. Spend most of today looking at examples, reading other similar posts on stackOverflow, reading Spring In Action as well as Spring Recipes with no success so far. A second pair of eyes will probably pick up my mistake in no time.
Error Notifier Interface
public interface ErrorNotifier {
public void notifyCopyError(String srcDir, String destDir, String filename);
}
Error Notifier Implementation
public class EmailErrorNotifier implements ErrorNotifier {
private MailSender mailSender;
/**
* Blank constructor
*/
public EmailErrorNotifier() {
}
public void setMailSender(MailSender mailSender) {
this.mailSender = mailSender;
}
#Override
public void notifyCopyError(String srcDir, String destDir, String filename) {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom("system#localhost");
message.setTo("admin#localhost");
message.setSubject("Finished Uploading File");
message.setText("Your upload failed!");
mailSender.send(message);
}
}
My config in applicationContext.xml
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="${email.host}"/>
<property name="protocol" value="${email.protocol}"/>
<property name="port" value="${email.port}"/>
<property name="username" value="${email.username}"/>
<property name="password" value="${email.password}"/>
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.auth">true</prop>
<prop key="mail.smtp.starttls.enable">true</prop>
</props>
</property>
</bean>
<bean id="errorNotifier" name="errorNotifier" class="com.bdw.controller.EmailErrorNotifier">
<property name="mailSender" ref="mailSender"/>
</bean>
And the class in which I test it
public class test {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext(
ApplicationContext.CLASSPATH_ALL_URL_PREFIX
+ "applicationContext.xml");
ErrorNotifier notifier =
context.getBean("errorNotifier", ErrorNotifier.class);
notifier.notifyCopyError("test", "test", "test");
}
}
I don't get any errors in tomcat or glassfish logs, just this output:
Exception in thread "main"
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
bean named 'errorNotifier' is defined at
org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:527)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1083)
at
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:274)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at
org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1079)
at test.main(test.java:21)
If I change context.getBean parameter to lookup mailSender, I get No bean named 'mailSender'.
Any ideas?
The applicationContext file is likely not on the class path; I'm not sure that the all_URL_prefix will dig past the root level of the filesystem and jars, making the test go wonky. Try moving the config file, or changing the list of locations from which to grab the config file.

Resources