emma自身的代码在处理合并覆盖率时,容错性不够,代码处理上也不完善,两处TODO也表明代码的逻辑处理还不够完善:

  1. // merge all data files: 
  2.             try 
  3.             { 
  4.                 final long start = log.atINFO () ? System.currentTimeMillis () : 0
  5.                  
  6.                 for (int f = 0; f < m_dataPath.length; ++ f) 
  7.                 { 
  8.                     final File dataFile = m_dataPath [f]; 
  9.                     if (verbose) log.verbose ("processing input file [" + dataFile.getAbsolutePath () + "] ..."); 
  10.                      
  11.                     final IMergeable [] fileData = DataFactory.load (dataFile); 
  12.                      
  13.                     final IMetaData _mdata = (IMetaData) fileData [DataFactory.TYPE_METADATA]; 
  14.                     if (_mdata != null
  15.                     { 
  16.                         if (verbose) log.verbose ("  loaded " + _mdata.size () + " metadata entries"); 
  17.                          
  18.                         if (mdata == null
  19.                             mdata = _mdata; 
  20.                         else 
  21.                             mdata = (IMetaData) mdata.merge (_mdata); // note: later datapath entries override earlier ones 
  22.                     } 
  23.                      
  24.                     final ICoverageData _cdata = (ICoverageData) fileData [DataFactory.TYPE_COVERAGEDATA]; 
  25.                     if (_cdata != null
  26.                     { 
  27.                         if (verbose) log.verbose ("  loaded " + _cdata.size () + " coverage data entries"); 
  28.                          
  29.                         if (cdata == null
  30.                             cdata = _cdata; 
  31.                         else 
  32.                             cdata = (ICoverageData) cdata.merge (_cdata); // note: later datapath entries override earlier ones 
  33.                     } 
  34.                      
  35.                     ++ m_dataFileCount; 
  36.                 } 
  37.                  
  38.                 if (log.atINFO ()) 
  39.                 { 
  40.                     final long end = System.currentTimeMillis (); 
  41.                      
  42.                     log.info (m_dataFileCount + " file(s) read and merged in " + (end - start) + " ms"); 
  43.                 } 
  44.                  
  45.                 if (((mdata == null) || mdata.isEmpty ()) && ((cdata == null) || cdata.isEmpty ())) 
  46.                 { 
  47.                     log.warning ("nothing to do: no metadata or coverage data found in any of the input files"); 
  48.                      
  49.                     // TODO: throw exception or exit quietly? 
  50.                     return
  51.                 } 
  52.             } 
  53.             catch (IOException ioe) 
  54.             { 
  55.                 // TODO: handle 
  56.                 ioe.printStackTrace (System.out); 
  57.             } 

 这里的问题是:如果粉红色底纹的语句抛出异常,将直接跳过灰色底纹(蓝色字体)语句块的检查,这将导致检查失效,最后导致mdata和cdata同时为null,在到后面处理的时候,抛出了java.lang.IllegalArgumentException: null input: data异常。

修改后的代码(灰色底纹部分是我新增或者修改的代码):

  1. // merge all data files: 
  2.             try 
  3.             { 
  4.                 final long start = log.atINFO () ? System.currentTimeMillis () : 0
  5.                  
  6.                 for (int f = 0; f < m_dataPath.length; ++ f) 
  7.                 { 
  8.                     final File dataFile = m_dataPath [f]; 
  9.                     if (verbose) log.verbose ("processing input file [" + dataFile.getAbsolutePath () + "] ..."); 
  10.                      
  11.                     // 五和:容错处理:如果DataFactory.load失败(load异常),说明em和ec文件存在损坏,合并过程跳过此文件。 
  12.                     IMergeable [] fileData = null
  13.                     try { 
  14.                         fileData = DataFactory.load (dataFile); 
  15.                     } catch(IOException ioe) { 
  16.                         // 五和:跳过异常em和ec文件的处理 
  17.                         continue
  18.                     } 
  19.                      
  20.                     if (fileData == null) { 
  21.                         continue
  22.                     } 
  23.                      
  24.                     final IMetaData _mdata = (IMetaData) fileData [DataFactory.TYPE_METADATA]; 
  25.                     if (_mdata != null
  26.                     { 
  27.                         if (verbose) log.verbose ("  loaded " + _mdata.size () + " metadata entries"); 
  28.                          
  29.                         if (mdata == null
  30.                             mdata = _mdata; 
  31.                         else 
  32.                             mdata = (IMetaData) mdata.merge (_mdata); // note: later datapath entries override earlier ones 
  33.                     } 
  34.                      
  35.                     final ICoverageData _cdata = (ICoverageData) fileData [DataFactory.TYPE_COVERAGEDATA]; 
  36.                     if (_cdata != null
  37.                     { 
  38.                         if (verbose) log.verbose ("  loaded " + _cdata.size () + " coverage data entries"); 
  39.                          
  40.                         if (cdata == null
  41.                             cdata = _cdata; 
  42.                         else 
  43.                             cdata = (ICoverageData) cdata.merge (_cdata); // note: later datapath entries override earlier ones 
  44.                     } 
  45.                      
  46.                     ++ m_dataFileCount; 
  47.                 } 
  48.                  
  49.                 if (log.atINFO ()) 
  50.                 { 
  51.                     final long end = System.currentTimeMillis (); 
  52.                      
  53.                     log.info (m_dataFileCount + " file(s) read and merged in " + (end - start) + " ms"); 
  54.                 } 
  55.                  
  56.                 if (((mdata == null) || mdata.isEmpty ()) && ((cdata == null) || cdata.isEmpty ())) 
  57.                 { 
  58.                     log.warning ("nothing to do: no metadata or coverage data found in any of the input files"); 
  59.                      
  60.                     // TODO: throw exception or exit quietly? 
  61.                     return
  62.                 } 
  63.             } 
  64.             catch (Exception ex)    // 处理merge异常 
  65.             { 
  66.                 // 捕获merge异常,并通过邮件报告给开发人员。 
  67.                 throw new EMMARuntimeException (UNEXPECTED_FAILURE, 
  68.                         new Object [] {ex.toString (), IAppConstants.APP_BUG_REPORT_LINK}, 
  69.                         ex); 
  70.             }