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

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

Related

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.

Jersey custom ExceptionMapper not called on 400 Bad Request (when validation fails)

I'm using Jersey with Spring for web services. For catching exceptions and formatting the response sent to the caller I have added an implementation of ExceptionMapper.
Though it is being called when I explicitly throw an exception from within the controller, but when the json field validation fails the exception mapper is not called and the response sent is **may not be null (path = checkNotification.arg0.tyres, invalidValue = null)
**
#Provider
public class GenericExceptionMapper implements ExceptionMapper<Throwable> {
#Override
public Response toResponse(Throwable ex) {
System.out.println("Exception Mapper !!!");
return Response.status(404).entity(ex.getMessage()).type("application/json").build();
}
}
<servlet>
<servlet-name>jersey-servlet</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.help.rest.controller,
com.fasterxml.jackson.jaxrs.json
</param-value>
</init-param>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.help.filter.FeatureRegistration</param-value>
</init-param>
<init-param>
<param-name>jersey.config.beanValidation.enableOutputValidationErrorEntity.server</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Jersey Version is 2.22.1
Spring Version is 4.2.4
I made it work by changing
#Provider
public class GenericExceptionMapper implements ExceptionMapper<Throwable> {
#Override
public Response toResponse(Throwable ex) {
System.out.println("Exception Mapper !!!");
return Response.status(404).entity(ex.getMessage()).type("application/json").build();
}
}
to
#Provider
public class GenericExceptionMapper implements ExceptionMapper<ConstraintViolationException> {
#Override
public Response toResponse(ConstraintViolationException ex) {
System.out.println("Exception Mapper !!!");
return Response.status(404).entity(ex.getMessage()).type("application/json").build();
}
}
Though I'm able to catch the exception I am not getting the exact class and field which failed the constraint.
Resolved
Found a Set containing all the required fields in ContraintViolationException, could be accessed using ex.getConstraintViolations()
made it work by changing
#Provider
public class GenericExceptionMapper implements ExceptionMapper<Throwable> {
#Override
public Response toResponse(Throwable ex) {
System.out.println("Exception Mapper !!!");
return Response.status(404).entity(ex.getMessage()).type("application/json").build();
}
}
to
#Provider
public class GenericExceptionMapper implements ExceptionMapper<ConstraintViolationException> {
#Override
public Response toResponse(ConstraintViolationException ex) {
System.out.println("Exception Mapper !!!");
return Response.status(404).entity(ex.getMessage()).type("application/json").build();
}
}
To get the exact exception details, like which field failed the constraint use ConstraintViolationException's getConstraintViolations(). This method provides a set for all the constraint violations.
You need to register it:
public class MyApplication extends Application {
public Set<Class<?>> getClasses() {
Set<Class<?>> s = new HashSet<Class<?>>();
s.add(HelloWorldResource.class);
/** you need to add ExceptionMapper class as well **/
s.add(GenericExceptionMapper.class)
return s;
}
}

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!

Spring inject bean into startup class during server start up

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 );
}
}

Resources