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

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>

Related

Table not auto create in HeidiSql(mysql) by spring hibernate. And no error shows in console but jdbc details missing, my code details given below

Table not auto create in HeidiSql(mysql) by spring hibernate. And no error shows in console but jdbc details missing, my code details given below
Model class
my entity java class
#Entity
#Table(name = "Payment_Table")
public class Payment implements Serializable {
private static final long serialVersionUID = 4501753715497967062L;
#Id
#GeneratedValue
private int id;
private String transactionId;
private String vendor;
private Date paymentDate;
private double amount;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTransactionId() {
return transactionId;
}
public void setTransactionId(String transactionId) {
this.transactionId = transactionId;
}
public String getVendor() {
return vendor;
}
public void setVendor(String vendor) {
this.vendor = vendor;
}
public Date getPaymentDate() {
return paymentDate;
}
public void setPaymentDate(Date paymentDate) {
this.paymentDate = paymentDate;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
public Payment() {
super();
// TODO Auto-generated constructor stub
}
public Payment(String transactionId, String vendor, Date paymentDate, double amount) {
super();
this.transactionId = transactionId;
this.vendor = vendor;
this.paymentDate = paymentDate;
this.amount = amount;
}
}
application-context.xml
my data base configuration
<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/test" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.spring.rest.curd.model.Payment</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernet.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
web.xml
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/application-context.xml</param-value>
</context-param>
<display-name>Spring Rest Application</display-name>
<servlet>
<servlet-name>springRest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springRest</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
springRest-servlet.xml
<context:component-scan base-package="com.spring.rest.curd.*"></context:component-scan>
<mvc:annotation-driven />
<tx:annotation-driven />

Swaks (Swiss Army Knife for SMTP) can send, but Spring Java cannot send mail

I am developing a service in Spring and I can send email when I am running this same app from my development machine, but when I deploy it to a server it does not work.
I checked from the server with Swaks and it also works from command line but it's not working from Spring.
Here is the Spring configuration:
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="my-domain.tld"/>
<property name="port" value="587"/>
<property name="username" value="myemail#my-domain.tld"/>
<property name="password" value="mypassword"/>
<property name="defaultEncoding" value="UTF-8"/>
<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>
It stops after this line(from log file)
STARTTLS
220 2.0.0 Ready to start TLS
Here is the code to send email
#Component
public class EmailProvider {
#Autowired
private JavaMailSender mailSender;
#Async
public void sendEmail(final String to, final String subject, final String body, final String cc, final String bcc, final boolean html) {
if (StringUtils.isEmpty(to) || StringUtils.isEmpty(subject) || StringUtils.isEmpty(body)) {
return;
}
MimeMessagePreparator message = new MimeMessagePreparator() {
#Override
public void prepare(MimeMessage mmsg) throws Exception {
MimeMessageHelper mm = new MimeMessageHelper(mmsg);
mm.setTo(new InternetAddress(to));
mm.setSubject(subject);
mm.setFrom("from#my-domain.tld");
if (StringUtils.isNotEmpty(cc)) {
mm.setCc(cc);
}
if (StringUtils.isNotEmpty(bcc)) {
mm.setBcc(bcc);
}
mm.setText(body, html);
}
};
mailSender.send(message);
}
}
Thanks in advance.

Java Mail dont work when executed from bean

Here is my #Service class whose remind() method is called from the front-end.
#Service
public class EmailManagerImpl implements EmailManager {
private MailSender mailSender;
private SimpleMailMessage templateMessage;
public void setMailSender(MailSender mailSender) {
this.mailSender = mailSender;
}
public void setTemplateMessage(SimpleMailMessage templateMessage) {
this.templateMessage = templateMessage;
}
#Override
public void remind(Appointment appointment) {
Person patient = appointment.getPatient();
SimpleMailMessage msg = new SimpleMailMessage(this.templateMessage);
msg.setTo(patient.getMail());
msg.setText("Szanowny pacjencie " + patient.getFirstName() + " "
+ patient.getSurname() + " "
+ appointment.toString());
try {
mailSender.send(msg);
} catch (MailException ex) {
// log it and go on
System.err.println(ex.getMessage());
}
}
I am sure that templeMessage and mailSender are injected correctly. After whole process is executed i dont get any error, no exception no debugging info from true. When i try to run one of many demos, it works just fine. The only diffrence is that my application is on Tomcat + i invoke method from bean. Any ideas?
I can follow debug up to the following method from SimpleMailMessage line, later i get message that source is not found:
//---------------------------------------------------------------------
// Implementation of MailSender
//---------------------------------------------------------------------
public void send(SimpleMailMessage simpleMessage) throws MailException {
send(new SimpleMailMessage[] { simpleMessage });
}
My applicationConfig:
<!-- Wysylanie maili -->
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="${mail.host}" />
<property name="port" value="${mail.port}" />
<property name="username" value="${mail.username}" />
<property name="password" value="${mail.password}" />
<property name="protocol" value="smtp" />
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.ssl.trust">smtp.gmail.com</prop>
<prop key="mail.smtp.auth">true</prop>
<prop key="mail.smtp.starttls.enable">true</prop>
<prop key="mail.smtps.debug">true</prop>
</props>
</property>
</bean>
<!-- this is a template message that we can pre-load with default state -->
<bean id="templateMessage" class="org.springframework.mail.SimpleMailMessage">
<property name="from" value="${mail.username}" />
<property name="subject" value="${mail.subject}" />
</bean>
<bean id="emailManagerImpl" class="com.przychodnia.rejestracja.integration.EmailManagerImpl">
<property name="mailSender"><ref bean="mailSender"/></property>
<property name="templateMessage"><ref bean="templateMessage"/></property>
</bean>

"No Session found for current thread" when adding #Autowire

I've seen several similar questions, but none of the suggested solutions helped me.
Summary: when I create and inject the beans on the .xml, it works; but when I use #Autowire or #Resource, it doesn't.
Environment: Spring3, Hibernate4, Tomcat7.
Details: the following setup DOES work:
web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/root-context.xml
/WEB-INF/spring/security-context.xml
/WEB-INF/spring/users-context.xml
</param-value>
</context-param>
root-context.xml:
<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/venus" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.airbus.genesis.marte.dal" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<tx:annotation-driven transaction-manager="txManager" />
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
users-context.xml:
<bean id="usersDAO" class="com.airbus.genesis.marte.dal.users.UsersDAO">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
BL object:
#Service("usersManager")
#Transactional(readOnly = true)
public class UsersManager implements IUsersManager {
#Autowired
#Qualifier("usersDAO")
private IUsersDAO usersDAO;
#Override
public List<User> getUsers() {
return usersDAO.getUsers();
}
}
DAO object (notice that #Repository and #Resource are commented):
//#Repository("usersDAO")
#Transactional(readOnly = true)
public class UsersDAO implements IUsersDAO {
// #Resource(name = "sessionFactory")
private SessionFactory sessionFactory;
#Override
public List<User> getUsers() {
#SuppressWarnings("unchecked")
List<User> res = (List<User>) getSessionFactory().getCurrentSession()
.createQuery("from User").list();
return res;
}
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
}
But the following one DOES NOT work:
users-context.xml:
<!--
<bean id="usersDAO" class="com.airbus.genesis.marte.dal.users.UsersDAO">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
-->
DAO object (notice that #Repository and #Resource are uncommented now):
#Repository("usersDAO")
#Transactional(readOnly = true)
public class UsersDAO implements IUsersDAO {
#Resource(name = "sessionFactory")
private SessionFactory sessionFactory;
#Override
public List<User> getUsers() {
#SuppressWarnings("unchecked")
List<User> res = (List<User>) getSessionFactory().getCurrentSession()
.createQuery("from User").list();
return res;
}
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
}
org.hibernate.HibernateException: No Session found for current thread is raised:
org.hibernate.HibernateException: No Session found for current thread
org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:941)
com.airbus.genesis.marte.dal.users.UsersDAO.getUsers(UsersDAO.java:23)
com.airbus.genesis.marte.bl.users.UsersManager.getUsers(UsersManager.java:22)
[...]
The same happens if I use #Autowire instead of #Resource.
I guess it is some kind of misunderstanding on my side, but cannot find where. Any idea?
The problem is likely that #Repository and #Service annotations are being picked up in the dispatcher-servlet.xml configuration (do you use context:component-scan?), so these beans are created in the dispatcher servlet context instead of the root web app context.
A good practice is to put your service layer objects to the dedicated packages and use the specific package name as <context:component-scan/> base-package qualifier (like 'com.myproject.services'). You can also use filter expressions to include and exclude elements see examples here : #Service are constructed twice
and 4.10.3 section of the Spring documentation
See also Difference between applicationContext.xml and spring-servlet.xml in Spring Framework

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