Page 1 of 1

Convert to ByteArrayOutputStream

PostPosted: Fri Jan 03, 2014 9:31 am
by andyflint
Hi

Firstly have used docx4j to modify a document but at the end I need to convert the WorProcessinfMLDocument document to a ByteArrayOutputStream before I can save it to my application. Can someone please advise the best way of doing this.

Thank you in advance and any help is much appreciated

A

Re: Convert to ByteArrayOutputStream

PostPosted: Fri Jan 03, 2014 2:23 pm
by jason
If you wanted to save the entire docx pkg, you'd do:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    SaveToZipFile saver = new SaveToZipFile(pkg);
    saver.save(baos);
 
Parsed in 0.015 seconds, using GeSHi 1.0.8.4


or similar with https://github.com/plutext/docx4j/blob/ ... /Save.java

But that doesn't seem to be what you are asking.

To save just the main document part contents,

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    MainDocumentPart mdp = wordMLPackage.getMainDocumentPart();
    mdp.marshal(baos)

 
Parsed in 0.015 seconds, using GeSHi 1.0.8.4

Re: Convert to ByteArrayOutputStream

PostPosted: Fri Jan 03, 2014 9:32 pm
by andyflint
Hello Jason thank you for your reply.

In the application I am using the starting point is a byteArrayInputAtream. what I then need to do is modify some fields and return a ByteArrayOutputStream to the applications. Everything works fine until I try to create the byte from the wordProcessingML.

