2

I'm using the OpenNTF POI 4 XPages plugin. This works very well for generating Word Documents. Now, after generating the Word document, I would like to create a new response document and store the word document as an attachment in a rich text field in this response document. Here is my code (in the poi postGenerationProcess property of the POI 4 XPages widget):

var doc:NotesDocument = currentDocument.getDocument();
var rdoc:NotesDocument = database.createDocument();
rdoc.appendItemValue("Form", "frmRespTempl");
rdoc.appendItemValue("Subject", "Embedded Word Document");
var rtitem:NotesRichTextItem = rdoc.createRichTextItem("Body");
rtitem.embedObject(xwpfdocument);
rdoc.makeResponse(doc);
rdoc.save();

Unfortunately, this gives me the error:

com.ibm.jscript.InterpretException: Script interpreter error, line=13, 
col=8: [TypeError] Method NotesRichTextItem.embedObject(org.apache.poi.xwpf.usermodel.XWPFDocument)
not found, or illegal parameters

Any tips how I can achieve this?

Implementing the suggestion offered below by Knut Hermann, I get:

POI 4 XPages -> ERROR

Error : Error during Documentgeneration POI LIB : 1.2.6.201312211419 StackTrace: com.ibm.xsp.exception.EvaluationExceptionEx: Error while executing JavaScript action expression at com.ibm.xsp.binding.javascript.JavaScriptMethodBinding.invoke(JavaScriptMethodBinding.java:126) at biz.webgate.dominoext.poi.component.containers.UIDocument$1.run(UIDocument.java:300) at biz.webgate.dominoext.poi.component.containers.UIDocument$1.run(UIDocument.java:1) at java.security.AccessController.doPrivileged(AccessController.java:251) at biz.webgate.dominoext.poi.component.containers.UIDocument.doPostGenerationProcessPrivileged(UIDocument.java:298) at biz.webgate.dominoext.poi.component.containers.UIDocument.postGenerationProcess(UIDocument.java:290) at biz.webgate.dominoext.poi.component.kernel.DocumentProcessor.processDocument(DocumentProcessor.java:233) at biz.webgate.dominoext.poi.component.kernel.DocumentProcessor.generateNewFile(DocumentProcessor.java:143) at biz.webgate.dominoext.poi.component.containers.UIDocument.processAjaxRequest(UIDocument.java:208) at biz.webgate.dominoext.poi.component.actions.DocumentGenerationServerAction.invoke(DocumentGenerationServerAction.java:48) at com.ibm.xsp.actions.ActionGroup.invoke(ActionGroup.java:135) at com.ibm.xsp.application.ActionListenerImpl.processAction(ActionListenerImpl.java:60) at javax.faces.component.UICommand.broadcast(UICommand.java:324) at com.ibm.xsp.component.UIEventHandler.broadcast(UIEventHandler.java:366) at com.ibm.xsp.component.UIDataPanelBase.broadcast(UIDataPanelBase.java:400) at com.ibm.xsp.component.UIDataPanelBase.broadcast(UIDataPanelBase.java:400) at com.ibm.xsp.component.UIDataPanelBase.broadcast(UIDataPanelBase.java:400) at com.ibm.xsp.extlib.component.layout.UIVarPublisherBase.broadcast(UIVarPublisherBase.java:183) at com.ibm.xsp.component.UIDataPanelBase.broadcast(UIDataPanelBase.java:400) at com.ibm.xsp.component.UIViewRootEx.broadcast(UIViewRootEx.java:1535) at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:307) at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:428) at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:94) at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:210) at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:96) at com.ibm.xsp.controller.FacesControllerImpl.execute(FacesControllerImpl.java:250) at com.ibm.xsp.webapp.FacesServlet.serviceView(FacesServlet.java:223) at com.ibm.xsp.webapp.FacesServletEx.serviceView(FacesServletEx.java:204) at com.ibm.xsp.webapp.FacesServlet.service(FacesServlet.java:160) at com.ibm.xsp.webapp.FacesServletEx.service(FacesServletEx.java:138) at com.ibm.xsp.webapp.DesignerFacesServlet.service(DesignerFacesServlet.java:103) at com.ibm.designer.runtime.domino.adapter.ComponentModule.invokeServlet(ComponentModule.java:576) at com.ibm.domino.xsp.module.nsf.NSFComponentModule.invokeServlet(NSFComponentModule.java:1281) at com.ibm.designer.runtime.domino.adapter.ComponentModule$AdapterInvoker.invokeServlet(ComponentModule.java:847) at com.ibm.designer.runtime.domino.adapter.ComponentModule$ServletInvoker.doService(ComponentModule.java:796) at com.ibm.designer.runtime.domino.adapter.ComponentModule.doService(ComponentModule.java:565) at com.ibm.domino.xsp.module.nsf.NSFComponentModule.doService(NSFComponentModule.java:1265) at com.ibm.domino.xsp.module.nsf.NSFService.doServiceInternal(NSFService.java:653) at com.ibm.domino.xsp.module.nsf.NSFService.doService(NSFService.java:476) at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.doService(LCDEnvironment.java:341) at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.service(LCDEnvironment.java:297) at com.ibm.domino.xsp.bridge.http.engine.XspCmdManager.service(XspCmdManager.java:272) Caused by: com.ibm.jscript.InterpretException: Script interpreter error, line=10, col=14: Error calling method 'write(java.io.FileOutputStream)' on java class 'org.apache.poi.xwpf.usermodel.XWPFDocument' at com.ibm.jscript.types.JavaAccessObject.call(JavaAccessObject.java:334) at com.ibm.jscript.types.FBSObject.call(FBSObject.java:161) at com.ibm.jscript.ASTTree.ASTCall.interpret(ASTCall.java:175) at com.ibm.jscript.ASTTree.ASTProgram.interpret(ASTProgram.java:119) at com.ibm.jscript.ASTTree.ASTProgram.interpretEx(ASTProgram.java:139) at com.ibm.jscript.JSExpression._interpretExpression(JSExpression.java:435) at com.ibm.jscript.JSExpression.access$1(JSExpression.java:424) at com.ibm.jscript.JSExpression$2.run(JSExpression.java:414) at java.security.AccessController.doPrivileged(AccessController.java:284) at com.ibm.jscript.JSExpression.interpretExpression(JSExpression.java:410) at com.ibm.jscript.JSExpression.evaluateValue(JSExpression.java:251) at com.ibm.jscript.JSExpression.evaluateValue(JSExpression.java:234) at com.ibm.xsp.javascript.JavaScriptInterpreter.interpret(JavaScriptInterpreter.java:221) at com.ibm.xsp.binding.javascript.JavaScriptMethodBinding.invoke(JavaScriptMethodBinding.java:111) ... 41 more Caused by: org.apache.poi.POIXMLException: java.lang.IllegalStateException: Access denied (java.lang.RuntimePermission getClassLoader) at org.apache.poi.POIXMLDocument.getProperties(POIXMLDocument.java:141) at org.apache.poi.POIXMLDocument.write(POIXMLDocument.java:177) at sun.reflect.GeneratedMethodAccessor163.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37) at java.lang.reflect.Method.invoke(Method.java:611) at com.ibm.jscript.types.JavaAccessObject.call(JavaAccessObject.java:321) ... 54 more Caused by: java.lang.IllegalStateException: Access denied (java.lang.RuntimePermission getClassLoader) at org.apache.xmlbeans.XmlBeans.getContextTypeLoader(XmlBeans.java:336) at org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.PropertiesDocument$Factory.parse(Unknown Source) at org.apache.poi.POIXMLProperties.(POIXMLProperties.java:75) at org.apache.poi.POIXMLDocument.getProperties(POIXMLDocument.java:139) ... 59 more Caused by: java.security.AccessControlException: Access denied (java.lang.RuntimePermission getClassLoader) at java.security.AccessController.checkPermission(AccessController.java:108) at java.lang.SecurityManager.checkPermission(SecurityManager.java:544) at java.lang.Thread.getContextClassLoader(Thread.java:456) at org.apache.xmlbeans.impl.schema.SchemaTypeLoaderImpl.getContextTypeLoader(SchemaTypeLoaderImpl.java:131) at sun.reflect.GeneratedMethodAccessor128.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37) at java.lang.reflect.Method.invoke(Method.java:611) at org.apache.xmlbeans.XmlBeans.getContextTypeLoader(XmlBeans.java:327) ... 62 more

  • rtitem.embedObject has to have at least three parameters: http://publib.boulder.ibm.com/infocenter/domhelp/v8r0/index.jsp?topic=%2Fcom.ibm.designer.domino.main.doc%2FH_EMBEDOBJECT_METHOD_JAVA.html with the path to your Word file as the third. Write the Word file to file system and then you can attach it. – Knut Herrmann Apr 01 '14 at 15:14

