You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@poi.apache.org by OLESEN Mark <ma...@faurecia.com> on 2015/07/17 16:29:17 UTC

XSLF create tables : Need help diagnosing odd behavior

I'm trying to figure out what is going awry with my use of XSLF.
It doesn't seem to be a POI issue per se, but maybe some weird interaction between libraries or calls?
I can't really figure out where to look.

The situation: I am providing a netbeans module for use within a commercial software (STARCCM) that itself is implemented using netbeans.
When using POI to create a pptx with tables, the content is not be added correctly. For testing, I am using a simple bit of common code (see below), but the results depend on how I call it.

If I call the PoiTests. runTest() method from a SystemAction (eg, from a menu or top component), the table gets generated with content (no issues). If, however, I use dynamically compiled and loaded java (they call it NeoScript) to call the code, the table gets generated but without any content. It gets even weirder though. If I use dynamic code to simply open a top component that embeds the original SystemAction, the table is generated but without content!.
It appears that involving the NeoScript mechanism anywhere in the calling chain it somehow influences the behavior of POI (maybe xmlbeans?) and inhibits proper filling of the table content. 

I can unfortunately not simply avoid the dynamic code bits, since these are my only entry point for interacting with STARCCM for batch processes. I've contacted the vendor (cdadapco), but they couldn't provide any answers at the moment.

Does anyone have any ideas or even guesses about what might be going on here? What could be going on behind the scenes within POI that could even slightly explain this behaviour? I naturally suspect xmlbeans, but for no reason other than everything about it is a mystery to me.

Thanks in advance for any guesses, hints, suggestions, etc.
Maybe someone has experienced similar odd interactions with other software that might help put me on the right path.

/mark

-----

public class PoiTests
{
    public static void runTest(String outputName)
    {
        System.out.println("run test with output to " + outputName);
        XMLSlideShow ppt = new XMLSlideShow();
        XSLFSlide slide = ppt.createSlide();
        tableTest0(slide.createTable());

        try
        {
            FileOutputStream os = new FileOutputStream(outputName);
            ppt.write(os);
        }
        catch (IOException ignore)
        {}
    }

    public static void tableTest0(XSLFTable table)
    {
        final int ncols = 4;
        final int nrows = 2;

        table.setAnchor(new Rectangle2D.Double(100, 100, 0, 0));

        for (int rowI=0; rowI < nrows; ++rowI)
        {
            XSLFTableRow row = table.addRow();

            for (int colI=0; colI < ncols; ++colI)
            {
                XSLFTableCell cel = row.addCell();
                cel.addNewTextParagraph().addNewTextRun().setText
                (
                    "r" + rowI + " c" + colI
                );
            }
        }
    }
}

This electronic transmission (and any attachments thereto) is intended solely for the use of the addressee(s). It may contain confidential or legally privileged information. If you are not the intended recipient of this message, you must delete it immediately and notify the sender. Any unauthorized use or disclosure of this message is strictly prohibited.  Faurecia does not guarantee the integrity of this transmission and shall therefore never be liable if the message is altered or falsified nor for any virus, interception or damage to your system.


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@poi.apache.org
For additional commands, e-mail: dev-help@poi.apache.org


RE: XSLF create tables : Need help diagnosing odd behavior

Posted by OLESEN Mark <ma...@faurecia.com>.
Hi Andi (and others),

I can finally report some moderate success and at least I have a workaround (hack).

Tracing the class-loader information shows that "SchemaGlobalElementImpl" isn't being loaded and the CTTable$Factory fallback is used instead.
I don't understand why this happening, but just try to deal with the result.

Rather than patching up the XmlObject in the XSLFTable constructor, I've taken the easier route of fixing the graphical frame to have the correct table contents, and calling this fix before writing out the presentation contents.

Until the underlying problem gets solved, the following workaround code can be used by any others with a similar situation.

Cheers,
/mark
--------

/**
 * Handle faulty XSLFTable by splicing in the CTTable contents.
 *
 * These faults are associated with pesky XmlBeans bug (Bugzilla #49934 - see XSLFTable constructor),
 * which is somehow also provoked when the STARCCM NeoDynamicClassLoader is involved (eg, StarMacro).
 *
 * @return true if a repair was needed, false otherwise
 */
public static boolean fixupTable(XSLFTable table)
{
    // check for bug
    //
    // without bug:  org.openxmlformats.schemas.drawingml.x2006.main.impl.CTTableImpl
    // with    bug:  org.apache.xmlbeans.impl.values.XmlAnyTypeImpl

    XmlCursor cursor = table.getXmlObject().getGraphic().getGraphicData().newCursor();
    boolean hasBug =
    (
        cursor.toChild(new QName("http://schemas.openxmlformats.org/drawingml/2006/main", "tbl"))
     && cursor.getObject() instanceof org.apache.xmlbeans.impl.values.XmlAnyTypeImpl
    );

    if (hasBug)
    {
        // remove old tbl content
        cursor.removeXmlContents();

        // step into tbl element
        cursor.toNextToken();

        // copy in CTTable content
        // - introduces some leading spaces into the xml,
        //   but this is obviously cosmetic
        XmlCursor input = table.getCTTable().newCursor();
        input.toStartDoc();
        input.copyXmlContents(cursor);

        input.dispose();
    }

    cursor.dispose();
    return hasBug;
} 

