JMS implementation using JNDI in spring application - spring

I am trying to implement JMS in my spring application. I have defined the JNDI name + queue name in applicationContext.xml as follows:
<bean id="emailQueueConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean" lazy-init="true">
<property name="jndiName" value="java:comp/env/jms/<<Name of JNDI of connection factory>>" />
</bean>
<bean id="emailQueueDestination" class="org.springframework`enter code here`.jndi.JndiObjectFactoryBean" lazy-init="true">
<property name="jndiName" value="java:comp/env/jms/<<JNDI name of queue>>" />
</bean>
<bean id="emailQueueTemplate" class="org.springframework.jms.core.JmsTemplate" lazy-init="true">
<property name="connectionFactory" ref="emailQueueConnectionFactory" />
<property name="defaultDestination" ref="emailQueueDestination" />
</bean>
<bean id="emailSender" class="<<Package>>.EmailSender" lazy-init="true">
<property name="jmsTemplate">
<ref bean="emailQueueTemplate" />
</property>
</bean>
Now my controller makes a call to the emailSender bean using the following code:
ApplicationContext context = new ClassPathXmlApplicationContext("/applicationContext.xml");
EmailSender sender =(EmailSender)context.getBean("emailSender");
The exception I get is: Error 404: Request processing failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [applicationContext.xml]; nested exception is java.io.FileNotFoundException: class path resource [applicationContext.xml] cannot be opened because it does not exist
I am loading the applicationContext.xml at serevr start-up still my code is not able to locate this file.
Can anyone please help.??

make sure your applicationContext.xml file is in your class path then add the class path prefix, You can try some thing like this
ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:applicationContext.xml");

Related

Unable to locate a ejb in spring context

I am trying to use a EJB singleton bean inside of spring bean but somehow it unable to locate a this ejb and getting a message when run a server:
SEVERE: Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'authenticationFailureHandler' defined in class path resource [spring-security-config.xml]: Cannot resolve reference to bean 'loginAttemptService' while setting bean property 'loginAttemptService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'loginAttemptService' is defined
Here is a EJB:
public interface ILoginAttemptService {
public boolean checkout(String username);
}
Here is implementation:
#Slf4j
#Stateless(name = "loginAttemptService")
#Singleton
public class LoginAttemptsService implements ILoginAttemptService {
..
}
In spring framework this is how i define a stateless bean:
<bean id="loginAttemptServiceBean"
class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean">
<property name="jndiName"
value="java:app/osloproject-ejb/loginAttemptService"/>
<property name="businessInterface"
value="com.hospitality.hp.securitycommons.api.ILoginAttemptService"/>
</bean>
<bean id="authSuccessHandler"
class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<property name="redirectStrategy">
<bean class="com.hospitality.hp.securitycommons.tools.spring.CORSCompatibleTwoFactorAuthenticationRedirectStrategy">
<property name="loginAttemptService" ref="loginAttemptServiceBean"/>
</bean>
</property>
</bean>
<bean id="authenticationFailureHandler"
class="com.hospitality.hp.securitycommons.tools.spring.AuthenticationFailureCustomHandler">
<property name="useForward" value="true"/>
<property name="defaultFailureUrl" value="/login.jsp"/>
<property name="loginAttemptService" ref="loginAttemptServiceBean"/>
</bean>
Can someone tell me why it unable to find the JNDI name of this EJB ?
try
<jee:local-slsb id="loginAttemptServiceBean" jndi-name="java:app/osloproject-ejb/loginAttemptService"
business-interface="com.hospitality.hp.securitycommons.api.ILoginAttemptService"/>
"jee" is Spring’s namespace.and also check the jndi-name value is correct

Spring Social applicationURL setup exception

