美文网首页工作中源代码学习
Orika、CompletableFuture结合使用:报Map

Orika、CompletableFuture结合使用:报Map

作者: ___TheOne___ | 来源:发表于2019-05-16 15:21 被阅读0次

    1.背景

    项目需要使用到一个实体映射工具(Entity Mapping)。例如:实体A、B,字段名称全部一样,将实体A中的字段值,全部复制到实体B中。
    调查过程中,采用orika-mapper框架,本地单元测试也表现良好。

    2.问题

    当将使用orika代码,在测试环境运行,转换过程报NullPointerException。详细异常堆栈信息见下方

    java.lang.RuntimeException: ma.glasnost.orika.MappingException: While attempting the following mapping:
    sourceType = com.ctrip.corp.hotelbooking.bookcommon.db.model.corporderdb.CorpOrders
    destinationType = com.ctrip.corp.hotelbooking.bookcommon.db.entity.corporderdb.HTLCCorpOrders
    Error occurred: java.lang.NullPointerException
    -------------------------------------------------------------
    Unenhance strategy: ma.glasnost.orika.unenhance.BaseUnenhancer@1e408a3b
    -----end dump of current state-------------------------------
        at ma.glasnost.orika.impl.generator.MapperGenerator.build(MapperGenerator.java:105)
        at ma.glasnost.orika.impl.DefaultMapperFactory.buildMapper(DefaultMapperFactory.java:1372)
        at ma.glasnost.orika.impl.DefaultMapperFactory.lookupMapper(DefaultMapperFactory.java:757)
        at ma.glasnost.orika.impl.DefaultMapperFactory.lookupMapper(DefaultMapperFactory.java:707)
        at ma.glasnost.orika.impl.MapperFacadeImpl.resolveMapper(MapperFacadeImpl.java:591)
        at ma.glasnost.orika.impl.MapperFacadeImpl.resolveMappingStrategy(MapperFacadeImpl.java:216)
        at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:741)
        at ma.glasnost.orika.impl.MapperFacadeImpl.map(MapperFacadeImpl.java:721)
        at com.ctrip.corp.hotelbooking.bookcommon.db.repository.entityMapper.EntityMapper.map(EntityMapper.java:26)
        at com.ctrip.corp.hotelbooking.bookcommon.db.repository.impl.CorpOrdersRepositoryImpl.insert(CorpOrdersRepositoryImpl.java:27)
        at com.ctrip.corp.hotelbooking.hotelws.manager.createorder.member.sub.SaveHTLCCorpOrdersBiz.saveHTLCCorpOrder(SaveHTLCCorpOrdersBiz.java:95)
        at com.ctrip.corp.hotelbooking.hotelws.manager.createorder.member.sub.SaveCorpOrderDBBiz.lambda$saveCorpOrderDBAsync$4(SaveCorpOrderDBBiz.java:92)
        at com.ctrip.corp.hotelbooking.bookcommon.utility.util.LambdaUtil.lambda$tryOf$1(LambdaUtil.java:46)
        ... 6 more
    Caused by: java.lang.NullPointerException
        at ma.glasnost.orika.impl.generator.JavassistCompilerStrategy.registerClassLoader(JavassistCompilerStrategy.java:133)
        at ma.glasnost.orika.impl.generator.JavassistCompilerStrategy.compileClass(JavassistCompilerStrategy.java:235)
        at ma.glasnost.orika.impl.generator.SourceCodeContext.compileClass(SourceCodeContext.java:249)
        at ma.glasnost.orika.impl.generator.SourceCodeContext.getInstance(SourceCodeContext.java:266)
        at ma.glasnost.orika.impl.generator.MapperGenerator.build(MapperGenerator.java:75)
        ... 18 more
    

    后续通过源码调查发现,是因为使用orika框架映射实体的代码,在jdk1.8---CompletableFuture内部执行,CompletableFuture内部维护的线程池-ForkJoinPool中的Thread,通过方法getContextClassLoader()获取类加载器上下文环境为 NULL

    异常核心代码

    简单解决方案:
    为CompletableFuture传入一个自定义的ForkJoinPool,这样线程池中Thread.getContextClassLoader()非空。

    深入解决思路
    1.tomcat容器类加载机制
    2.JDK1.8中CompleteFuture默认的ForkJoinPool线程池,Thread.contextClassLoader如何设置?
    3.自定义线程池时,Thread.contextClassLoader如何设置?

    3.文章参考

    1.NullPointerException in JavassistCompilerStrategy.registerClassLoader when using ForkJoinPool #225
    2.Parallel stream doesn't set Thread.contextClassLoader after tomcat upgrade

    相关文章

      网友评论

        本文标题:Orika、CompletableFuture结合使用:报Map

        本文链接:https://www.haomeiwen.com/subject/qqymaqtx.html