Set FopFactoryBuilder baseURI to jar classpath
Asked Answered
B

2

9

I'm upgrading an Apache FOP 1.0 project to Apache FOP 2.1. In this project, all necessary files are packaged within the jar file.

I've added the new FopFactoryBuilder to generate a FopFactory

    FopFactoryBuilder builder = new FopFactoryBuilder(new File(".").toURI());
    builder = builder.setConfiguration(config);
    fopFactory = builder.build();

but all my resouces are loaded from the relative path on my file system, not from the jar. How can I set the baseURI to the jar's classpath?

Thanks

Beniamino answered 15/1, 2017 at 14:5 Comment(0)
H
11

We also used FOP 2.1 and want to achieve, that images inside jars-classpath will be found. Our tested and used solution is the following:

Create your own ResourceResolver

import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.net.URL;

import org.apache.fop.apps.io.ResourceResolverFactory;
import org.apache.xmlgraphics.io.Resource;
import org.apache.xmlgraphics.io.ResourceResolver;

public class ClasspathResolverURIAdapter implements ResourceResolver {

  private final ResourceResolver wrapped;


  public ClasspathResolverURIAdapter() {
    this.wrapped = ResourceResolverFactory.createDefaultResourceResolver();
  }


  @Override
  public Resource getResource(URI uri) throws IOException {
    if (uri.getScheme().equals("classpath")) {
      URL url = getClass().getClassLoader().getResource(uri.getSchemeSpecificPart());

      return new Resource(url.openStream());
    } else {
      return wrapped.getResource(uri);
    }
  }

  @Override
  public OutputStream getOutputStream(URI uri) throws IOException {
    return wrapped.getOutputStream(uri);
  }

}
  1. Create the FOPBuilderFactory with your Resolver
FopFactoryBuilder fopBuilder = new FopFactoryBuilder(new File(".").toURI(), new ClasspathResolverURIAdapter());
  1. Finally address your image
<fo:external-graphic src="classpath:com/mypackage/image.jpg" />

Because you use our own Resolver it is possible to do every lookup which you want.

Hearten answered 4/4, 2017 at 19:26 Comment(4)
I bumped into a similar problem (wanted to load everything from inside the jar, config and even fonts to embed into the pdf), and created a working demo based on JaxtOr's post. Here it is: github.com/riskop/fop_testDewaynedewberry
Please change (uri.getScheme().equals("classpath")) to "classpath".equals(uri.getScheme())) to avoid NullPointerException for relative URIsThrove
amazing solution, thank you so much for sharing it.Coalesce
Unfortunately this solution does not work since 2.7, fonts that are being loaded from .xconf will throw the following: unknown protocol: classpath: java.net.MalformedURLException: unknown protocol: classpathDonelu
S
2

By specifying the URL as a classpath URL like:

<fo:external-graphic src="classpath:fop/images/myimage.jpg"/>

In this example the file is a resource in the resource-package fop.images but the actual file gets later packed to some entirely different place inside the JAR, which is - however - part of the classpath, so the lookup as above works.

Salty answered 14/3, 2017 at 9:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.