lucky-xin opened a new issue, #12885:
URL: https://github.com/apache/dubbo/issues/12885

   <!-- If you need to report a security issue please visit 
https://github.com/apache/dubbo/security/policy -->
   
   - [ ] I have searched the [issues](https://github.com/apache/dubbo/issues) 
of this repository and believe that this is not a duplicate.
   
   ### Environment
   
   * Dubbo version: 3.2.4
   * Operating System version: k8s v1.27
   * Java version: 17
   
   ### Steps to reproduce this issue
   
   1. 多线程执行服务消费者
   2. 使用stream().parallel().forEach()遍历并调用服务提供者
   
   
   Pls. provide [GitHub address] to reproduce this issue.
   
   ### Expected Behavior
   
   支持服务消费者多线程调用服务提供者
   
   ### Actual Behavior
   <!-- What actually happens? -->
   服务消费端返回值被转为HashMap
   If there is an exception, please attach the exception trace:
   ```
   com.alibaba.com.caucho.hessian.io.java8.LocalDateTimeHandle"}
   
{"@timestamp":"2023-08-12T09:09:34.881328+08:00","thread":"ForkJoinPool.commonPool-worker-2","thread_id":15,"level":"WARN","message":"Hessian/Burlap:
 'com.alibaba.com.caucho.hessian.io.java8.LocalTimeHandle' is an unknown class 
in 
jdk.internal.loader.ClassLoaders$AppClassLoader@531d72ca:\njava.lang.ClassNotFoundException:
 com.alibaba.com.caucho.hessian.io.java8.LocalTimeHandle"}
   
{"@timestamp":"2023-08-12T09:09:34.881663+08:00","thread":"ForkJoinPool.commonPool-worker-2","thread_id":15,"level":"WARN","message":"Hessian/Burlap:
 'com.alibaba.com.caucho.hessian.io.java8.LocalDateHandle' is an unknown class 
in 
jdk.internal.loader.ClassLoaders$AppClassLoader@531d72ca:\njava.lang.ClassNotFoundException:
 
   java.util.concurrent.CompletionException: java.lang.ClassCastException: 
class java.util.HashMap cannot be cast to class com.x.x.x.UserInfo 
(java.util.HashMap is in module java.base of loader 
'bootstrap';com.x.x.x.UserInfo is in unnamed module of loader 
org.springframework.boot.loader.LaunchedURLClassLoader@573f2bb1)
   at 
java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:315)
   at 
java.base/java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:320)
   at 
java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1770)
   at 
java.base/java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1760)
   at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
   at 
java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
   at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
   at 
java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
   at 
java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165
   ```
   
   
跟踪代码发现问题出现在com.alibaba.com.caucho.hessian.io.SerializerFactory#getDeserializer(java.lang.String)中,加载业务class失败导致获取Deserializer为null,最后返回MapDeserializer
   ```
   public Deserializer getObjectDeserializer(String type)
               throws HessianProtocolException {
   
           Deserializer deserializer = getDeserializer(type);
          // deserializer为null,返回MapDeserializer
           if (deserializer != null)
               return deserializer;
           else if (_hashMapDeserializer != null)
               return _hashMapDeserializer;
           else {
               _hashMapDeserializer = new MapDeserializer(HashMap.class);
   
               return _hashMapDeserializer;
           }
       }
   ```
   ```
   public Deserializer getDeserializer(String type)
               throws HessianProtocolException {
           if (type == null || type.equals("") || 
_typeNotFoundDeserializerMap.containsKey(type))
               return null;
   
           Deserializer deserializer;
   
           if (_cachedTypeDeserializerMap != null) {
               deserializer = (Deserializer) 
_cachedTypeDeserializerMap.get(type);
   
               if (deserializer != null)
                   return deserializer;
           }
   
   
           deserializer = (Deserializer) _staticTypeMap.get(type);
           if (deserializer != null)
               return deserializer;
   
           if (type.startsWith("[")) {
               Deserializer subDeserializer = 
getDeserializer(type.substring(1));
   
               if (subDeserializer != null)
                   deserializer = new 
ArrayDeserializer(subDeserializer.getType());
               else
                   deserializer = new ArrayDeserializer(Object.class);
           } else if (_unrecognizedTypeCache.get(type) == null) {
               try {
                   // 问题在这出现
                  //                Class cl = Class.forName(type, false, 
_loader);
                   Class cl = loadSerializedClass(type);
                   deserializer = getDeserializer(cl);
               } catch (Exception e) {
                   log.warning("Hessian/Burlap: '" + type + "' is an unknown 
class in " + _loader + ":\n" + e);
                   _typeNotFoundDeserializerMap.put(type, PRESENT);
                   log.log(Level.FINER, e.toString(), e);
                   _unrecognizedTypeCache.put(type, new AtomicLong(1L));
               }
           } else {
               ((AtomicLong) 
_unrecognizedTypeCache.get(type)).incrementAndGet();
               if (((AtomicLong) _unrecognizedTypeCache.get(type)).get() % 
2000L == 0L)
                   ((AtomicLong) 
_unrecognizedTypeCache.get(type)).getAndSet(1L);
           }
   
           if (deserializer != null) {
               if (_cachedTypeDeserializerMap == null)
                   _cachedTypeDeserializerMap = new ConcurrentHashMap(8);
   
               _cachedTypeDeserializerMap.put(type, deserializer);
           }
   
           return deserializer;
       }
   ```
   loadSerializedClass时会获取ClassFactory加载class
   ```
   public Class<?> loadSerializedClass(String className)
               throws ClassNotFoundException
       {
           return getClassFactory().load(className);
       }
   
       public ClassFactory getClassFactory()
       {
           synchronized (this) {
               if (_classFactory == null) {
                // 获取当前SerializerFactory的ClassLoader
                   _classFactory = new ClassFactory(getClassLoader());
               }
   
               return _classFactory;
           }
       }
   ```
   而SerializerFactory的ClassLoader是通过当前执行线程获取的,单线程环境下没有问题,多线程环境下很可能就会有问题
   ```
   public class Hessian2ObjectInput implements ObjectInput, Cleanable {
       private final Hessian2Input mH2i;
       private final Hessian2FactoryManager hessian2FactoryManager;
   
       @Deprecated
       public Hessian2ObjectInput(InputStream is) {
           mH2i = new Hessian2Input(is);
           this.hessian2FactoryManager = 
FrameworkModel.defaultModel().getBeanFactory().getOrRegisterBean(Hessian2FactoryManager.class);
           
mH2i.setSerializerFactory(hessian2FactoryManager.getSerializerFactory(Thread.currentThread().getContextClassLoader()));
       }
   
       public Hessian2ObjectInput(InputStream is, Hessian2FactoryManager 
hessian2FactoryManager) {
           mH2i = new Hessian2Input(is);
           this.hessian2FactoryManager = hessian2FactoryManager;
           // 反序列化时创建SerializerFactory,并把当前线程的ClassLoader给SerializerFactory
          
mH2i.setSerializerFactory(hessian2FactoryManager.getSerializerFactory(Thread.currentThread().getContextClassLoader()));
       }
   //...
   }
   ```


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to