The example I am using (based on yours is below:


Code: Select all
   private   ByteArrayOutputStream convertToByteArray() throws Exception{
      
//      FlatOpcXmlCreator worker = new FlatOpcXmlCreator(wordML);
         OpcPackage pkg = wordML.getPackage();
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         SaveToZipFile saver = new SaveToZipFile(pkg);
         saver.save(baos);
         return baos;
   }


The error that I am getting is basically a class loader issue when trying to load org/docx4j/jaxb/mc-preprocessor.xslt which I can see in the jar but because I am running this is a web container my class can't find the xslt in the class path and is not using the manifest.

Is there another way that I can convert to a byte array I can see that WordProcessingMLPackage has a helper method for loading a byteArray why can't it have another helper methord for returning a byteArray?.

Anyway the error I am getting below.

Code: Select all
03.01.2014 10:20:33 *DEBUG* SaveToZipFile: For Relationship Id=rId1 Source is /word/header3.xml, Target is media/image1.png (SaveToZipFile.java, line 324)
03.01.2014 10:20:33 *DEBUG* SaveToZipFile: Getting part /word/media/image1.png (SaveToZipFile.java, line 365)
03.01.2014 10:20:33 *DEBUG* SaveToZipFile: org.docx4j.openpackaging.parts.WordprocessingML.ImagePngPart (SaveToZipFile.java, line 376)
03.01.2014 10:20:33 *DEBUG* SaveToZipFile: .. saving binary stuff (SaveToZipFile.java, line 415)
03.01.2014 10:20:33 *INFO * SaveToZipFile: success writing part: word/media/image1.png (SaveToZipFile.java, line 463)
03.01.2014 10:20:33 *DEBUG* SaveToZipFile: For Relationship Id=rId1 Source is /word/document.xml, Target is numbering.xml (SaveToZipFile.java, line 324)
03.01.2014 10:20:33 *DEBUG* SaveToZipFile: Getting part /word/numbering.xml (SaveToZipFile.java, line 365)
03.01.2014 10:20:33 *DEBUG* SaveToZipFile: org.docx4j.openpackaging.parts.WordprocessingML.NumberingDefinitionsPart (SaveToZipFile.java, line 376)
03.01.2014 10:20:33 *DEBUG* SaveToZipFile: .. saving  (SaveToZipFile.java, line 419)
03.01.2014 10:20:33 *INFO * JaxbXmlPart: marshalling org.docx4j.openpackaging.parts.WordprocessingML.NumberingDefinitionsPart (JaxbXmlPart.java, line 323)
03.01.2014 10:20:33 *INFO * JaxbXmlPart: Lazily unmarshalling /word/numbering.xml (JaxbXmlPart.java, line 129)
03.01.2014 10:20:33 *INFO * JaxbXmlPartXPathAware: For org.docx4j.openpackaging.parts.WordprocessingML.NumberingDefinitionsPart, unmarshall via binder (JaxbXmlPartXPathAware.java, line 299)
03.01.2014 10:20:34 *WARN * JaxbValidationEventHandler: [ERROR] : unexpected element (uri:"http://schemas.microsoft.com/office/word/2010/wordml", local:"shadow"). Expected elements are < (JaxbValidationEventHandler.java, line 91)
03.01.2014 10:20:34 *INFO * JaxbValidationEventHandler: continuing (with possible element/attribute loss) (JaxbValidationEventHandler.java, line 107)
03.01.2014 10:20:34 *INFO * JaxbXmlPartXPathAware: encountered unexpected content; pre-processing (JaxbXmlPartXPathAware.java, line 324)
03.01.2014 10:20:34 *WARN * ResourceUtils: Couldn't get resource: org/docx4j/jaxb/mc-preprocessor.xslt (ResourceUtils.java, line 52)
03.01.2014 10:20:34 *ERROR* JaxbValidationEventHandler: Problem setting up  mc-preprocessor.xslt (JaxbValidationEventHandler.java, line 61)
java.io.IOException: org/docx4j/jaxb/mc-preprocessor.xslt not found via classloader.
   at org.docx4j.utils.ResourceUtils.getResource(ResourceUtils.java:54)
   at org.docx4j.jaxb.JaxbValidationEventHandler.getMcPreprocessor(JaxbValidationEventHandler.java:56)
   at org.docx4j.openpackaging.parts.JaxbXmlPartXPathAware.unmarshal(JaxbXmlPartXPathAware.java:347)
   at org.docx4j.openpackaging.parts.JaxbXmlPart.getJaxbElement(JaxbXmlPart.java:130)
   at org.docx4j.openpackaging.parts.JaxbXmlPart.marshal(JaxbXmlPart.java:324)
   at org.docx4j.openpackaging.parts.JaxbXmlPart.marshal(JaxbXmlPart.java:301)
   at org.docx4j.openpackaging.io.SaveToZipFile.saveRawXmlPart(SaveToZipFile.java:247)
   at org.docx4j.openpackaging.io.SaveToZipFile.saveRawXmlPart(SaveToZipFile.java:196)
   at org.docx4j.openpackaging.io.SaveToZipFile.savePart(SaveToZipFile.java:420)
   at org.docx4j.openpackaging.io.SaveToZipFile.addPartsFromRelationships(SaveToZipFile.java:383)
   at org.docx4j.openpackaging.io.SaveToZipFile.savePart(SaveToZipFile.java:438)
   at org.docx4j.openpackaging.io.SaveToZipFile.addPartsFromRelationships(SaveToZipFile.java:383)
   at org.docx4j.openpackaging.io.SaveToZipFile.save(SaveToZipFile.java:166)
   at eu.ema.dream.sbo.docxinjection.EMADocxInjection.convertToByteArray(EMADocxInjection.java:255)
   at eu.ema.dream.sbo.docxinjection.EMADocxInjection.setDocxID(EMADocxInjection.java:305)
   at eu.ema.dream.sbo.docxinjection.EMADocxInjection.setDocxID(EMADocxInjection.java:85)
   at eu.ema.dream.bof.type.EMADocument.doSave(EMADocument.java:189)
   at com.documentum.fc.client.DfPersistentObject.saveEx(DfPersistentObject.java:912)
   at com.documentum.fc.client.DfPersistentObject.save(DfPersistentObject.java:907)
   at eu.ema.dream.bof.type.EMADocument___PROXY.save(EMADocument___PROXY.java)
   at com.documentum.operations.nodeactions.inbound.DfCheckinObject.checkin(DfCheckinObject.java:235)
   at com.documentum.operations.nodeactions.inbound.DfCheckinObject.execute(DfCheckinObject.java:39)
   at com.documentum.operations.steps.impl.OperationStep.executeStep(OperationStep.java:163)
   at com.documentum.operations.steps.impl.OperationStep.execute(OperationStep.java:41)
   at com.documentum.operations.impl.OperationExecutionEngine.execute(OperationExecutionEngine.java:51)
   at com.documentum.operations.DfOperation.execute(DfOperation.java:401)
   at com.documentum.operations.inbound.impl.InboundOperation.execute(InboundOperation.java:104)
   at com.documentum.operations.inbound.DfImportOperation.execute(DfImportOperation.java:96)
   at com.documentum.web.contentxfer.DFCOperationSupport.execute(DFCOperationSupport.java:61)
   at com.documentum.web.contentxfer.ContentTransferService.execute(ContentTransferService.java:377)
   at com.documentum.web.contentxfer.JobAdapter.execute(JobAdapter.java:108)
   at com.documentum.job.async.AsyncJobManager$AsyncTimerJob.executeJob(AsyncJobManager.java:236)
   at com.documentum.job.async.AsyncJobManager$AsyncTimerJob.run(AsyncJobManager.java:215)
   at java.util.TimerThread.mainLoop(Timer.java:512)
   at java.util.TimerThread.run(Timer.java:462)
03.01.2014 10:20:34 *ERROR* JaxbXmlPart: No JAXBElement has been created for this part, yet! (JaxbXmlPart.java, line 326)
03.01.2014 10:20:34 *ERROR* JaxbXmlPart: No JAXBElement has been created for this part, yet! (JaxbXmlPart.java, line 334)
javax.xml.bind.JAXBException: No JAXBElement has been created for this part, yet!
   at org.docx4j.openpackaging.parts.JaxbXmlPart.marshal(JaxbXmlPart.java:327)
   at org.docx4j.openpackaging.parts.JaxbXmlPart.marshal(JaxbXmlPart.java:301)
   at org.docx4j.openpackaging.io.SaveToZipFile.saveRawXmlPart(SaveToZipFile.java:247)
   at org.docx4j.openpackaging.io.SaveToZipFile.saveRawXmlPart(SaveToZipFile.java:196)
   at org.docx4j.openpackaging.io.SaveToZipFile.savePart(SaveToZipFile.java:420)
   at org.docx4j.openpackaging.io.SaveToZipFile.addPartsFromRelationships(SaveToZipFile.java:383)
   at org.docx4j.openpackaging.io.SaveToZipFile.savePart(SaveToZipFile.java:438)
   at org.docx4j.openpackaging.io.SaveToZipFile.addPartsFromRelationships(SaveToZipFile.java:383)
   at org.docx4j.openpackaging.io.SaveToZipFile.save(SaveToZipFile.java:166)
   at eu.ema.dream.sbo.docxinjection.EMADocxInjection.convertToByteArray(EMADocxInjection.java:255)
   at eu.ema.dream.sbo.docxinjection.EMADocxInjection.setDocxID(EMADocxInjection.java:305)
   at eu.ema.dream.sbo.docxinjection.EMADocxInjection.setDocxID(EMADocxInjection.java:85)
   at eu.ema.dream.bof.type.EMADocument.doSave(EMADocument.java:189)
   at com.documentum.fc.client.DfPersistentObject.saveEx(DfPersistentObject.java:912)
   at com.documentum.fc.client.DfPersistentObject.save(DfPersistentObject.java:907)
   at eu.ema.dream.bof.type.EMADocument___PROXY.save(EMADocument___PROXY.java)
   at com.documentum.operations.nodeactions.inbound.DfCheckinObject.checkin(DfCheckinObject.java:235)
   at com.documentum.operations.nodeactions.inbound.DfCheckinObject.execute(DfCheckinObject.java:39)
   at com.documentum.operations.steps.impl.OperationStep.executeStep(OperationStep.java:163)
   at com.documentum.operations.steps.impl.OperationStep.execute(OperationStep.java:41)
   at com.documentum.operations.impl.OperationExecutionEngine.execute(OperationExecutionEngine.java:51)
   at com.documentum.operations.DfOperation.execute(DfOperation.java:401)
   at com.documentum.operations.inbound.impl.InboundOperation.execute(InboundOperation.java:104)
   at com.documentum.operations.inbound.DfImportOperation.execute(DfImportOperation.java:96)
   at com.documentum.web.contentxfer.DFCOperationSupport.execute(DFCOperationSupport.java:61)
   at com.documentum.web.contentxfer.ContentTransferService.execute(ContentTransferService.java:377)
   at com.documentum.web.contentxfer.JobAdapter.execute(JobAdapter.java:108)
   at com.documentum.job.async.AsyncJobManager$AsyncTimerJob.executeJob(AsyncJobManager.java:236)
   at com.documentum.job.async.AsyncJobManager$AsyncTimerJob.run(AsyncJobManager.java:215)
   at java.util.TimerThread.mainLoop(Timer.java:512)
   at java.util.TimerThread.run(Timer.java:462)
03.01.2014 10:20:34 *ERROR* SaveToZipFile: No JAXBElement has been created for this part, yet! (SaveToZipFile.java, line 304)
javax.xml.bind.JAXBException: No JAXBElement has been created for this part, yet!
   at org.docx4j.openpackaging.parts.JaxbXmlPart.marshal(JaxbXmlPart.java:327)
   at org.docx4j.openpackaging.parts.JaxbXmlPart.marshal(JaxbXmlPart.java:301)
   at org.docx4j.openpackaging.io.SaveToZipFile.saveRawXmlPart(SaveToZipFile.java:247)
   at org.docx4j.openpackaging.io.SaveToZipFile.saveRawXmlPart(SaveToZipFile.java:196)
   at org.docx4j.openpackaging.io.SaveToZipFile.savePart(SaveToZipFile.java:420)
   at org.docx4j.openpackaging.io.SaveToZipFile.addPartsFromRelationships(SaveToZipFile.java:383)
   at org.docx4j.openpackaging.io.SaveToZipFile.savePart(SaveToZipFile.java:438)
   at org.docx4j.openpackaging.io.SaveToZipFile.addPartsFromRelationships(SaveToZipFile.java:383)
   at org.docx4j.openpackaging.io.SaveToZipFile.save(SaveToZipFile.java:166)
   at eu.ema.dream.sbo.docxinjection.EMADocxInjection.convertToByteArray(EMADocxInjection.java:255)
   at eu.ema.dream.sbo.docxinjection.EMADocxInjection.setDocxID(EMADocxInjection.java:305)
   at eu.ema.dream.sbo.docxinjection.EMADocxInjection.setDocxID(EMADocxInjection.java:85)
   at eu.ema.dream.bof.type.EMADocument.doSave(EMADocument.java:189)
   at com.documentum.fc.client.DfPersistentObject.saveEx(DfPersistentObject.java:912)
   at com.documentum.fc.client.DfPersistentObject.save(DfPersistentObject.java:907)
   at eu.ema.dream.bof.type.EMADocument___PROXY.save(EMADocument___PROXY.java)
   at com.documentum.operations.nodeactions.inbound.DfCheckinObject.checkin(DfCheckinObject.java:235)
   at com.documentum.operations.nodeactions.inbound.DfCheckinObject.execute(DfCheckinObject.java:39)
   at com.documentum.operations.steps.impl.OperationStep.executeStep(OperationStep.java:163)
   at com.documentum.operations.steps.impl.OperationStep.execute(OperationStep.java:41)
   at com.documentum.operations.impl.OperationExecutionEngine.execute(OperationExecutionEngine.java:51)
   at com.documentum.operations.DfOperation.execute(DfOperation.java:401)
   at com.documentum.operations.inbound.impl.InboundOperation.execute(InboundOperation.java:104)
   at com.documentum.operations.inbound.DfImportOperation.execute(DfImportOperation.java:96)
   at com.documentum.web.contentxfer.DFCOperationSupport.execute(DFCOperationSupport.java:61)
   at com.documentum.web.contentxfer.ContentTransferService.execute(ContentTransferService.java:377)
   at com.documentum.web.contentxfer.JobAdapter.execute(JobAdapter.java:108)
   at com.documentum.job.async.AsyncJobManager$AsyncTimerJob.executeJob(AsyncJobManager.java:236)
   at com.documentum.job.async.AsyncJobManager$AsyncTimerJob.run(AsyncJobManager.java:215)
   at java.util.TimerThread.mainLoop(Timer.java:512)
   at java.util.TimerThread.run(Timer.java:462)


Any help would be much appreciated

Re: Convert to ByteArrayOutputStream

PostPosted: Fri Jan 03, 2014 9:47 pm
by andyflint
Have just noticed that I have probably posted this issue in the wrong forum as I will be deploying the docx4j application in tomcat and weblogic if I can get it to work and there seems to be another area for deploying applications to these containers.

So apologies for that

Andy

Re: Convert to ByteArrayOutputStream

PostPosted: Fri Jan 03, 2014 10:14 pm
by jason
andyflint wrote:The error that I am getting is basically a class loader issue when trying to load org/docx4j/jaxb/mc-preprocessor.xslt which I can see in the jar but because I am running this is a web container my class can't find the xslt in the class path and is not using the manifest.


That seems weird. Could you please verify that org/docx4j/jaxb/mc-preprocessor.xslt is in your docx4j jar file. If not, where did you get it from?

Re: Convert to ByteArrayOutputStream

PostPosted: Fri Jan 03, 2014 10:27 pm
by andyflint
Hi Jason

Yes the xslt is definitely in the jar. But the problem might be more to do with the way Documentum works which is the application that I am using.

The jars that I am using from docx4j are added to libraries and when the Documentum application is invoked that jars are downloaded to a cache and the cloasses are loaded from there. Now this seems to work fine for packages but not for files contained within the jar.

By the way this works fine when I run the application in eclipse but the problem occurs when I am running the application within tomcat and calling it using Documentum's business objects.

Andy

Re: Convert to ByteArrayOutputStream

PostPosted: Sat Jan 04, 2014 6:21 am
by jason
Hi Andy

Could you please explain in a little more detail what Documentum product you are using exactly, and how this relates to Tomcat?

How is Documentum invoking Tomcat, and what is Tomcat's response supposed to be? I don't understand how Documentum would be affecting Tomcat's behaviour, assuming it is standard Tomcat. What version?

cheers .. Jason

Re: Convert to ByteArrayOutputStream

PostPosted: Sat Jan 04, 2014 8:36 pm
by andyflint
Ok

Documentum is a content management system that is largely written in Java. The UI runs on a web container such as Tomcat and web logic and there is a separate content server or repository where the documents are stored.

The web client talks to the content server via a java class library known as DFC which is basically a java API.

Now, the way documentum works is that you have documents which are types which form a hierarchical structure and these types can have business objects (Known ad TBO Type Based Objects) which are basically java classes that can be overridden with a custom TBO. When a user accesses or creates a type using the UI the TBO is downloaded to a cache. The key thing here is that the TBO and its supporting libraries and jars are stored in the repository and these are also downloaded when the TBO is called

For the customisation the requirement is to automatically set particular fields within the document which is where docx4j comes in. Using DFC I can get and set the content using an api call that gets the content as a byteArrayStream and then sets the updated content.

The solution almost works but the issue arises when I try to generate the byte array output stream I think the key to the problem is class loading from the cache and the dependencies. I have solved some of the issues by placing the xalan serialise jars in the Tomcat\lib directory(which i not an ideal way forward). However, the above issue still occurs and it seems to be having a problem locating an xslt contained within the docx4j.jar or this might be a generic problem that is surfacing due to some deeper issue

For the application Tomcat is just as container and the version is 1.6.

Hope this helps

Andy

Re: Convert to ByteArrayOutputStream

PostPosted: Sun Jan 05, 2014 7:16 am
by jason
docx4j 3.0's ResourceUtils contains:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
    public static java.io.InputStream getResource(String filename) throws java.io.IOException
    {
        // Try to load resource from jar.
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        if (loader == null) {  // IKVM (v.0.44.0.5) doesn't set context classloader
            loader = ResourceUtils.class.getClassLoader();
        }
       
        java.net.URL url = loader.getResource(filename);
 
Parsed in 0.018 seconds, using GeSHi 1.0.8.4


So you need to set the context class loader before doing docx4j stuff:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
ClassLoader tccl = Thread.currentThread().getContextClassLoader();
try {
    ClassLoader cl = getClass().getClassLoader();
    Thread.currentThread().setContextClassLoader(cl);
    // .. do DFS stuff
} finally {
    Thread.currentThread().setContextClassLoader(tccl);
}
 
Parsed in 0.014 seconds, using GeSHi 1.0.8.4


See http://donr7n.wordpress.com/2008/11/25/ ... of-module/
or page 17 of http://www.emc.com/collateral/software/ ... ork-wp.pdf
or EMC Documentum Foundation Classes Version 6.7 Development Guide page 148 (heading "Calling DFS, JAXB API, or other components from a BOF module")

Hope this helps ... by the way, I will shortly rename this thread "Documentum - resource not found", and move it to the deployment forum.

Re: Convert to ByteArrayOutputStream

PostPosted: Mon Jan 06, 2014 3:23 am
by andyflint
Thank you so much I will try that and get back you you via the forum.

Bye the way renaming and moving this thread is fine by me - I released that I had put it in the wrong place anyway.

Andy

Re: Convert to ByteArrayOutputStream

PostPosted: Mon Jan 06, 2014 9:41 pm
by andyflint
Hi Jason

Fantastic that seems to have sorted it and there was I assuming that the problem was a bug in docx4J.

Well thank you so much for your time a patients in helping me sort this problem out although going forward I am sure that I will find other issues that I need help with ;)

Thank you

Andy

Re: Convert to ByteArrayOutputStream

PostPosted: Tue Jan 07, 2014 9:36 pm
by jason
Hi Andy, Glad to hear that addressed the issue; thanks for reporting back. cheers .. Jason

Re: Convert to ByteArrayOutputStream

PostPosted: Thu Nov 03, 2016 3:56 pm
by SamFrnd
Hi Jason,

I have the same issue as discussed in the forum. However, in this case the code is running on the UCM instance on UNIX server.
The docx4j-3.2.2.jar is present in the lib folder. The class path is set as path/lib/docx4j-3.2.2.jar.

I have tried setting the context class loader but the code is still not able to load the mc-preprocessor.xslt file from the docx4j-3.2.2.jar.

Could you please assist. Could you please let me know where exactly the class loader code should be set in this structure. Any help is greatly appreciated.

The following code structure is deployed.
com/web/content/docx4j - This has the class files to write the header/footer and tables to the word document

Adap.class

public class Adap {
private org.docx4j.wml.ObjectFactory factory = null;
private WordprocessingMLPackage pkg = null;

private Adap() {
}
private static Adapter adap = new Adapter();

public static Adapter getInstance() {
return adapter;
}

public ObjectFactory getObjFactory() {
if (factory == null) {
factory = new ObjectFactory();
}
return factory;
}

public WordprocessingMLPackage getPackage(File file) {
try {
pkg = WordprocessingMLPackage.load(new FileInputStream(file));
} catch (Exception e) {
}
return pkg;
}

Table.Class
package com.web.content.docx4j;
public Tbl getFirstTable(ObjectFactory factory, WordprocessingMLPackage pkg) {
Tbl headerTable = null;
try {
List<Object> tbllst = getAllElementFromObject(pkg
.getMainDocumentPart().getContents(), Tbl.class);
}

com/main/content/main - This has the Main.class that calls the methods from the class files present in com/web/content/docx4j folder.
The Main.class has the code to start the process.

import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.wml.ObjectFactory;
import org.docx4j.wml.Tbl;

public void writewordDocument(File file) {
try {
Adapter adap = Adapter.getInstance();
WordprocessingMLPackage pkg = adapter.getPackage(file);
ObjectFactory factory = adap.getObjFactory();
Tbl hdrTbl = TableUtil.getInstance().getFirstTable(factory, pkg);
if (hdrTbl != null) {
pkg.getMainDocumentPart().getContent()
.remove(hdrTbl.getParent());
}