ITextRenderer多线程使用时java.lang.NullPointerException问题

问题:

由于使用的版本比较古老:R5pre1,所以在使用过程中遇到了并发使用的问题,
就是在多线程创建ITextRenderer时会出现.
java.lang.NullPointerException: null
at org.xhtmlrenderer.util.XRLog.log(XRLog.java:206)
at org.xhtmlrenderer.util.XRLog.render(XRLog.java:194)
at org.xhtmlrenderer.util.XRLog.render(XRLog.java:190)
at org.xhtmlrenderer.layout.SharedContext.<init>(SharedContext.java:107)
at org.xhtmlrenderer.pdf.ITextRenderer.<init>(ITextRenderer.java:111)
at org.xhtmlrenderer.pdf.ITextRenderer.<init>(ITextRenderer.java:102)
...

分析:

查看org.xhtmlrenderer.util.XRLog源码
  ...
  public static void log(String where, Level level, String msg)
  {
    if (initPending) {
      init();
    }
    if (isLoggingEnabled()) {
      loggerImpl.log(where, level, msg);
    }
  }
  ...
  private static void init()
  {
    synchronized (XRLog.class)
    {
      if (!initPending) {
        return;
      }
      initPending = false;

      setLoggingEnabled(Configuration.isTrue("xr.util-logging.loggingEnabled", true));
      if (loggerImpl == null) {
        loggerImpl = new JDKXRLogger();
      }
    }
  }
  ...
在多线程的环境下如果线程A处理到initPending = false;而此时时间片轮到了线程B
处理到if (initPending) 时,结果是false,但此时并未初始化完毕,那么在往下执行
时loggerImpl未null,所有会出现空指针问题。

解决:

1、在无法修改源码版本的情况下,使用这种方式创建对象即可。
ITextRenderer renderer;
synchronized (XRLog.class) {
    renderer = new ITextRenderer();
}
原理就是强制有序创建对象。
2、在高版本的应用中应该不存在该问题,升级jar包版本即可。

猜你喜欢

转载自blog.csdn.net/m0_38043362/article/details/78952994