Unable to use exposed bean which uses RequiredAnnotationBeanPostProcessor - java

I am creating a war which is going to use a class from a jar file.
Now this jar file has a exposed a bean in its associationApplicationContext.xml which uses the #Required annotation on some of its properties for initialization.
associationApplicationContext.xml
e.g.
<!-- processes #Required annotations-->
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
<!-- The client bean to access the association rest web service -->
<bean id="associationClient" class="com.springtest.client.AssociationClientImpl">
<property name="associationRestClient" ref="associationServiceRestClient" />
</bean>
So inside the AssociationClient the property associationRestClient has #Required tag over its setter method.
#Required
public void setAssociationRestClient(final AssociationRestClient associationRestClient) {
this.associationRestClient= associationRestClient;
}
Now, as when I try to use this bean in my war file -
I have already put the jar dependency in pom.xml of war file
Already put the contextConfigLocation in web.xml as
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:/associationApplicationContext.xml
</param-value>
</context-param>
Using the bean from inside the war file in another applicationcontext.xml file as
<import resource="classpath:/associationApplicationContext.xml"/>
<bean id="requestHandlerV1"
class="com.springtest.application.RequestHandlerV1">
<property name="associationClient" ref="associationClient"></property>
</bean>
Here the property associationClient is not getting initialized because it is not able to find the reference to bean associationRestClient which is associationServiceRestClient
I am getting
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'associationServiceRestClient' is defined
How can I get the object of associationClient initialized here ?
PS : I cannot change the implementation which uses #Required annotation

Assuming you have the following:
In web.xml:
<!-root application context-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:associationApplicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>JerseySpringWebApplication</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationcontext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!--URl for web service -->
<servlet-mapping>
<servlet-name>JerseySpringWebApplication</servlet-name>
<url-pattern>/service/*</url-pattern>
</servlet-mapping>
You don't have to import the associationApplicationContext.xml in applicationcontext.xml as now the root application beans will be visible in applicationcontext.xml. So application Context.xml will be like:
<mvc:annotation-config/>
<bean id="requestHandlerV1" class="com.springtest.application.RequestHandlerV1">
<property name="associationClient" ref="associationClient"></property>
</bean>
*Assuming you are invoking the controller through rest call.
If you still see issue with this, post your log.

Related

Problem with replacing placeholders in xml configured in contextConfigLocation param

When I put placeholder in web.xml then it is correctly replaced by value defined in catalina.properties or -D param from vm options. But don't work when i put placeholder into xml which is loaded by ContextLoaderListener.
web.xml snippet:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
${placeholder}, <!-- WORKS -->
/WEB-INF/applicationContext.xml <!-- DON'T WORK, WHEN PLACEHOLDER IS DEFINED INSIDE XML -->
</param-value>
</context-param>
Problem solved. Xml defined in contextConfigLocation is loaded by spring and it is required to define bean from class org.springframework.beans.factory.config.PropertyPlaceholderConfigurer. Properties file can be empty. Values will be loaded from catalina.properties or vm options.
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath:example.properties</value>
</property>
</bean>

Externalize web.xml params in a Spring application

I have few parameters in web.xml file to be externalized. Application is in spring 4.0. Is there a spring way to do this?
More precisely, if I define PropertyPlaceholderConfigurer in context file, is there a way to use that for fetching properties in web.xml?
This is what I tried:
In applicationContext.xml:
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property
name="location"
value="classpath:/test.properties" />
<property
name="ignoreUnresolvablePlaceholders"
value="true" />
</bean>
Then in web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
</param-value>
</context-param>
But the below code returns param value as ${app.url}
<init-param>
<param-name>appUrl</param-name>
<param-value>${app.url}</param-value>
</init-param>
This is not possible as web.xml will be loaded before context initialization. The only solution for this is to move these properties to application server specific properties files.
I am using Tomcat and I moved this property to catalina.properties. Now it's working.

how i can tell glassfish about my spring dependancy injection?

I am new here, I am working on a project using hibernate and spring dependency injection and SOAP web service.
My problem is when I run my project in the console using this class:
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-beans.xml");
IServicesPharmacie pharmacieService = (IServicesPharmacie) context.getBean("service");
context.close();
Endpoint.publish("http://localhost:3597/Pharmacies", pharmacieService);
System.out.println("The service has been published with success!");
my project work fine, because with these 3 lines:
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-beans.xml");
IServicesPharmacie pharmacieService = (IServicesPharmacie) context.getBean("service");
context.close();
I can tell about my spring dependancy injection.
BUT i don't know how to run my project on a glassfish server, and tell him about my spring dependancy injection, I guess that I most have a web.xml!!!!
My spring-beans.xml is like that :
<bean class="dao.PharmImpl" id="dao"></bean>
<bean class="metier.PharMetier" id="metier">
<property name="phardao" ref="dao"></property>
</bean>
<bean class="services.ServicesPharmacie" id="service">
<property name="servmetier" ref="metier" />
</bean>
</beans>
You need to configure a ContextLoaderListener to bootstrap spring in your application. like below:
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
Perhaps if you are using springMVC its done as below:
<servlet>
<servlet-name>springServlet</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Please note URL-pattern is based on your requirement.

Wire an existing spring ApplicationContext to REST service with JAX-RS

I could start my application with REST endpoints exposed without problem.
However, I have another spring ApplicationContext created elsewhere and would like to be accessible from my REST endpoints.
Currently, I have to use a Singleton to lookup the beans. But is there a way to wire an existing ApplicationContext?
Below is what I have.
web.xml
<web-app>
<context-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>package1.MyJaxRsApplication</param-value>
</context-param>
<listener>
<listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
</listener>
<listener>
<listener-class>org.jboss.resteasy.plugins.spring.SpringContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>resteasy-servlet</servlet-name>
<servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>resteasy-servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
applicationContext.xml
<beans>
<context:component-scan base-package="package2.rest" />
</beans>
I think u will have to package your service interfaces as a separate jar and use it on other application. Together with that you will have to define service consuming spring configuration use it in you other application
<bean name="/ExposedService.htm" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
<property name="service" ref="exposedService"/>
<property name="serviceInterface" value="com.app.client.ExposedService"/>
</bean>

Initialize spring bean profile through ContextLoaderListener in web.xml

In my web.xml I'm declaring a ContextLoaderListener to configure spring application this way:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
In one of my spring configuration xml files, I'm using different beans profile for development and production.
<beans profile="production">
<bean />
</beans
<beans profile="development">
<bean />
</beans
How I could set the default beans profile in the web.xml? is there something similar to the following when using ContextLoaderListener instead of spring servlet:
<init-param>
<param-name>spring.profiles.active</param-name>
<param-value>production</param-value>
</init-param>
You can configure web.xml at the level of ContextLoaderListener with:
<context-param>
<param-name>spring.profiles.active</param-name>
<param-value>profileName</param-value>
</context-param>
and the level of DispatcherServlet with:
<init-param>
<param-name>spring.profiles.active</param-name>
<param-value>profileName</param-value>
</init-param>
Reference: http://spring.io/blog/2011/02/11/spring-framework-3-1-m1-released/

Categories