2 Answers2

6

Save your Word document to file system in a temporary folder and then attach it from there with rtitem.embedObject to your RichTextItem:

var temp = java.lang.System.getProperty("java.io.tmpdir");
var file = new java.io.File(temp + "YourFile.docx"); 
var fileOutputStream = new java.io.FileOutputStream(file);
xwpfdocument.write(fileOutputStream);
fileOutputStream.close();

var doc:NotesDocument = currentDocument.getDocument();
var rdoc:NotesDocument = database.createDocument();
rdoc.appendItemValue("Form", "frmRespTempl");
rdoc.appendItemValue("Subject", "Embedded Word Document");
var rtitem:RichTextItem = rdoc.createRichTextItem("Body");
rtitem.embedObject(lotus.domino.local.EmbeddedObject.EMBED_ATTACHMENT, "",
                   file.getAbsolutePath(), null);
rdoc.makeResponse(doc);
rdoc.save();

If you don't want to save the file into file system then create a MIMEEntity instead and stream the Word content direct to Notes document (Java code snippet as a starting point).

Community
  • 1
  • 1
Knut Herrmann
  • 30,880
  • 4
  • 31
  • 67
  • Thanks very much for your help. I'm now trying to implement your solution but unfortunately I get an error: –  Apr 02 '14 at 09:13
  • I'm working on this issue now, I get the error com.ibm.jscript.InterpretException: Script interpreter error, line=10, col=14: Error calling method 'write(java.io.FileOutputStream)' on java class 'org.apache.poi.xwpf.usermodel.XWPFDocument' at com.ibm.jscript.types.JavaAccessObject.call(JavaAccessObject.java:334) –  Apr 02 '14 at 09:23
  • Is there any additional information in stack trace about error cause? – Knut Herrmann Apr 02 '14 at 09:30
  • Thanks, I just added the entire trace above. –  Apr 02 '14 at 09:36
  • I think the important part is "org.apache.poi.POIXMLException: java.lang.IllegalStateException: Access denied (java.lang.RuntimePermission getClassLoader)" but what causes it? – Knut Herrmann Apr 02 '14 at 09:53
  • Have you tried to grant all permissions in the java.policy (or java.pol) on the server ? – umeli Apr 02 '14 at 10:07
  • Just as a test: does it work if you change line `xwpfdocument.write(fileOutputStream);` to `fileOutputStream.write(1);` - this way we can test if writing files allowed. – Knut Herrmann Apr 02 '14 at 11:29
  • Using the line fileOutputStream.write(1); writes a special character which looks like [] to the file. –  Apr 02 '14 at 12:16
  • You mean file got attached to Notes document and there was no error message? – Knut Herrmann Apr 02 '14 at 12:20
  • Now a new response document is created which contains "YourFile.txt" in the Body field. YourFile is empty and the XPage displays the error message: Error 500 HTTP Web Server: Command Not Handled Exception –  Apr 02 '14 at 12:46
  • ok, the permission error comes from POI not from writing file to file system - I'll look at this this evening - error 500 is not relevant to this issue – Knut Herrmann Apr 02 '14 at 12:54
  • So, is it attempting to write to the user's machine or the server? I'm using the FacesContext to create spreadsheets, which presents the user with a dialog for where the file ought to go. I'm guessing that your method simply places it automatically and I'm wondering if the filepath is incorrect. – David Navarre Apr 02 '14 at 13:58
  • The file is created on the server in the C:\TempWord folder. –  Apr 02 '14 at 14:19
  • Yes, with java.lang.System.getProperty("java.io.tmpdir") the result is the same. A response doc is created with an empty .txt file. –  Apr 02 '14 at 15:13
  • 1
    (1) It will work if you add `grant { permission java.security.AllPermission; };` to file `/jvm/lib/security/java.policy` and restart the http task. I had that on my dev server that's why it just worked for me. But, this is usually not an option for a production server for security reasons. That's why you might consider to realize one of the following comments. – Knut Herrmann Apr 03 '14 at 05:14
  • 1
    (2) In source code of POI4XPages you can see that all original apache poi methods are framed by `AccessController.doPrivileged(new PrivilegedAction() {... poi methods ...}` to get the necessary rights at this moment (e.g. in biz.webgate.dominoext.poi.beans.PoiBean). You can use this technique in an own Java class to get the xwpfdocument.write() to work. – Knut Herrmann Apr 03 '14 at 05:20
  • 1
    (3) If you use the `poiBean` to create the Word files then you can use the method `ByteArrayOutputStream processDocument2Stream()` and combine it with the MIMEEntity approach (see last part of my answer) OR add a method like `attachFile(String filename, RichTextItem rtitem)` to class PoiBean. – Knut Herrmann Apr 03 '14 at 05:28
  • 1
    Thanks very much. Tip one works, I'll now try tip 2. –  Apr 03 '14 at 07:34
  • I'm trying to get point 2 to work now but I just can't get the syntax right :-( –  Apr 07 '14 at 13:49
  • "not the right syntax" means you can't compile the Java code or it doesn't run like expected? – Knut Herrmann Apr 07 '14 at 14:15
  • I get the error 'processDocument2(java.io.FileOutputStream)' on java class 'AZGPackage.writeXWPFDocument' not found at com.ibm.jscript.types.JavaAccessObject.call(JavaAccessObject.java:360). I call the code from the postGenerationProcess event using var temp = java.lang.System.getProperty("java.io.tmpdir"); var file = new java.io.File(temp + "YourFile.docx"); var fileOutputStream = new java.io.FileOutputStream(file); var jce:writeXWPFDocument = new writeXWPFDocument(); jce.processDocument2(xwpfdocument,fileOutputStream); The method processDocument2 is contained in the java class below. –  Apr 08 '14 at 07:22
  • public FileOutputStream processDocument2(XWPFDocument xwpfdocument, FileOutputStream fileOutputStream) { final FileOutputStream fileOutputStreamFin = fileOutputStream; final XWPFDocument docFin; final FileOutputStream newdoc; docFin = xwpfdocument; newdoc = AccessController.doPrivileged(new PrivilegedAction() { public FileOutputStream run() { try { docFin.write(fileOutputStreamFin); } catch (Exception e) { e.printStackTrace(); } return fileOutputStreamFin; } }); return fileOutputStreamFin; } –  Apr 08 '14 at 07:23
  • The error message tells that you call 'processDocument2(java.io.FileOutputStream)' with only one parameter but it is defined with two. In your code you call it with two parameters - is project not build after changing SSJS? – Knut Herrmann Apr 09 '14 at 06:52
  • I have checked that the class is built but now get the error: Caused by: com.ibm.jscript.InterpretException: Script interpreter error, line=10, col=28: Java method 'processDocument2(org.apache.poi.xwpf.usermodel.XWPFDocument, java.io.FileOutputStream)' on java class 'AZGPackage.writeXWPFDocument' not found. Is the xwpfdocument available in the postGenerationProcess event actually an object of type org.apache.poi.xwpf.usermodel.XWPFDocument? I think I need to redefine the method so it will accept xwpfdocument being passed to it. –  Apr 10 '14 at 09:03
  • Is the Java class defined as a normal Design element in "Code / Java" or somewhere visible only in package explorer like "WebContent / ..."? – Knut Herrmann Apr 10 '14 at 16:31
  • The java class is defined as a normal Java class design element in the .nsf –  Apr 11 '14 at 15:19
  • The java class is defined as a normal Java class design element under Code \ Java in the .nsf –  Apr 11 '14 at 15:37
  • If I define the method as public FileOutputStream processDocument2(Object xwpfdocument, FileOutputStream fileOutputStream) it is found but then the write method does not work. –  Apr 11 '14 at 16:12
  • I've now managed to pass the xwpfdocument as an XPWFDocument object. The problem was that the poi .jar files were installed on both the server and in the database. –  May 07 '14 at 07:20
2

The Notes API requires a file, not a Java object. I would suggest you use the MIME document approach where you Base64 the Doc as mime part

stwissel
  • 20,110
  • 6
  • 54
  • 101