laitimes

java 浅拷贝BeanUtils.copyProperties引发的RPC异常

background

Recently participated in a key project, in the early stage because of other process reasons, the test time has been delayed for several days, I thought that the stuck point has been solved, and the follow-up process should be smooth and smooth, but I didn't expect people to be on the subway, and the bug came from Dong Dong~

Without any modification to the service interface, an exception is thrown:

java.lang.ClassCastException: java.util.HashMap cannot be cast to cn.xxx.xxx.xxx.xxx.BatchInfo

Troubleshooting process

1. As a veteran driver who writes bugs, the first feeling is that there is a problem with the format of the message that is transmitted, and it can be troubled by simulating the message. So, in the group, I circled the service provider student B to take a look, BG quickly used the test tool + local debug to verify the format of the following message, and found that it was successfully called. . .

2. Synchronous service calls student L, focusing on: 1) the serialization mode of the caller; 2) Whether there is a problem with the logic of the recent code changes. After student L confirms that there is no problem with his logic, he synchronizes student B and student S to see if there is any internal processing logic...

3. When I came the next morning, I quickly wrote a single test to confirm that there was no problem with the format of the packet received by the server. So, I started picking up the code... Spot suspicious code:

BeanUtils.copyProperties(item,cargoInfo)

private List<CargoInfo> convertToCargoInfo(OutboundEventCallbackRequest outboundEventCallbackRequest) {
        return outboundEventCallbackRequest.getCargos().stream().map(item -> {
            CargoInfo cargoInfo = new CargoInfo();
            BeanUtils.copyProperties(item, cargoInfo);
            return cargoInfo;
    }).collect(Collectors.toList());
}           

PS: Client-server class relationship

java 浅拷贝BeanUtils.copyProperties引发的RPC异常



This is because BeanUtils.copyProperties is a shallow copy, and a shallow copy just calls the set method of the child object, and does not copy all the properties (a memory address referenced). So when making a call, JSF will convert it to a Map because it can't find the corresponding class when deserializing.

The visual diagram is as follows:

java 浅拷贝BeanUtils.copyProperties引发的RPC异常



Above, the preliminary location of the cause, the solution is clear.

solution

Remove BeanUtils.copyProperties and manually assign a value. This problem was finally solved.

Follow-up reflection

1. Thinking of Mr. Wang Dongyue's words, the more primitive the more stable~

2. If there are many such transformations, it is recommended to use MapStruct

3、谨慎使用BeanUtils.copyProperties,请看:

java 浅拷贝BeanUtils.copyProperties引发的RPC异常