When trying to export some 900 powerpoint slides I get some 18 exceptions in the process producing image files of 0 bytes size. Here are some example exception reasons: java.lang.IllegalArgumentException: Currently only SolidPaint is supported! at org.apache.poi.xslf.usermodel.XSLFTextRun.setFontColor(XSLFTextRun.java:153) java.lang.NullPointerException at org.apache.poi.xslf.usermodel.XSLFHyperlink.getAddress(XSLFHyperlink.java:57) java.lang.NullPointerException at org.apache.poi.xslf.usermodel.XSLFTextRun.copy(XSLFTextRun.java:602) java.lang.NullPointerException at java.util.TreeMap.getEntry(TreeMap.java:347) at java.util.TreeMap.get(TreeMap.java:278) at org.apache.poi.openxml4j.opc.PackageRelationshipCollection.getRelationshipByID(PackageRelationshipCollection.java:286) at org.apache.poi.openxml4j.opc.PackagePart.getRelationship(PackagePart.java:392) at org.apache.poi.xslf.usermodel.XSLFSheet.importBlip(XSLFSheet.java:596) There is only a bit of variety and you might consider this a different bugs. From my point of view the main issue is to make sure that suche detail errors in part of the rendering process should not necessarily make the whole rendering fail. It would be good to have an option for this (or is there already such a thing?.
The first workaround I found is to change copy in XSLFTextRun.java like this: double srcFontSize = 12.0; try { srcFontSize=r.getFontSize(); } catch (NullPointerException npe) { npe.printStackTrace(); } getFontSize is the culprit but in my eclipse debuggin environment it does not show with it's details in the stacktrace.
The Nullpointer Exception seems to be nasty since it doesn't seem to have a stacktrace. I am currently looking at https://stackoverflow.com/questions/2411487/nullpointerexception-in-java-with-no-stacktrace and http://jawspeak.com/2010/05/26/hotspot-caused-exceptions-to-lose-their-stack-traces-in-production-and-the-fix/ to find out why
Its much simpler then I though. Assigning getFontSize() Double result to a double calls for trouble if the Double may be null. I suggest to not only change the Declaration to Double srcFontSize but also make the getFontSize function itself more robust. I am going to prepare a pull request for this.
Here is a manuall git diff for a start: +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java @@ -41,6 +41,7 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun; import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor; import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeStyle; import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextField; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont; @@ -206,9 +207,18 @@ public class XSLFTextRun implements TextRun { @Override public Double getFontSize(){ double scale = 1; - CTTextNormalAutofit afit = getParentParagraph().getParentShape().getTextBodyPr().getNormAutofit(); - if(afit != null) { - scale = (double)afit.getFontScale() / 100000; + XSLFTextParagraph pp = getParentParagraph(); + if (pp!=null) { + XSLFTextShape ps = pp.getParentShape(); + if (ps!=null) { + CTTextBodyProperties tbp = ps.getTextBodyPr(); + if (tbp!=null) { + CTTextNormalAutofit afit = tbp.getNormAutofit(); + if(afit != null) { + scale = (double)afit.getFontScale() / 100000; + } + } + } } CharacterPropertyFetcher<Double> fetcher = new CharacterPropertyFetcher<Double>(_p.getIndentLevel()){ @@ -222,7 +232,8 @@ public class XSLFTextRun implements TextRun { } }; fetchCharacterProperty(fetcher); - return fetcher.getValue() == null ? null : fetcher.getValue()*scale; + Double result=fetcher.getValue() == null ? null : fetcher.getValue()*scale; + return result; } /** @@ -589,7 +600,7 @@ public class XSLFTextRun implements TextRun { setFontColor(srcFontColor); } - double srcFontSize = r.getFontSize(); + Double srcFontSize=r.getFontSize(); if(srcFontSize != getFontSize()){ setFontSize(srcFontSize); }
see pull request https://github.com/apache/poi/pull/92 for a fix
Thank you for providing the patch. Fixed long ago as part of bug 62393 and r1831974