This electronic transmission (and any attachments thereto) is intended solely for the use of the addressee(s). It may contain confidential or legally privileged information. If you are not the intended recipient of this message, you must delete it immediately and notify the sender. Any unauthorized use or disclosure of this message is strictly prohibited.  Faurecia does not guarantee the integrity of this transmission and shall therefore never be liable if the message is altered or falsified nor for any virus, interception or damage to your system.


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@poi.apache.org
For additional commands, e-mail: dev-help@poi.apache.org


RE: XSLF create tables : Need help diagnosing odd behavior

Posted by OLESEN Mark <ma...@faurecia.com>.
Hi Andi,

First results:
- Replacing poi-ooxml-schemas with ooxml-schemas didn't show any difference.
- Didn't figure out how the xmlbeans debugging works. I add the following, 
        XBeanDebug.enable(XBeanDebug.TRACE_SCHEMA_LOADING);
        XBeanDebug.log("Starting with " + outputName);
but this just emits the single log message without tracing much of anything.
I added these lines before creating the XMLSlideShow.

The netbeans module class paths looks identical for both cases - as reported by org.netbeans.core.startup.Main.getModuleSystem().getModuleJars()
and all the jars are available:

  {path}/modules/org-marko.jar
  {path}/modules/ext/poi-ooxml-3.12-20150511.jar
  {path}/modules/ext/xmlbeans-2.6.0.jar
  {path}/modules/ext/poi-3.12-20150511.jar
  {path}/modules/ext/ooxml-schemas-1.1.jar
  {path}/modules/ext/poi-scratchpad-3.12-20150511.jar

I can't actually figure out how to interrogate the class-loaders directly to find out what it can possibly resolve.

However, using a basic printf-style debugging, I was able to find this interesting behaviour.
The tables' CTTable representation are in both cases (good and bad table generation) identical, but their CTGraphicalObjectFrame are radically different.
In the bad generation, the table graphic representation is empty - it appears to only be getting the prototype information.

Digging some more, it looks like some variant of the bug 49934 is hitting (saw the comment in XSLFTable) ... despite using the full ooxml-schemas.

With some more printf-debugging:
for (XmlObject rs : table.getXmlObject().getGraphic().getGraphicData().selectPath("declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' ./a:tbl")) {
            System.out.println("class: " + rs.getClass());
            System.out.println(rs.toString());
}
       
Reveals the bad table (called via macro):
class: org.apache.xmlbeans.impl.values.XmlAnyTypeImpl
<xml-fragment xmlns:main="http://schemas.openxmlformats.org/drawingml/2006/main">
  <main:tblPr/>
  <main:tblGrid/>
</xml-fragment>

Whereas the good table (called directly from action) has
class: org.openxmlformats.schemas.drawingml.x2006.main.impl.CTTableImpl
with the appropriate content.

I still can't figure if this is truly a caller issue, or if bug 49934 is still partly the culprit.
In the XSLFTable constructor, there is a hack to catch exactly this case (XmlAnyTypeImpl being returned).
In this case a new XmlObject is created from the factory to manage the CTTable, but it looks to me that this xml-fragment is not being re-associated with the graphic object frame, which should be its parent.
This could explain why the CTTable looks fine for both cases, but the final output doesn't.

Maybe the getXmlObject() itself need to know about the hack? Ie,

if (hackedTable)
{
   orig = super.getXmlObject()
   // replace table element with CTTable fragement
}


Cheers,
/mark

This electronic transmission (and any attachments thereto) is intended solely for the use of the addressee(s). It may contain confidential or legally privileged information. If you are not the intended recipient of this message, you must delete it immediately and notify the sender. Any unauthorized use or disclosure of this message is strictly prohibited.  Faurecia does not guarantee the integrity of this transmission and shall therefore never be liable if the message is altered or falsified nor for any virus, interception or damage to your system.


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@poi.apache.org
For additional commands, e-mail: dev-help@poi.apache.org


Re: XSLF create tables : Need help diagnosing odd behavior

Posted by Andreas Beeker <ki...@apache.org>.
Hi Mark,

my guess is, that's a xmlbeans/classloading issue too.

I would try the following:
- replace the poi-ooxml-schemas with the ooxml-schemas [1]
- check how the netbeans classloading mechanism is working
   and try to put the libs in a different context. Maybe temporarily
   try the libs directory of the jre. [2]
- dump the loaded classes - see the OOXMLLite class
- activate xmlbeans logging - see the XBeanDebug class  [3]

Best wishes,
Andi

[1] http://poi.apache.org/faq.html#faq-N10025
[2] http://stackoverflow.com/questions/2859471/what-is-the-exact-way-to-use-endorsed-directory-in-jdk1-6
[3] http://svn.apache.org/repos/asf/xmlbeans/trunk/src/common/org/apache/xmlbeans/impl/common/XBeanDebug.java




---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@poi.apache.org
For additional commands, e-mail: dev-help@poi.apache.org