I have a very simple project setup.
Spring 4.14
Jersey 2.15
Web.xml
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.talentera</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
For some reason, #Autowired not working or the beans are not being scanned.
Below is my project setup:
Below is the spring configuration:
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:p="http://www.springframework.org/schema/p"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.2.xsd">
<context:annotation-config />
<context:component-scan base-package="com.talentera">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Component" />
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Service" />
</context:component-scan>
Below is the usage:
#Component
#Path("/user")
#Scope("request")
public class UserRestService extends BaseAPIService{
#Autowired
UserManagementService userManagementService;
protected static final Log logger = LogFactory.getLog( UserRestService.class.getName() );
EmailFormatValidator emailValidator = new EmailFormatValidator();
public UserManagementService getUserManagementService() {
return userManagementService;
}
public void setUserManagementService(UserManagementService userManagementService) {
this.userManagementService = userManagementService;
}
#GET
#Path("/get/{userId}")
#Produces(MediaType.APPLICATION_JSON)
public String getUser(#PathParam("userId") Integer userId)
{
System.out.println(getSerRequest().getSession().getId());
User u = userManagementService.getUserById(userId);
response.setData(u);
return jsonStringifyResponse();
}
package com.talentera.common.service.impl;
imports,,,,
#Service("userManagementService")
#Transactional(rollbackFor = Exception.class)
#SuppressWarnings("unchecked")
public class UserManagementServiceImpl extends AbstractService<Identifiable> implements UserManagementService
{
This throws a NULL pointer exception since userManagementService is NULL.
Please help me with your findings. Thanks in Advance.
It seems like adding this to your xml might solve the problem. If you are picking from a specific list of annotations you would also need to add the autowired annotation in their.
<context:include-filter type="annotation" expression="org.springframework.stereotype.Autowired" />
Related
I would like to know how to autowire JNDI resource in Spring controller using annotation.
Currently I can retrieve the resource using
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="my/service"/>
</bean>
Is there any way, I can do the same thing using annotation? Something like
#Resource(name="my/service") ?
#Configuration
public class Configuration {
#Bean(destroyMethod = "close")
public DataSource dataSource() {
JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
dsLookup.setResourceRef(false);
DataSource dataSource = dsLookup.getDataSource("my/service");
return dataSource;
}
}
I use this configuration to inject a JNDI resource
spring config
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee.xsd">
<jee:jndi-lookup id="destination" jndi-name="java:/queue/inbound/jndiname" />
</beans>
Class
#Autowired
private javax.jms.Destination destination;
I am working on a Spring Project:Common that uses a combination of Annotaions and Spring IOC in XML.
I have a common.jar which contains Common classes used by various projects.
And I have another Spring Project:WebService that refers to the beans defined in common.jar.
For some reason beans marked with #Component Annotation in Common.jar are not being picked up by my WebService Project. But all beans defined using <bean id="" class="" /> in Common.jar were picked up.
Below are the code for all files that have necessary configuration. Would really appreciate your help. Thanks in advance.
In Common.jar, applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<import resource="springConfig/app/AppServices.xml"/> <!-- Beans in this file were loaded. -->
<context:annotation-config/>
<context:component-scan base-package="com.ipd.app1"/> <!-- Beans for all classes under app1 package were NOT loaded -->
</beans>
In Common.jar, AppServices.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="inquireOrderApp" class="com.ipd.app.inquireOrderDetail.InquireOrderDetailAppImpl"/>
</beans>
Common.jar, com.test.app.MyClass
package com.ipd.app1;
#Component("createOrderApp")
public class CreateOrderAppImpl implements CreateOrderApp {
#Override
public CreateOrderResponse processMSSOrder(TransactionContext tx,
CreateOrderRequest createOrderRequest)
throws ApplicationException, Exception {
System.out.println("In App Layer Class CreateOrderAppImpl to ProcessOrder.");
return response;
}
}
WebService Project, IpdService_IPDSoapHTTPPortImpl.java
#WebService(portName = "IpdSoapHTTPPort", serviceName = "IpdService", targetNamespace = "http://ipd.com/ipdIpdweb/", wsdlLocation = "/wsdls/Ipd.wsdl", endpointInterface = "com.ipd.ipdIpdweb.IpdPortType")
#BindingType("http://schemas.xmlsoap.org/wsdl/soap/http")
public class IpdService_IpdSoapHTTPPortImpl implements IpdPortType {
ApplicationContext ctx;
public IpdService_IpdSoapHTTPPortImpl() {
this.ctx = AppContext.getCtx();
}
#Override
public void createOrder(WSHeader wsHeader,
CreateOrderRequest createOrderRequest,
Holder<WSResponseHeader> wsResponseHeader,
Holder<CreateOrderResponse> createOrderResponse)
throws WSException {
CreateOrderApp createOrderApp = (CreateOrderApp) ctx.getBean("createOrderApp");
res = createOrderApp.processOrder(tx, createOrderRequest);
res.setResponseCode(BigInteger.valueOf(0));
res.setResponseMessage("Success");
.....
}
}
Please let me know if you need see the code for any other file.
Well add this to applicationContext.xml
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
I was wondering if there is a way to do the following:
have my wep app startup with its servle-context.xml
When, at a certain point, one particular bean in this xml config is instantiated, it will add it's own xml configuration to the application context (or to a child perhaps?).
I'm asking this because I want to pack some functionality in a stand alone library and then reuse it in different projects, so that initializing a bean of this library will load its xml config.
What I wrote is:
public class IrisLibHelper {
ApplicationContext context;
ApplicationContext irisContext;
#Required
#Autowired
public void setContext(ApplicationContext ctx){
this.context = ctx;
ClassPathXmlApplicationContext xap = new ClassPathXmlApplicationContext(ctx);
xap.setConfigLocation("classpath:com/dariodario/irislib/xmldefs/irisconfig.xml");
this.irisContext = xap;
}
public ApplicationContext getIrisContext() {
return irisContext;
}
public void setIrisContext(ApplicationContext irisContext) {
this.irisContext = irisContext;
}
}
and the irisconfig.xml is:
<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-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/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<!-- <context:component-scan base-package="com.dariodario"></context:component-scan> -->
<mvc:annotation-driven />
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"
p:synchronizeOnSession="true" />
<context:component-scan base-package="com.dariodario.iris.controllers"></context:component-scan>
</beans>
The problem is that it doesn't seem to scan the com.dariodario.iris.controllers package, in fact the controllers don't get mapped! (I've logging debugging on and I don't seen anything).
Why not use the tag <import resource="classpath:applicationConfig.xml" /> ? You can load a spring configuration file which is in jar. In a jar, the Spring XML configuration is always at the root. But if not, you can use this notation: <import resource="${configurablePath}/applicationConfig.xml" /> where configurablePath can be reach by a property place holder or other.
I think this way is cleaner than merging two Spring context.
So I wanted to do something like this:
#Component
#Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES)
public class MyBean {
#Autowired HttpServletRequest request;
#PreDestroy
public void afterRequest() {
try {
System.out.println("After request...");
// use request here:
}
finally {
System.out.println("Completed successfully...");
}
}
}
And I end up with the following message, AFTER the "Completed successfully..." message logs:
09:19:16 WARN Invocation of destroy method failed on bean with name 'scopedTarget.myBean': java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
I'm not really sure what to make of this, since my logging indicates the destroy method completed successfully. Does anyone know what's going on?
EDIT:
Here's the mvc-servlet.xml. As you can see there is not much going on here. It's all annotation driven:
<?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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-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/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.0.xsd">
<!-- properties file -->
<context:property-placeholder location="app.properties" />
<context:component-scan base-package="my.package.web" />
<context:component-scan base-package="my.package.services" />
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:viewClass="org.springframework.web.servlet.view.JstlView" p:prefix="/WEB-INF/view" p:suffix=".jspx" />
</beans>
If you use request scope without spring MVC you should declare org.springframework.web.context.request.RequestContextListener in web-app listener.
<web-app>
...
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
...
</web-app>
check http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-factory-scopes-other-web-configuration
I never did get this working, but I ended up changing the code to apply #After advice on the controller methods, which has the same effect.
Is it possible to Autowire an object in a Validation class? I keep getting null for the object that is supposed to be Autowired...
Are your Validation class an enabled Spring bean ??? If not, you always will get null for your object autowired. Make sure you have enabled your Validation class.
And do not forget enable The Annotation config bean post-processor (see <context:annotation-config /> element)
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config />
</beans>
How to enable your Validation class as a managed Spring bean. Either
1° By using xml (As shown above)
<beans ...>
<bean class="AccessRequestValidator"/>
<context:annotation-config />
</beans>
2° By using annotation instead (Notice #Component just above class)
#Component
public class AccessRequestValidator implements Validator {
}
But to enable Spring annotated component scanning, you must enable a bean-post processor (notice <context:component-scan element)
<beans ...>
<context:annotation-config />
<context:component-scan base-package="<PUT_RIGHT_HERE_WHICH_ROOT_PACKAGE_SHOULD_SPRING_LOOK_FOR_ANY_ANNOTATED_BEAN>"/>
</beans>
Inside your Controller, just do it (Do not use new operator)
Choose one of the following strategies
public class MyController implements Controller {
/**
* You can use FIELD #Autowired
*/
#Autowired
private AccessRequestValidator accessRequestValidator;
/**
* You can use PROPERTY #Autowired
*/
private AccessRequestValidator accessRequestValidator;
private #Autowired void setAccessRequestValidator(AccessRequestValidator accessRequestValidator) {
this.accessRequestValidator = accessRequestValidator;
}
/**
* You can use CONSTRUCTOR #Autowired
*/
private AccessRequestValidator accessRequestValidator;
#Autowired
public MyController(AccessRequestValidator accessRequestValidator) {
this.accessRequestValidator = accessRequestValidator;
}
}
UPDATE
Your web app structure should looks like
<CONTEXT-NAME>/
WEB-INF/
web.xml
<SPRING-SERVLET-NAME>-servlet.xml
business-context.xml
classes/
/com
/wuntee
/taac
/validator
AccessRequestValidator.class
lib/
/**
* libraries needed by your project goes here
*/
Your web.xml should looks like (NOTICE contextConfigLocation context-param and ContextLoaderListener)
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<!--If your business-context.xml lives in the root of classpath-->
<!--replace by classpath:business-context.xml-->
<param-value>
/WEB-INF/business-context.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name><SPRING-SERVLET-NAME></servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name><SPRING-SERVLET-NAME></servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
</web-app>
Your <SPRING-SERVLET-NAME>-servlet.xml should looks like (Notice i am using Spring 2.5 - replace if you are using 3.0)
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<!--ANY HANDLER MAPPING-->
<!--ANY VIEW RESOLVER-->
<context:component-scan base-package="com.wuntee.taac"/>
<context:annotation-config/>
</beans>
Trying to follow what you show above, I am still getting a null pointer:
context.xml:
<context:annotation-config />
<context:component-scan base-package="com.wuntee.taac"/>
AccessRequestValidator.java
package com.wuntee.taac.validator;
#Component
public class AccessRequestValidator implements Validator {
#Autowired
private UserAccessCache userAccessCache;
...
}
business-context.xml:
<bean id="userAccessCache" class="com.wuntee.taac.controller.UserAccessCache">
<property name="cadaDao" ref="cadaDao" />
<property name="adDao" ref="adDao" />
</bean>
Does the scanner recursively scan the tree?