Eric
Eric

Reputation: 515

JsonMappingException when using @RefreshScope on a property bean

JsonMappingException when using @RefreshScope on a property bean

I have a spring boot application which use spring cloud for the configuration

My configuration class looks like this:

package test;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;

@Component
@EnableConfigurationProperties
@ConfigurationProperties("configuration")
@RefreshScope
public class MyConfigurationBean {

  @Value("${configuration.projectName}")
  private String name;
  private String city;
  private int port;

  // Getters/setters
}

And a RESTController that looks like this:

package test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RefreshScope
public class MyRestController {

  @Autowired
  private MyConfigurationBean config;

  @RequestMapping(value = "/config", produces = MediaType.APPLICATION_JSON_VALUE)
  public MyConfigurationBean port() {
    return this.config;
  }
}

The /refresh endpoint is also enabled.

When I try a GET on /config, I have this exception:

2017-09-19 11:46:25.694  WARN 23005 --- [nio-5858-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: No serializer found for class org.springframework.context.expression.StandardBeanExpressionResolver and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS); nested exception is com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class org.springframework.context.expression.StandardBeanExpressionResolver and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: test.MyConfigurationBean$$EnhancerBySpringCGLIB$$3a7ee0c3["targetSource"]->org.springframework.aop.target.SimpleBeanTargetSource["beanFactory"]->org.springframework.beans.factory.support.DefaultListableBeanFactory["parentBeanFactory"]->org.springframework.beans.factory.support.DefaultListableBeanFactory["beanExpressionResolver"])

When I remove the @RefreshScope annotation from the MyConfigurationBean class, the error disapear, but the bean is not refresh when I call the /refresh endpoint.

What is wrong with my code?

Upvotes: 0

Views: 818

Answers (1)

ywy
ywy

Reputation: 89

I got the same exception and found this answer to question Casting a Spring's Proxy object to the actual runtime class

Basically RefreshScope creates a CGLib proxy on your original property object which is not json serializable.

Casting e.g. (MyConfigurationBean)((Advised) config).getTargetSource().getTarget() should work, but it's strongly not advised.

Upvotes: 1

Related Questions