【问题标题】:DxlImporter inside a loop throws error " DXL importer operation failed"循环内的 DxlImporter 引发错误“DXL 导入器操作失败”
【发布时间】:2016-11-23 12:01:06
【问题描述】:

我有一个 java 代理,它遍历视图并从每个文档中获取附件,附件只是包含文档 xml 数据的 .dxl 文件。我在某个临时目录中提取文件,并在提取后尝试导入提取的 .dxl。

但这里的问题是,它只在循环中导入或处理第一个文档的附件,并在 java 调试控制台中抛出错误

NotesException: DXL importer operation failed
at lotus.domino.local.DxlImporter.importDxl(Unknown Source)
at JavaAgent.NotesMain(Unknown Source)
at lotus.domino.AgentBase.runNotes(Unknown Source)
at lotus.domino.NotesThread.run(Unknown Source)

我的java代理代码是

public class JavaAgent extends AgentBase {
static DxlImporter importer = null;

public void NotesMain() {

  try {
      Session session = getSession();
      AgentContext agentContext = session.getAgentContext();



      // (Your code goes here) 
      // Get current database
      Database db = agentContext.getCurrentDatabase();

      View v = db.getView("DXLProcessing_mails");
      DocumentCollection dxl_tranfered_mail = v.getAllDocumentsByKey("dxl_tranfered_mail"); 
      Document dxlDoc = dxl_tranfered_mail.getFirstDocument();
      while(dxlDoc!=null){

          RichTextItem rt = (RichTextItem) dxlDoc.getFirstItem("body");

          Vector allObjects= rt.getEmbeddedObjects();

          System.out.println("File name is "+ allObjects.get(0));
          EmbeddedObject eo = dxlDoc.getAttachment(allObjects.get(0).toString()); 
          if(eo.getFileSize()>0){
         eo.extractFile(System.getProperty("java.io.tmpdir") + eo.getName()); 

          System.out.println("Extracted File to "+System.getProperty("java.io.tmpdir") + eo.getName());
           String filePath = System.getProperty("java.io.tmpdir") + eo.getName();
           Stream stream = session.createStream();
          if (stream.open(filePath) & (stream.getBytes() >0)) {
            System.out.println("In If"+System.getProperty("java.io.tmpdir"));

             importer = session.createDxlImporter();
           importer.setDocumentImportOption(DxlImporter.DXLIMPORTOPTION_CREATE);
                  System.out.println("Break Point");

        importer.importDxl(stream,db);
        System.out.println("Imported Sucessfully");
      }else{
          System.out.println("In else"+stream.getBytes());


      }

      }
            dxlDoc = dxl_tranfered_mail.getNextDocument();   

   }
   } catch(Exception e) {
      e.printStackTrace();
   }

代码执行直到它打印“断点”并抛出错误,但附件是第一次导入

在其他情况下,如果我从文件系统硬编码特定 dxl 文件的 filePath,它会将 dxl 作为文档导入数据库中而没有错误

我想知道是否是传递的流没有完成并执行下一个循环的问题。

任何形式的建议都会有所帮助。

【问题讨论】:

  • 简短回答:将单个操作移动到其自己的方法中,并将循环限制为调用该方法,回收并前进到下一个文档。并回收利用!!!!

标签: import xpages document javaagents ibm-doors


【解决方案1】:

我看不到您的 while 循环会从第一个文档继续进行的任何部分。

通常你会有类似的东西:

Document nextDoc = dxl_tranfered_mail.getNextDocument(dxlDoc);
dxlDoc.recycle();
dxlDoc = nextDoc;

在循环结束时将其推进到下一个文档。按照您的代码目前的情况,它看起来永远不会前进,并且总是在第一个文档上。

如果您不知道“回收”多米诺骨牌对象的必要性,我建议您搜索一些博客文章来解释这样做的必要性。 它有点复杂,但基本上,Java 对象只是 C API 中对象的“包装器”。 每当您创建一个 Domino 对象(例如 Document、View、DocumentCollection 等)时,都会在底层的“C”层中分配一个内存句柄。这需要释放(或回收),并且最终会在会话被回收时这样做,但是当您在循环中处理时,回收更为重要,因为您很容易耗尽可用的内存句柄并导致崩溃。

您还可能需要在完成导入每个文件后关闭(并回收)每个 Stream

最后,仔细检查导致异常的提取文件绝对是有效的 DXL 文件,可能只是某些附件不是有效的 DXL 并且总是会引发异常。 您可以在循环中放置一个 try/catch 来处理该场景(并报告问题文件),这将允许代理继续而不会停止

【讨论】:

  • 您好,谢谢您的回复,但我可以看到这是我输入的错误。但我没有执行 dxlDoc.recycle();
  • 我已经尝试过这个解决方案,但异常抛出“importer.importDxl(stream,db);”
  • 几件事,你确定提取的文件是有效的dxl吗?它是否仍然第一次工作并且第二次失败?每次导入后关闭流有什么不同吗?在循环中放置一个try catch怎么样,所以如果它在一个文档上失败,它仍然会移动到下一个文档。您是否 100% 确定 dxl 始终是第一个嵌入对象?为什么不循环遍历向量呢?另外作为旁注,您绝对应该在完成嵌入对象后回收它们,否则它们不会清理他们秘密创建的临时文件。
  • 你说得对,是dxl数据的问题。导入dxl数据的事情应该完美导出。
  • 很高兴听到它正在工作!如果您可以接受我的回答作为解决方案,这样问题就不会留下“未回答”,可以吗?
猜你喜欢
  • 2012-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-01
  • 1970-01-01
相关资源
最近更新 更多