Page 1 of 1

multiple WML load and MainDocumentPart NullPointer

PostPosted: Wed Apr 06, 2011 4:37 am
by Lars
Hi Jason,

today I've got a really strange problem with docx4j, I hope you can help us...

Situation:
We have a document and inside this document some customXML elements which make our application to load some other documents under some conditions. The documents are stored at a server (fHost in the code). The application works fine as long as we are not trying to load 2 or more of this extra documents.

The code that loads the files:
Code: Select all
...
final LoadFromZipNG fileLoader = new LoadFromZipNG();
...
try {
  inputStream = fHost.getSubTemplateAsStream(subReport.getCustomXmlPr().getAttr(IDocxConstants.ATTR_FACH_ID).getVal());
  wordComponent = (WordprocessingMLPackage) fileLoader.get(inputStream);
} catch (final Docx4JException e) {
  throw new TextProcessorException("Unable to open docx file from stream", e); //$NON-NLS-1$
} catch (final IOException e) {
  throw new TextProcessorException("failed to open the template", e); //$NON-NLS-1$
} finally {
  IOUtils.closeQuietly(inputStream);
}


The application runs and gets the first customXML element, it loads it and processes everything like it should. Then the applikation comes to the second customXML element, it loads it and tries to initialize the process. One part of the initialization is this:

Code: Select all

...
public class CustomXmlFinder extends CallbackImpl {
  ...
  public void walkJAXBElements(Object parent) {
  List<?> children = getChildren(parent);
  if (children != null) {
    for (Object child: children) {
    child = XmlUtils.unwrap(child);
    if (!this.fTrigger) {
    if (child == this.fChild) {
    this.fTrigger = true;
    }
  } else {
  this.apply(child);
  }
  if (this.shouldTraverse(child)) {
  walkJAXBElements(child);
}
}
}
}
...

final CustomXmlFinder rootElemFinder = new CustomXmlFinder();

rootElemFinder.walkJAXBElements(wmlPackage.getMainDocumentPart().getJaxbElement().getBody());



When reaching the last line during the initialization of the second document the applikation crashes.

I attached a succes.log and the failure.log file for you to see where (and why?) docx4j does't load the second docx file in the right way. After analysing these logs we found out that during the second loading of a docx file the whole process of loading stops after about 20% and we really have no idea why. At this point, we have a WMLPackage (wordComponent in the code) but as I said it is not really a WMLPackage cause lots of the parts in it are null and thats why the walkJAXBElement method produces a NullPointer Exception.

I forgot something:
The docx files are no issue. I tried the procedure with other docx files and with another order of the docx files. It is allways the second loading procedure that crashes no matter what file should be loaded. The first allways loads fine.


Thanks for your help!


kind regards,
Lars

Re: multiple WML load and MainDocumentPart NullPointer

PostPosted: Wed Apr 06, 2011 10:09 am
by jason
Hi Lars

I've had a look at this, but have nothing to suggest so far. (Are you sure the NPE (which I can't see) has nothing to do with it?)

You already have DEBUG level logging turned on in the relevant classes...

Can you produce a test which exhibits the problem which is isolated from your larger system?

Re: multiple WML load and MainDocumentPart NullPointer

PostPosted: Wed Apr 06, 2011 8:35 pm
by Lars
Hi,

we made this test and analized the whole code again, finally we found the problem by fluke.

this is how our application is (was ;-) ) designed:
Code: Select all
...
final LoadFromZipNG fileLoader = new LoadFromZipNG();
...
for (all sub documents) {
  try {
  ...
  wordComponent = (WordprocessingMLPackage) fileLoader.get(inputStream);
  ...
  }
  ...
}


and this is how it works:
Code: Select all
for (all sub documents) {
  final LoadFromZipNG fileLoader = new LoadFromZipNG();
  try {
  ...
  wordComponent = (WordprocessingMLPackage) fileLoader.get(inputStream);
  ...
  }
  ...
}


The class LoadFromZipNG is obviously a dynamic one but you can only use it once. If we create a new instance in every run of the process we have no more problems.

I suggest to change the class to static or make it work like a real dynamic class because from my point of view others will fall into this trap.


regards,
Lars

Re: multiple WML load and MainDocumentPart NullPointer

PostPosted: Thu Apr 07, 2011 12:40 am
by jason
I'm glad you worked that out.

Looks like it would be easy enough to make the class static.

Re: multiple WML load and MainDocumentPart NullPointer

PostPosted: Sat Apr 16, 2011 1:03 pm
by jason