Search code examples
javaosgiapache-poiclassloaderosgi-bundle

Load file from classpath using OPCPackage in OSGi environment


I'm trying to load a rather large .xslx file (29MB) to process in Java using POI.

Because of the uncompressed file size when reading the file in memory using an InputStream, I run into heap space issues.

As recommended on Stackoverflow, I make use of an OPCPackage to not have to load the entire file in memory.

I try to load the file using the OPCPackage open method. This method accepts:

  • File
  • InputStream (Cannot load file in inputstream - OutOfMemory)
  • Path

File option

Problem is that we are working in an OSGi environment, so when trying to create a File with the asset path. The asset path is in fact a link to the bundle

URL url = getClass().getClassLoader().getResource("/excel/file.xslx");
File file = new File(url.toURI()); // URI = bundle://449.124:/excel/file.xlsx

So following Exception occurs: java.lang.IllegalArgumentException: URI scheme is not "file"

Trying to use the URL path instead also is not successful:

File file = new File(url.getPath()); // Path= /excel/file.xslx
if(!file.exists()){
    // FILE DOES NOT EXIST
}

Path option

When I try to use the path open method, it cannot seem to resolve the path, since I always get following Exception: java.lang.IllegalStateException: Zip File is closed

opcPackage = OPCPackage.open(url.toURI().getPath()); // Path= /excel/file.xslx

Any ideas on how I can reference my file from within a bundle environment in order for it to load? Or am I missing something obvious here?


Solution

  • If you cannot process the input stream, then you could copy the input stream to a File in the bundle data area and then process that file.

    Resources in bundles do not stand alone on the file system, so you would need to "extract" them to a file if necessary.