For Spring Social version 1.1.0.RELEASE, I need to set up the applicationUrl for the ProviderSignInController, as my application (a Tomcat app) is hosted behind a proxy (Apache web server). According the Spring Social document, I set it up as below:
<bean id="providerSignInController"
class="org.springframework.social.connect.web.ProviderSignInController">
<property name="signInUrl" value="/accounts/login" />
<property name="signUpUrl" value="/accounts/signup" />
<property name="postSignInUrl" value="/accounts/profile" />
<property name="applicationUrl" value="${applicationUrl}" />
</bean>
However, when deploying the application, I get an exception in Tomcat catalina.out saying:
PropertyAccessException 1:
org.springframework.beans.MethodInvocationException: Property
'applicationUrl' threw exception; nested exception is
java.lang.NullPointerException>org.springframework.beans.factory.BeanCreationException:
Error creating bean with name
'org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping#0'
defined in ServletContext resource [/WEB-INF/spring-servlet.xml]:
Initialization of bean failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Error creating
bean with name 'providerSignInController' defined in ServletContext
resource [/WEB-INF/spring-servlet.xml]: Error setting property values;
nested exception is
org.springframework.beans.PropertyBatchUpdateException; nested
PropertyAccessExceptions (1) are:
PropertyAccessException 1:
org.springframework.beans.MethodInvocationException: Property
'applicationUrl' threw exception; nested exception is
java.lang.NullPointerException
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
Any suggestions please? Thanks.
It should be a bug with class ProviderSignInController in Spring Social version 1.1.0.RELEASE. In class ProviderSignInController, connectSupport is created after properties being set:
public void afterPropertiesSet() throws Exception {
this.connectSupport = new ConnectSupport(sessionStrategy);
this.connectSupport.setUseAuthenticateUrl(true);
};
Therefore when method setApplicationUrl is invoked, connectSupport is still null.
Now when I configure it in the way shown below, it works. Or if I revert to version 1.0.3.RELEASE, it works fine too.
<bean id="providerSignInController"
class="org.springframework.social.connect.web.ProviderSignInController">
<property name="signInUrl" value="/accounts/login" />
<property name="signUpUrl" value="/accounts/signup" />
<property name="postSignInUrl" value="/accounts/profile" />
</bean>
<bean
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="providerSignInController" />
<property name="targetMethod" value="setApplicationUrl" />
<property name="arguments">
<list>
<bean class="java.lang.String">
<constructor-arg value="${applicationUrl}" />
</bean>
</list>
</property>
</bean>
Follow-up
This problem has been resolved in Spring Social version 1.1.3.RELEASE. In class ProviderSignInController, method afterPropertiesSet has been updated to:
public void afterPropertiesSet() throws Exception {
this.connectSupport = new ConnectSupport(sessionStrategy);
this.connectSupport.setUseAuthenticateUrl(true);
if (this.applicationUrl != null) {
this.connectSupport.setApplicationUrl(applicationUrl);
}
};
As a result, the workaround of configuration given above (by the way, would not work with Spring Social version 1.1.3.RELEASE any more) can now be simplified to:
<bean id="providerSignInController"
class="org.springframework.social.connect.web.ProviderSignInController">
<property name="signInUrl" value="/accounts/login" />
<property name="signUpUrl" value="/accounts/signup" />
<property name="postSignInUrl" value="/accounts/profile" />
<property name="applicationUrl" value="${applicationUrl}" />
</bean>

Multiple SharedEntityManagerBeans and ApplicationContext.getBean issue

