Skip to content
This repository

NullPointerException in com.xmlcalabash.util.XProcURIResolver #35

Closed
raducoravu opened this Issue March 14, 2012 · 5 comments

2 participants

Radu Coravu Norman Walsh
Radu Coravu

I have an XProc with code like this:
.................
<p:xsl-formatter content-type="application/pdf">
<p:with-option name="href" select="$pdf-file"></p:with-option>
<p:with-param name="UserConfig" select="$fop-config"/>
</p:xsl-formatter>
...................

which tries to generate PDF using Apache FOP.

The FOP configuration file looks like this:

<fop version="1.0">
<accessibility>true</accessibility>
<target-resolution>240</target-resolution>
<renderers>
<renderer mime="application/pdf">
<fonts>
<auto-detect/>
</fonts>
</renderer>
</renderers>
</fop>

When transforming, the output fails with a message like:

Failed to process FO document with FOP null

which is actually generated by:

Caused by: java.lang.NullPointerException
at java.net.URI$Parser.parse(Unknown Source)
at java.net.URI.(Unknown Source)
at com.xmlcalabash.util.XProcURIResolver.resolve(Unknown Source)
at org.apache.fop.apps.FOURIResolver.resolve(FOURIResolver.java:179)
at org.apache.fop.apps.FopFactory.resolveURI(FopFactory.java:753)
at org.apache.fop.apps.FOUserAgent.resolveURI(FOUserAgent.java:425)
at org.apache.fop.render.DefaultFontResolver.resolve(DefaultFontResolver.java:44)
at org.apache.fop.fonts.FontLoader.openFontUri(FontLoader.java:154)
at org.apache.fop.fonts.truetype.TTFFontLoader.read(TTFFontLoader.java:94)
at org.apache.fop.fonts.truetype.TTFFontLoader.read(TTFFontLoader.java:84)
at org.apache.fop.fonts.FontLoader.getFont(FontLoader.java:190)
at org.apache.fop.fonts.FontLoader.loadFont(FontLoader.java:139)
at org.apache.fop.fonts.LazyFont.load(LazyFont.java:134)
at org.apache.fop.fonts.LazyFont.getAscender(LazyFont.java:241)
at org.apache.fop.fonts.Font.getAscender(Font.java:106)
at org.apache.fop.layoutmgr.BlockLayoutManager.initialize(BlockLayoutManager.java:87)
at org.apache.fop.layoutmgr.AbstractLayoutManager.getChildLM(AbstractLayoutManager.java

So the method:

public Source resolve(String href, String base) throws TransformerException {

receives a NULL base from Apache FOP and tries to make an URI out of it:

URIResolver(file:/C:/Windows/FONTS/arial.ttf,null)

So you should take into account on the URIResolver the possibility of a NULL base.

The workaround is simple, a "./" can be specified in the configuration file in order for Apache FOP to also specify the base in the URI resolver and avoid the NPE.

One more improvement which would help debug such cases would be that in the method:

com.xmlcalabash.library.XSLFormatter.run()

when an exception is caught, it should not be ignored but instead be provided as the cause of the thrown XProcException.

Norman Walsh
Owner
ndw commented March 15, 2012

I believe XSLFormatter.run does include the underlying exception:

        try {
            out = new BufferedOutputStream(new FileOutputStream(output));
            provider.format(source.read(),out,contentType);
        } catch (XProcException e) {
            throw e;
        } catch (Exception e) {
            throw new XProcException(step.getNode(), "Failed to process FO document", e);
        } finally {
            out.close();
        }

If you can provide a complete pipeline that demonstrates the NPE problem, I'll see what I can do.

I'm not sure what the right semantic is when the base is null.

Radu Coravu

Hi Norm,

About wrapping the original exception, I was referring to this part of the XSLFormatter:

    FoProcessor provider = null;
    for (String className : foClasses) {
        if (provider == null) {
            try {
                provider = (FoProcessor) Class.forName(className).newInstance();
                provider.initialize(runtime,step,options);
            } catch (NoClassDefFoundError ncdfe) {
                provider = null;
            } catch (Exception e) {
              //THE NPE IS CAUGHT HERE...........................
                provider = null;
            }
        }
    }

    if (provider == null) {
        throw new XProcException(step.getNode(), "Failed to instantiate FO provider");
    }

About the approach in the XProcURIResolver when the base is NULL, the Xerces URI Resolver has the code something like:
.....
if (base==null) {
url = new URL(uri);
result = url.toString();
} else {
URL baseURL = new URL(base);
url = (href.length()==0 ? baseURL : new URL(baseURL, uri));
result = url.toString();
}
....

Regards,
Radu

Norman Walsh
Owner
ndw commented March 15, 2012

Ah. Ok. I'd already reworked part of that code in XSLFormatter which partially corrected the problem. I improved it some more :-)

And I attempted to do the Xerces compatible thing in resolve()

Radu Coravu

Thanks, Norm.

Norman Walsh ndw closed this May 19, 2012
Norman Walsh
Owner
ndw commented May 19, 2012

I hope this is fixed now. Please reopen if it isn't.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.