1. Recurrence problem
Today, when starting the spring boot project, the following problems suddenly occurred:
SLF4J: Failed toString() invocation on an object of type [com.superjson.superjsonmanager.config.jwt.JwtProperties$$EnhancerBySpringCGLIB$$3c58badf]
Reported exception:
com.alibaba.fastjson.JSONException: write javaBean error, fastjson version 1.2.70, class org.springframework.beans.factory.support.DefaultListableBeanFactory, fieldName : $$beanFactory, write javaBean error, fastjson version 1.2.70, class com.baomidou.mybatisplus.MybatisConfiguration, fieldName : configuration, write javaBean error, fastjson version 1.2.70, class com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceWrapper, fieldName : dataSource, write javaBean error, fastjson version 1.2.70, class com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl, fieldName : connection, write javaBean error, fastjson version 1.2.70, class com.mysql.cj.jdbc.ConnectionImpl, fieldName : connectionRaw, write javaBean error, fastjson version 1.2.70, class com.mysql.cj.jdbc.DatabaseMetaData, fieldName : metaData, write javaBean error, fastjson version 1.2.70, class com.mysql.cj.jdbc.result.ResultSetImpl, fieldName : catalogs
at com.alibaba.fastjson.serializer.JavaBeanSerializer.write(JavaBeanSerializer.java:539)
at com.alibaba.fastjson.serializer.JavaBeanSerializer.write(JavaBeanSerializer.java:149)
at com.alibaba.fastjson.serializer.JSONSerializer.writeWithFieldName(JSONSerializer.java:333)
at com.alibaba.fastjson.serializer.ASMSerializer_1_JwtProperties$$EnhancerBySpringCGLIB$$3c58badf.write(Unknown Source)
at com.alibaba.fastjson.serializer.JSONSerializer.write(JSONSerializer.java:285)
at com.alibaba.fastjson.JSON.toJSONString(JSON.java:758)
at com.alibaba.fastjson.JSON.toJSONString(JSON.java:696)
at com.alibaba.fastjson.JSON.toJSONString(JSON.java:661)
at com.superjson.superjsonmanager.config.jwt.JwtProperties.toString(JwtProperties.java:73)
at org.slf4j.helpers.MessageFormatter.safeObjectAppend(MessageFormatter.java:277)
at org.slf4j.helpers.MessageFormatter.deeplyAppendParameter(MessageFormatter.java:249)
at org.slf4j.helpers.MessageFormatter.arrayFormat(MessageFormatter.java:211)
at org.slf4j.helpers.MessageFormatter.arrayFormat(MessageFormatter.java:161)
at ch.qos.logback.classic.spi.LoggingEvent.getFormattedMessage(LoggingEvent.java:293)
at ch.qos.logback.classic.spi.LoggingEvent.prepareForDeferredProcessing(LoggingEvent.java:206)
at ch.qos.logback.core.OutputStreamAppender.subAppend(OutputStreamAppender.java:223)
at ch.qos.logback.core.OutputStreamAppender.append(OutputStreamAppender.java:102)
at ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:84)
at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:51)
at ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:270)
at ch.qos.logback.classic.Logger.callAppenders(Logger.java:257)
at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:421)
at ch.qos.logback.classic.Logger.filterAndLog_1(Logger.java:398)
at ch.qos.logback.classic.Logger.info(Logger.java:583)
at com.superjson.superjsonmanager.SuperJsonManagerApplication.main(SuperJsonManagerApplication.java:51)
Caused by: com.alibaba.fastjson.JSONException: write javaBean error, fastjson version 1.2.70, class com.baomidou.mybatisplus.MybatisConfiguration, fieldName : configuration, write javaBean error, fastjson version 1.2.70, class com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceWrapper, fieldName : dataSource, write javaBean error, fastjson version 1.2.70, class com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl, fieldName : connection, write javaBean error, fastjson version 1.2.70, class com.mysql.cj.jdbc.ConnectionImpl, fieldName : connectionRaw, write javaBean error, fastjson version 1.2.70, class com.mysql.cj.jdbc.DatabaseMetaData, fieldName : metaData, write javaBean error, fastjson version 1.2.70, class com.mysql.cj.jdbc.result.ResultSetImpl, fieldName : catalogs
at com.alibaba.fastjson.serializer.JavaBeanSerializer.write(JavaBeanSerializer.java:539)
at com.alibaba.fastjson.serializer.JavaBeanSerializer.write(JavaBeanSerializer.java:149)
at com.alibaba.fastjson.serializer.JSONSerializer.writeWithFieldName(JSONSerializer.java:333)
at com.alibaba.fastjson.serializer.ASMSerializer_105_DefaultSqlSessionFactory.write(Unknown Source)
at com.alibaba.fastjson.serializer.MapSerializer.write(MapSerializer.java:271)
at com.alibaba.fastjson.serializer.MapSerializer.write(MapSerializer.java:44)
at com.alibaba.fastjson.serializer.FieldSerializer.writeValue(FieldSerializer.java:320)
at com.alibaba.fastjson.serializer.JavaBeanSerializer.write(JavaBeanSerializer.java:470)
... 24 more
2. Analyze problems
I use alibaba.fastjson
to parses the jwtproperties
object and reports the above error. This object is used to store the parameters of JWT
, as shown in the following code:
/**
* @author zby
* @datetime 2022/8/19 12:05
* @desc jwt entity class, get the configured properties from the yml configuration file
*/
@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix = "jwt")
public class JwtProperties {
@Value("${jwt.secret}")
private String appSecret;
@Value("${jwt.expiration}")
private long expiration;
@Value("${jwt.typ}")
private String typ;
@Value("${jwt.alg}")
private String alg;
@Value("${jwt.subject}")
private String subject;
@Value("${jwt.tokenStartWith}")
private String tokenStartWith;
@Value("${jwt.tokenHeader}")
private String tokenHeader;
public String getTokenStartWith() {
return tokenStartWith + " ";
}
@Override
@JSONField(serialize = false)
public String toString() {
return JSONObject.toJSONString(this);
}
}
That is, rewrite the tostring()
method internal statement JSONObject.toJSONString(this);
has a problem, so the breakpoint is to see why this problem occurs, as shown in the screenshot below:
You will find that the dynamically generated the object of jwtproperties
does not only have its property value, but also has many more property values that I have not defined. Why does this happen?
It should be that spring boot
uses the dynamic proxy mode to instantiate the object, and this additional attribute value is the attribute value of the dynamic proxy object. Therefore, fastjson
cannot resolve the attribute value of the dynamic proxy, so an error is reported.
3. Solve problems
Since we know that the error is caused by the spring boot
dynamic agent, we do not give the object to the spring boot
dynamic agent. We can modify the toString()
method as follows:
@Override
@JSONField(serialize = false)
public String toString() {
JSONObject jsonObject = new JSONObject();
jsonObject.put("appSecret", this.appSecret);
jsonObject.put("expiration", this.expiration);
jsonObject.put("typ", this.typ);
jsonObject.put("alg", this.alg);
jsonObject.put("subject", this.subject);
jsonObject.put("tokenStartWith", this.tokenStartWith);
jsonObject.put("tokenHeader", this.tokenHeader);
return JSONObject.toJSONString(jsonObject);
}
Start spring boot
as shown in the following figure: