Hmily and Feign conflict error report NullPointerException
Hmily is used in the project to ensure the consistency of distributed transactions. Since Hmily will register an HmilyFeignInterceptor, and feign will add it to requestInterceptors in the SynchronousMethodHandler. When the feign client executes the apply method in the HmilyFeignInterceptor
public void apply(final RequestTemplate requestTemplate) { ().transmit((x$0, xva$1) -> { (x$0, new String[]{xva$1}); }, ().get()); }
Since the obtained HmilyTransactionContext is null , a NullPointerException exception is thrown.
Solution
Define a postprocessor that will not be annotated by @Hmily, and remove HmilyFeignInterceptor.
package ; import ; import ; import ; import ; import .slf4j.Slf4j; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; /** * @author:JZ * @date:2020/6/1 */ @Slf4j @Component public class ShopFeignPostProcessor implements BeanPostProcessor { public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { // Process all beans containing @FeignClient if ((((), ))) { // Exclude beans with @Controller and @RestController annotations if ((((), )) || (((), ))) { return bean; } try { // Get FeignInvocationHandler in the proxy class Field h = ().getSuperclass().getDeclaredField("h"); boolean hAccessible = (); (true); Object feignInvocationHandler = (bean); /** * Get the Map<Method, MethodHandler> dispatch property of the dispatch field in FeignInvocationHandler. * Methods containing feign proxy in dispatch and SynchronousMethodHandler */ Field dispatchField = ().getDeclaredField("dispatch"); boolean dispatchAccessible = (); (true); Map<Method, > dispatch = (Map<Method, >) (feignInvocationHandler); /** * List<RequestInterceptor> requestInterceptors field in SynchronousMethodHandler * Loaded Hmily's interceptor on feign HmilyFeignInterceptor */ for (<Method, > entry : ()) { /** * Methods without @Hmily annotation need not be intercepted by Hmily. * Otherwise, a NullPointerException will be caused by the loaded HmilyTransactionContext being null */ if ((((), ))) { Field riField = ().getClass().getDeclaredField("requestInterceptors"); boolean riAccessible = (); (true); List<RequestInterceptor> requestInterceptors = (List<RequestInterceptor>) (()); for (RequestInterceptor interceptor : requestInterceptors) { if (interceptor instanceof HmilyFeignInterceptor) { (interceptor); break; } } (riAccessible); ("{}.{} Method removal HmilyFeignInterceptor", beanName, ().getName()); } } (dispatchAccessible); (hAccessible); } catch (Exception e) { ("{} exception", beanName); (); } } return bean; } }
Several reasons and solutions
Reason for appearance
1. String variable not initialized
2. Interface type objects are not initialized with specific classes, such as:
Map map // An error will be reportedMap map = new Map(); //There will be no error
3. When the value of an object is empty, you do not judge to be empty.
4. Comparison between strings and texts. Text can be a string or an Enum element. An exception will occur as follows.
String str = null; if((“Test”)){undefined //The code here will not be triggered because an exception will be thrown.}
5. Prioritize the use of the() method instead of toString()
When the program code requires a string representation of an object, avoid using the toString method of that object. If your object's reference is equal to null, NullPointerException will be thrown, using a static method, which will not throw any exceptions and print "null"
6. The class is declared with type, default class = null; In this way, when calling the method in class, the system can only give you a null pointer exception, just instantiate it: class = new Class();
7. Return null. The return value of the method should not be defined as a general type, but use an array. This way, if you want to return null, you can avoid many unnecessary NullPointerExceptions.
The two I bolded are relatively common and easy to ignore.
Most of the time when string comparison is compared, because str=null, then an exception will be thrown using ("Test")
null cannot be compared with string
There are two solutions:
- It is to determine whether the string is empty before comparison
- When the passed parameter str is empty, the program will be exceptional. The correct thing is to put the string in front of it.
"Test".equals(str)
The second type is recommended.
The above is personal experience. I hope you can give you a reference and I hope you can support me more.