0

I have web application using Spring, Apache CXF and Jetty. Spring doesn't like the addition of an annotation called @Loggable to methods in one of my classes.

First, the annotation @Loggable links to the class LogAspect, which logs request and response messages:

@Aspect
@Component
public class LogAspect {

     ...
     ...
        @Around("execution(* * (..)) && @annotation(Loggable)")
        public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {

          ...
          if ( returnValue != null) {
                logger.infoRequestResponse(clazz, name, joinPoint.getArgs(), returnValue);
          } else {
                logger.infoRequestResponse(clazz, name, joinPoint.getArgs(), "void");
          }
          return returnValue;
        }
}

I'm guessing it has something to do with the @Context-annotation, and what is being injected when.

The class is an implementation of a RESTful service. The private member request has the annotation @Context on it:

@org.springframework.stereotype.Service(value = "resellerService")
public class ResellerServiceImpl implements ResellerService {

    @Context
    private HttpServletRequest request;
...
...
    @Loggable
    @Override
    public Response isUserLoggedIn() {
        Optional<ResellerSession> maybeSession = getSessionFromContext();
        return Response.ok(maybeSession.isPresent()).build();
    }

The addition of the @Loggable-annotation on a the isUserLoggedIn method gives me the following exception:

        WARN  org.eclipse.jetty.webapp.WebAppContext - Failed startup of context o.e.j.w.WebAppContext@79a9e51e{/,file:/home/lars/intellij_wspace/app/app-node/trunk/src/main/webapp/,STARTING}{src/main/webapp/}
        org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'resellerServiceServer': Invocation of init method failed; nested exception is org.apache.cxf.service.factory.ServiceConstructionException
            at [SNIP]
    org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1349) ~[jetty-webapp-9.2.10.v20150310.jar:9.2.10.v20150310]
            at ]
[SNIP]
        Caused by: org.apache.cxf.service.factory.ServiceConstructionException: null
            at org.apache.cxf.jaxrs.JAXRSServerFactoryBean.create(JAXRSServerFactoryBean.java:219) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_80]
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_80]
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_80]
            at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_80]
            at 
    [SNIP]
            ... 33 common frames omitted
        Caused by: java.lang.IllegalArgumentException: Can not set javax.servlet.http.HttpServletRequest field com.app.service.impl.reseller.ResellerServiceImpl.request to com.sun.proxy.$Proxy109
            at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164) ~[na:1.7.0_80]
            at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:168) ~[na:1.7.0_80]
            at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:55) ~[na:1.7.0_80]
            at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:75) ~[na:1.7.0_80]
            at java.lang.reflect.Field.set(Field.java:741) ~[na:1.7.0_80]
            at org.apache.cxf.jaxrs.utils.InjectionUtils$1.run(InjectionUtils.java:192) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
            at java.security.AccessController.doPrivileged(Native Method) ~[na:1.7.0_80]
            at org.apache.cxf.jaxrs.utils.InjectionUtils.injectFieldValue(InjectionUtils.java:188) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
            at org.apache.cxf.jaxrs.utils.InjectionUtils.injectContextProxiesAndApplication(InjectionUtils.java:1058) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
            at org.apache.cxf.jaxrs.JAXRSServerFactoryBean.injectContexts(JAXRSServerFactoryBean.java:405) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
            at org.apache.cxf.jaxrs.JAXRSServerFactoryBean.updateClassResourceProviders(JAXRSServerFactoryBean.java:429) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
            at org.apache.cxf.jaxrs.JAXRSServerFactoryBean.create(JAXRSServerFactoryBean.java:162) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]

So I tried taking away the @Context on the request, and adding it to a setter method instead:

private HttpServletRequest request;

@Context
public void setRequest(HttpServletRequest request) { this.request = request; }