I have two databases which I want to access from my Spring application. I configured two SharedEntityManagerBean for both databases. Here is the config:
<jpa:repositories base-package="xxx" entity-manager-factory-ref="entityManagerFactory1" />
<jpa:repositories base-package="xxx" entity-manager-factory-ref="entityManagerFactory2" />
<tx:annotation-driven/>
<bean class="org.springframework.orm.jpa.JpaTransactionManager"
id="transactionManager1">
<property name="entityManagerFactory" ref="entityManagerFactory1" />
<property name="dataSource" ref="dataSource1" />
</bean>
<bean class="org.springframework.orm.jpa.JpaTransactionManager"
id="transactionManager2">
<property name="entityManagerFactory" ref="entityManagerFactory2" />
<property name="dataSource" ref="dataSource2" />
</bean>
<bean id="entityManagerFactory1"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:packagesToScan="xxxxxx"
....
</bean>
<bean id="entityManagerFactory2"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:packagesToScan="xxxxx"
...
</bean>
<bean id="entityManager1" class="org.springframework.orm.jpa.support.SharedEntityManagerBean" >
<property name="entityManagerFactory" ref="entityManagerFactory1" />
</bean>
<bean id="entityManager2" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="entityManagerFactory" ref="entityManagerFactory2" />
</bean>
<bean id="dataSource1"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
...
</bean>
<bean id="dataSourceOntology"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
...
</bean>
I have two EntityLocators which are not managed by Spring that access entities in each of the corresponding databases. They look something like that:
public class SpringEntitiyLocator1 {
private EntityManager em;
public SpringEntitiyLocator1() {
}
private EntityManager getEM() {
if (em == null) {
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(RequestFactoryServlet.getThreadLocalServletContext());
SharedEntityManagerBean bean = context.getBean("entityManager1",SharedEntityManagerBean.class);
em = bean.getObject();
}
return em;
}
}
When I have only one SharedEntityManagerBean defined in my applicationContext the call to getBean() works fine. However once I have both SharedEntityManagerBeans defined I get the error:
Bean named 'x' must be of type [y], but was actually of type [$Proxy]
I read on SO that I should use cglib proxying by adding <aop:config proxy-target-class="true"/> to my application.xml.
Is that the best solution ?
When I add that line I get Caused by: java.lang.NoClassDefFoundError: org/aspectj/util/PartialOrder$PartialComparable errors.
Do I need aspectj for that?
EDIT:
In case I have only one SharedEntityManagerBean defined I can call getBean(SharedEntityManagerBean.class). This works fine.
I debugged the code and it seems that this call will call getBean("&entityManager1",SharedEntityManagerBean.class) (note &) .
However when I pass the name getBean("EntityManager1",SharedEntityManagerBean.class) I get a type cast exception.
Having both SharedEntityManagerBeans defined and call getBean without a name also causes an exception (can't find a bean with that name).
So my current workaround is to call: getBean("&entityManager1",SharedEntityManagerBean.class) and getBean("&entityManager2",SharedEntityManagerBean.class)
This works fine.
Ok apparently SharedEntityManagerBean is a FactoryBean and for that I have to add & before the bean name to retrieve the SharedEntityManagerBean.
Alternatively I could probably just call:
em = context.getBean("entityManager",EntityManager.class);
See here and here for reference.

Defining MessageSource and LocaleResolver beans in Spring MVC for adding i18n support

I'm trying to add i18n support to a Spring MVC project(3.2.0.RELEASE). I have two bundles below /src/main/resources/bundle:
messageBundle_en.properties
messageBundle_vi.properties
And the configurations for spring mvc as below:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="cache" value="false" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<bean class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:bundle/messageBundle" />
</bean>
<bean class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="vi" />
</bean>
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
</mvc:interceptors>
with above configurations the application is not working. The error was
org.apache.jasper.JasperException: javax.servlet.ServletException: javax.servlet.jsp.JspTagException: No message found under code 'message.home.header.welcome' for locale 'en_US'.
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:549)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:455)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238)
I spent many hours comparing with tutorials of adding i18n support. I saw that there is only one difference: bean definitions of CookieLocaleResolver and ReloadableResourceBundleMessageSource have id attributes. So I changed the configurations to
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:bundle/messageBundle" />
</bean>
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="vi" />
</bean>
Now it's working well!
Do ReloadableResourceBundleMessageSource and CookieLocaleResolver require to have ids in their definitions?
Why doesn't InternalResourceViewResolver need an id?
Wondering if anyone can give me an explanation in details.
DispatcherServlet.java
public static final String LOCALE_RESOLVER_BEAN_NAME = "localeResolver";
private void initLocaleResolver(ApplicationContext context) {
try {
this.localeResolver = context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleResolver.class);
if (logger.isDebugEnabled()) {
logger.debug("Using LocaleResolver [" + this.localeResolver + "]");
}
}
catch (NoSuchBeanDefinitionException ex) {
// We need to use the default.
this.localeResolver = getDefaultStrategy(context, LocaleResolver.class);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate LocaleResolver with name '" + LOCALE_RESOLVER_BEAN_NAME +
"': using default [" + this.localeResolver + "]");
}
}
}
Spring uses some conventional bean name to intialize DispatcherServlet.
In your case, spring will use a default one if no bean named "localeResolver" is found (therefore your custom LocaleResover is ignored).
UPDATE
In messageSource case,
"When an ApplicationContext is loaded, it automatically
searches for a MessageSource bean defined in the context. The
bean must have the name messageSource. If such a bean is found, all
calls to the preceding methods are delegated to the message source. If
no message source is found, the ApplicationContext attempts to find a
parent containing a bean with the same name. If it does, it uses that
bean as the MessageSource. If the ApplicationContext cannot find any
source for messages, an empty DelegatingMessageSource is instantiated
in order to be able to accept calls to the methods defined above."
quoted from spring doc.

#Resource dataSource mappedName - overriding to test in non JNDI env

I have an existing service bean which we deployed in Jboss. Unfortunatly it's dataSource reference is configured to inject the datasource reference via the "mappedName" lookup of the JNDI Service.
#Resource(name = "dataSource", mappedName = "java:/OracleDS")
private DataSource dataSource = null;
I want to test the bean in a non JNDI env. I expected to get this exception when i run in a non JNDI env.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating
bean with name 'myService': Injection of resource fields failed; nested exception
is org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean
definition with name 'java:/OracleDS' defined in JNDI environment: JNDI lookup
failed; nested exception is javax.naming.NoInitialContextException: Need to
specify class name in environment or system property, or as an applet parameter,
or in an application resource file: java.naming.factory.initial
I realise the quickest way to fix this is to dropped the mappedName restriction, since then the production or test spring context can define the datasource. But in the case that i can't do this. Is there a way to define an InitialContext via a test spring context to avoid the exception above.
I did some more reading on SimpleNamingContextBuilder and came up with this context setup for my test case. The trick being to use the MethodInvokingFactoryBean to ensure the bind() method is called.
<bean id="jndiContext" class="org.springframework.mock.jndi.SimpleNamingContextBuilder" factory-method="emptyActivatedContextBuilder"/>
<bean id="invokingFactoryBean"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject">
<ref local="jndiContext" />
</property>
<property name="targetMethod">
<value>bind</value>
</property>
<property name="arguments">
<list>
<value>java:/OracleDS</value>
<ref bean="dataSource" />
</list>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${datasource.driverClassName}" />
<property name="url" value="${datasource.url}" />
<property name="username" value="${datasource.username}" />
<property name="password" value="${datasource.password}" />
</bean>

Resources