Page 1 of 1

getXml method for XmlSignaturePart

PostPosted: Fri Apr 29, 2016 3:22 am
by travis
I am currently trying to store the xml from _xmlsignatures\sig1.xml. Using the code below, I search through the parts of the WordProcessingMLPackage until it finds a part with the content type of DIGITAL_SIGNATURE_XMLSIGNATURE_PART. Then, I cast the part as a XmlSignaturePart, but when I call the getXml() method of the XmlSignaturePart, it throws a MarshalException. While debugging, I've noticed that JaxbElement of the XmlSignaturePart is null and I believe that is the reason why it fails to marshal. I am wondering if there is anything that I am missing or overlooking, or can a XmlSignaturePart not be marshalled?

Code:
Code: Select all
try {
         XmlSignaturePart sigPart = new XmlSignaturePart();
         String sigXml = null;
         File file = new File (fileName);
         WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(file);
         Parts parts = wordMLPackage.getParts();
         HashMap<PartName, Part> partsMap = parts.getParts();
         for (PartName partName : partsMap.keySet()){
            Part p = partsMap.get(partName);
            if (p.getContentType().equals(ContentTypes.DIGITAL_SIGNATURE_XML_SIGNATURE_PART)){
               sigPart = (XmlSignaturePart) p;
               sigXml = sigPart.getXML();
            }      
         }
      } catch (Docx4JException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }


Error:
Exception in thread "main" java.lang.RuntimeException: javax.xml.bind.MarshalException
- with linked exception:
[com.sun.istack.internal.SAXException2: unable to marshal type "org.plutext.jaxb.xmldsig.SignatureType" as an element because it is missing an @XmlRootElement annotation]
at org.docx4j.XmlUtils.marshaltoString(XmlUtils.java:575)
at org.docx4j.openpackaging.parts.JaxbXmlPart.getXML(JaxbXmlPart.java:178)
at eci.edaexecute.signatureline.SignatureLineParse.main(SignatureLineParse.java:52)
Caused by: javax.xml.bind.MarshalException
- with linked exception:
[com.sun.istack.internal.SAXException2: unable to marshal type "org.plutext.jaxb.xmldsig.SignatureType" as an element because it is missing an @XmlRootElement annotation]
at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(Unknown Source)
at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.marshal(Unknown Source)
at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(Unknown Source)
at org.docx4j.XmlUtils.marshaltoString(XmlUtils.java:563)
... 2 more
Caused by: com.sun.istack.internal.SAXException2: unable to marshal type "org.plutext.jaxb.xmldsig.SignatureType" as an element because it is missing an @XmlRootElement annotation
at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.reportError(Unknown Source)
at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(Unknown Source)
at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsRoot(Unknown Source)
... 6 more

Re: getXml method for XmlSignaturePart

PostPosted: Fri Apr 29, 2016 8:59 pm
by jason
First off, just to note that v3.3.0 of Plutext's commercial Enterprise Ed contains digital signature support. You can download a trial from http://www.plutext.com/m/index.php/products

Now looking at v3.2.2 https://github.com/plutext/docx4j/blob/ ... ePart.java

XmlSignaturePart extends JaxbXmlPartXPathAware<JAXBElement<SignatureType>>

Because it has JAXBElement<SignatureType> that is, SignatureType is wrapped in JAXBElement, marshalling it shouldn't be an issue.

Evidently it is.

Workaround #1 You can work around it by using XmlUtils:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
/** Marshal to a String, for object
         *  missing an @XmlRootElement annotation.  */

        public static String marshaltoString(Object o, boolean suppressDeclaration, boolean prettyprint,
                        JAXBContext jc,
                        String uri, String local, Class declaredType)
 
Parsed in 0.015 seconds, using GeSHi 1.0.8.4


https://github.com/plutext/docx4j/blob/ ... .java#L650

For JAXBContext jc, use Context.jcXmlDSig

Workaround #2 Or, if you are working with the docx4j source code, you could add the @XmlRootElement annotation to org.plutext.jaxb.xmldsig.SignatureType

Re: getXml method for XmlSignaturePart

PostPosted: Tue May 03, 2016 8:28 am
by travis
Thank you very much for your reply. I ended up going with the first option, marshaltoString, and it solves the issue.