which gives me this exception instead:

 WARN  org.eclipse.jetty.webapp.WebAppContext - Failed startup of context o.e.j.w.WebAppContext@25ddbf05{/,file:/home/lars/intellij_wspace/app/app-node/trunk/src/main/webapp/,STARTING}{src/main/webapp/}
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'resellerServiceServer': Invocation of init method failed; nested exception is org.apache.cxf.service.factory.ServiceConstructionException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757) ~[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480) ~[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403) ~[spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306) ~[spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    ...
    ...
Caused by: org.apache.cxf.service.factory.ServiceConstructionException: null
    at org.apache.cxf.jaxrs.JAXRSServerFactoryBean.create(JAXRSServerFactoryBean.java:219) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_80]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_80]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_80]
    at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_80]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1702) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1641) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    ... 33 common frames omitted
Caused by: javax.ws.rs.InternalServerErrorException: HTTP 500 Internal Server Error
    at org.apache.cxf.jaxrs.utils.SpecExceptions.toInternalServerErrorException(SpecExceptions.java:79) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
    at org.apache.cxf.jaxrs.utils.ExceptionUtils.toInternalServerErrorException(ExceptionUtils.java:106) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
    at org.apache.cxf.jaxrs.utils.InjectionUtils.reportServerError(InjectionUtils.java:472) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
    at org.apache.cxf.jaxrs.utils.InjectionUtils.reportServerError(InjectionUtils.java:458) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
    at org.apache.cxf.jaxrs.utils.InjectionUtils.injectThroughMethod(InjectionUtils.java:314) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
    at org.apache.cxf.jaxrs.utils.InjectionUtils.injectThroughMethod(InjectionUtils.java:294) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
    at org.apache.cxf.jaxrs.utils.InjectionUtils.injectContextProxiesAndApplication(InjectionUtils.java:1046) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
    at org.apache.cxf.jaxrs.JAXRSServerFactoryBean.injectContexts(JAXRSServerFactoryBean.java:405) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
    at org.apache.cxf.jaxrs.JAXRSServerFactoryBean.updateClassResourceProviders(JAXRSServerFactoryBean.java:429) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
    at org.apache.cxf.jaxrs.JAXRSServerFactoryBean.create(JAXRSServerFactoryBean.java:162) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
    ... 40 common frames omitted

Anyone has any ideas on how to solve this?

EDIT

I cannot show my entire pom.xml, but I do have this line 4.1.6.RELEASE

And the build looks and works fine. All other annotations such as @Autowired works fine.

Lars Andren
  • 8,601
  • 7
  • 41
  • 56

2 Answers2

0

The problem is with spring-beans-4.1.6.RELEASE.jar.

Hope you have added Spring-beans-4.1.6.jar file Still Spring sometimes unable to fetch jar due to some problems. In this case

Remove already existing project from your server.

Right click your server,

Click clean,

Right click your server,

Click clear Working directory.

Spring MVC Can also fetch jar files in this manner, It works

Right Click your Spring MVC project,

Build Path -> Configure Build Path

A Tab will appear,

Select Add External JAR's button and add all the jar's that you want.

After that, Click Deployment Assembly,

Click Add Button,

Click Java Build Path Entries,

Click Next,

Select all the jars that are appearing on this window.

Click Finish.

Refresh your project,

Run the project.

As of now It'll fetch spring-beans-4.1.6.RELEASE.jar in correct manner. Hope it helps.

MS Ibrahim
  • 1,789
  • 1
  • 16
  • 28
  • Thanks for the answer, but I dont think this is the cause of the problem. I do have "Maven: org.springframework:spring-beans:4.1.6.RELEASE" in my project libraries. – Lars Andren May 19 '15 at 07:18
  • this works fine with maven..if ur problem hasn't solved.. u can give it a try. – MS Ibrahim May 19 '15 at 07:55
0

I have now received help on how to resolve this issue. In short, the @Context annotation had to be moved into the method of the interface that the class implemented.

The solution is as follows:

  1. Removed the private member HttpServletRequest request and its @Context annotation.
  2. Add the HttpServletRequest as parameter to the methods that use it. Example:

    public Response registerUser(HttpServletRequest request,...) {

  3. Add the @Context annotation to the REST interface instead. Example:

    @Path("register/user")
    @POST
    @Consumes("application/json")

    Response registerUser(@Context HttpServletRequest httpServletRequest, ..);

Lars Andren
  • 8,601
  • 7
  • 41
  • 56