Spring inject bean into startup class during server start up - spring

My bean is :
#Component
public class KidsServerStartUp implements ServletContextListener
{
UploadService uplService;
#Autowired
public void setUplService( UploadService uplService )
{
this.uplService = uplService;
}
public void contextInitialized(ServletContextEvent event) {
System.out.println ( uplService );
}
}
In web.xml; I am firstly calling spring framework to set all beans ; then setting the startup listener :
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>com.kids.util.KidsServerStartUp</listener-class>
</listener>
uplService is getting printed as null !

I think what you are looking for is something like this post.
Since you are using a ServletContextListener spring context will not be used for the creation of the Listener class. But we can get access to the ApplicationContext using the ServletContext.
public class KidsServerStartUp implements ServletContextListener {
public void contextInitialized(ServletContextEvent event) {
final WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
UploadService uplService = springContext.getBean(UploadService.class);
System.out.println ( uplService );
}
}

Related

Spring #Autowired not working , bean is null

I am using spring 5.2.8
I am using #Autowired to get create the Bean. But i am getting NullPointer when I used this bean
configuration
#Configuration
#Primary
#ComponentScan(basePackages = {"com.try.appli"})
#EnableJpaRepositories(basePackages = "com.tryappli.persistence")
#EnableTransactionManagement
public class AppliConfiguration {
...
My component in package com.try.appli
#Component
#Primary
public class Mycomponent extends MycomponentAbstract {
#Autowired
MyService service
public handle()
String data ="{data to update}";
service.update(data);
service :
#Service
public MyService {
#Autowired
private RestOperations resoperation;
public void update(dataToUpdate) {
restOperations.put("url", dataToUpdate);
}
....
I also tried to put the annotation on the implementation but without success
In web.xml
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

spring-session Session implementation not getting CGLIB Enhanced Proxy Bean

I'm attempting to drop spring-session into an existing web application that uses session scoped beans. This application is running on Wildfly 10.1.0.Final
When I run the application uses wildfly's internal session management, everything works fine. Attempting to put in a custom implementation of Spring-Session is losing the session bean information. When I debug the application, there is a call for scopedTarget.userSessionData, however it is of the underlying class UserSessionData, and not the UserSessionData$$EnhancedBySpringCGLIB$$1234 that has the actual data.
configuration-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="userSessionData" scope="session" class="UserSessionData">
<aop:scoped-proxy/>
</bean>
<context:annotation-config />
<bean class="my.MyHttpSessionConfiguration" />
</beans>
This configuration properly creates and registers a springSessionRepositoryFilter using MyHttpSessionConfiguration. However the problem is when MySession object has a session scoped bean of UserSessionData, I get the raw proxied class instance and not the decorated one which has the session values. I was able to verify this by debugging the below SesssionImpl on the #setAttribute method
class UserSessionData {
private String _myValue;
public void setMyValue(String value) {
_myValue = value;
}
public String getMyValue() {
return _myValue;
}
}
final class MySession implements ExpiringSession {
private final MapSession _delegate;
private final Map<String, Object> _delta = new HashMap<>();
private boolean _isNew;
MySession() {
this(new MapSession());
_isNew = true;
flushImmediateIfNecessary();
}
MySession(MapSession session) {
if (session == null) {
throw new IllegalArgumentException("MapSession cannot be null");
}
_isNew = false;
_delegate = session;
}
public boolean isNew() {
return _isNew;
}
#Override
public String getId() {
return _delegate.getId();
}
#Override
public long getCreationTime() {
return _delegate.getCreationTime();
}
#Override
public long getLastAccessedTime() {
return _delegate.getLastAccessedTime();
}
#Override
public void setLastAccessedTime(long lastAccessedTime) {
_delegate.setLastAccessedTime(lastAccessedTime);
flushImmediateIfNecessary();
}
#Override
public void setMaxInactiveIntervalInSeconds(int interval) {
_delegate.setMaxInactiveIntervalInSeconds(interval);
flushImmediateIfNecessary();
}
#Override
public int getMaxInactiveIntervalInSeconds() {
return _delegate.getMaxInactiveIntervalInSeconds();
}
#Override
public boolean isExpired() {
return _delegate.isExpired();
}
#SuppressWarnings("unchecked")
#Override
public <T> T getAttribute(String attributeName) {
return (T) _delegate.getAttribute(attributeName);
}
#Override
public Set<String> getAttributeNames() {
return _delegate.getAttributeNames();
}
#Override
public void setAttribute(String attributeName, Object attributeValue) {
_delegate.setAttribute(attributeName, attributeValue);
putAndFlush(attributeName, attributeValue);
}
#Override
public void removeAttribute(String attributeName) {
_delegate.removeAttribute(attributeName);
putAndFlush(attributeName, null);
}
Map<String, Object> getDelta() {
return _delta;
}
private void putAndFlush(String attr, Object value) {
_delta.put(attr, value);
flushImmediateIfNecessary();
}
private void flushImmediateIfNecessary() {
if (MySessionRepository.this._flushMode == MyFlushMode.IMMEDIATE) {
MySessionRepository.this.save(this);
}
}
}
I feel like I'm missing either a configuration or something because the native WildFly SessionImpl has the correct Enhanced object for serialization when I remove the springSessionRepositoryFilter and let the container handle the session object. Additionally the Spring Controllers have the correct enhanced object. It's just MySession that does not appear to be getting it. Any thoughts?
EDIT:
Looks like the core issue is that my spring-security is using a different version of the proxy class when setting members, so I am not getting them in the MySession object. Attached are the configurations for Spring-Security
public class WebSessionInitializer extends AbstractHttpSessionInitializer {
}
#Configuration
#EnableSpringHttpSession
public class MySessionConfiguration {
#Bean
public SessionRepository sessionRepository() {
return new MySessionRepository();
}
}
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="imb"
version="2.5">
<distributable />
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/configuration-spring.xml
</param-value>
</context-param>
The SpringSession filter is correctly added with my implementation. It appears the root problem is when I get into spring-security, it is setting values on a different instance of UserSessionData than the one in the MySession object. When I use #Autowired in MVC Controllers, I get the correct one.
Library Versions:
Spring: 3.2.14
Spring Session: 1.3.2
WildFly 10.1.0.Final

Spring Autowiring fails

I have added one Listener in web.xml
<listener>
<listener-class>*.LoadCacheServlet</listener-class>
</listener>
This is servlet class
#Component
public class LoadCacheServlet implements ServletContextListener {
#Autowired
private ConnectorRepository connectorRepository;
#Override
public void contextDestroyed(ServletContextEvent arg0) {
LOGGER.info("ServletContextListener destroyed----------------------------");
}
// Run this before web application is started
#Override
public void contextInitialized(ServletContextEvent arg0) {
LOGGER.info("ServletContextListener startedddd---------------------------------");
connectorRepository.callMe("xys");
}
}
On tomcat startup. contextInitialized method gets exceuted but connectorRepository is not initailized. ConnectorRepository is an interface and in other parts of application its gets autowired by SpringJPA module. How to initialize it in servlet.

Failed startup of context com.google.appengine.tools.development.DevAppEngineWebAppContext

I am using Spring MVC,google app engine, admin sdk, cloud sql.
I want to access (preferncesDao) dao class into Filter.
Below is my filter
public class NameSpaceGoogleSecurityFilter implements Filter
{
#Autowired
IPreferencesDao preferncesDao;
public void init( FilterConfig filterConfig ) throws ServletException{
SpringUtils.init(filterConfig.getServletContext());
preferncesDao = SpringUtils.getPreferncesDao();
}
}
Below is my SpringUtils class.
public class SpringUtils {
private static ApplicationContext appContext;
private static IPreferencesDao preferncesDao = null;
public static void init(final ServletConfig config) {
init(config.getServletContext());
}
public static void init(final ServletContext context) {
if(appContext==null){
appContext =
(ApplicationContext) context.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
}
}
public static IPreferencesDao getPreferncesDao() {
if(preferncesDao==null){
preferncesDao=(IPreferencesDao) appContext.getBean("preferncesDao");
}
return preferncesDao;
}
protected SpringUtils() {
throw new UnsupportedOperationException();
}
}
When I start build process, It is throwing below exception
Failed startup of context com.google.appengine.tools.development.DevAppEngineWebAppContext
java.lang.NullPointerException.
Nullpointer at line preferncesDao=(IPreferencesDao) appContext.getBean("preferncesDao");
How can i resolve above error ? is it right way to get dao object into filter ? if not what is correct way.?
It is required to add below tag in web.xml
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
That purely indicate that ContextLoaderListener missing.
so add below code in web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
For more details refer this link

Liferay 6.2 + Spring #Autowired not working in a hook

I am using Spring 4.0.6 with Liferay 6.2. Spring isn't able to inject autowired components in to the hook, object comes as null. I have also tried with spring version 3.1 that comes with liferay. Same code works in portlets but not in hooks.
private ApplicationEventPublisher publisher in ActivityEventPublisher.java is null.
web.xml
<?xml version="1.0"?>
<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>
<param-value>/WEB-INF/spring/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>com.liferay.portal.kernel.servlet.SecurePluginContextListener</listener- class>
</listener>
<listener>
<listener-class>com.liferay.portal.kernel.servlet.PortletContextListener</listener-class>
</listener>
<servlet>
<servlet-name>ViewRendererServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.ViewRendererServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ViewRendererServlet</servlet-name>
<url-pattern>/WEB-INF/servlet/view</url-pattern>
</servlet-mapping>
</web-app>
ActivityEventPublisher.java
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;
import connect.activity.solr.document.ActivityData;
#Component
public class ActivityEventPublisher implements ApplicationEventPublisherAware {
private ApplicationEventPublisher publisher;
#Override
public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
public ApplicationEventPublisher getPublisher() {
return publisher;
}
public void setPublisher(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
public void publish(ActivityData data) {
ActivityEvent event = new ActivityEvent(this);
event.setActivityData(data);
this.publisher.publishEvent(event);
}
}
Any help will be much appreciated.
Thanks
Unfortunately, autowired mechanisms are not allowed in hooks, wrappers or startup actions at Liferay.
You can implement an ApplicationContextProvider, it's so easy and useful:
#Component("applicationContextProvider")
public class ApplicationContextProvider implements ApplicationContextAware {
private static ApplicationContext ctx = null;
public static ApplicationContext getApplicationContext() {
return ctx;
}
#Override
public void setApplicationContext(ApplicationContext ac) throws BeansException {
ctx = ac;
}
}
An example of use in a Hook will be the following:
public class PostLoginActionHook extends Action {
// That code "replaces" #Autowired annotation
private final UserProxyService userProxyService = (UserProxyService) ApplicationContextProvider.
getApplicationContext().getBean(UserProxyService.class);
#Override
public void run(HttpServletRequest request, HttpServletResponse response) throws ActionException {
UserVO myCustomUser = userProxyService.getCustomUserByLiferayUser(user.getUserId());
{...}
}
Hope it helps!

Resources