java-native-access/jna · error · java.io.IOException

Can't obtain InputStream for resourcePath

Error message

Can't obtain InputStream for resourcePath

What it means

For non-file URLs (e.g. inside a jar/zip served by a custom classloader), extractFromResourcePath opens the resource stream; if URL.openStream() returns null it throws IOException 'Can't obtain InputStream for <resourcePath>'. This means the URL resolved but its handler cannot deliver the content, so the native library cannot be unpacked.

Source

Thrown at src/com/sun/jna/Native.java:1230

        LOG.log(DEBUG, "Found library resource at {0}", url);

        File lib = null;
        if (url.getProtocol().toLowerCase().equals("file")) {
            try {
                lib = new File(new URI(url.toString()));
            }
            catch(URISyntaxException e) {
                lib = new File(url.getPath());
            }
            LOG.log(DEBUG, "Looking in {0}", lib.getAbsolutePath());
            if (!lib.exists()) {
                throw new IOException("File URL " + url + " could not be properly decoded");
            }
        }
        else if (!Boolean.getBoolean("jna.nounpack")) {
            InputStream is = url.openStream();
            if (is == null) {
                throw new IOException("Can't obtain InputStream for " + resourcePath);
            }

            FileOutputStream fos = null;
            try {
                // Suffix is required on windows, or library fails to load
                // Let Java pick the suffix, except on windows, to avoid
                // problems with Web Start.
                File dir = getTempDir();
                lib = File.createTempFile(JNA_TMPLIB_PREFIX, Platform.isWindows()?".dll":null, dir);
                if (!Boolean.getBoolean("jnidispatch.preserve")) {
                    lib.deleteOnExit();
                }
                LOG.log(DEBUG, "Extracting library to {0}", lib.getAbsolutePath());
                fos = new FileOutputStream(lib);
                int count;
                byte[] buf = new byte[1024];
                while ((count = is.read(buf, 0, buf.length)) > 0) {
                    fos.write(buf, 0, count);

View on GitHub (pinned to d036ad9781)

Solutions

  1. Unpack JNA so libjnidispatch resources are in a plain JAR/classpath directory rather than a nested JAR
  2. Use framework features that expose nested content (e.g. Spring Boot's repackaged loader compatibility, OSGi Bundle-NativeCode or fragment host for natives)
  3. Install the native library on disk and supply -Djna.boot.library.path to bypass resource extraction
  4. Set -Djna.tmpdir to a writable location and ensure no security policy prevents URL stream opening

Example fix

// maven-shade: keep jna resources at jar root instead of nested
// before
<filter><artifact>net.java.dev.jna:jna</artifact><excludes><exclude>com/sun/jna/**</exclude></excludes></filter>
// after
<filter><artifact>net.java.dev.jna:jna</artifact><includes><include>**</include></includes></filter>
Defensive patterns

Strategy: try-catch

Validate before calling

// probe the stream before relying on extraction
try (InputStream is = url.openStream()) {
    if (is == null) throw new IllegalStateException("Cannot open stream for " + url + " - nested/bundled jar?");
} catch (IOException e) { throw new IllegalStateException("Resource unreadable: " + url, e); }

Try / catch

try { Native.extractFromResourcePath(res, loader); } catch (IOException e) { if (String.valueOf(e.getMessage()).startsWith("Can't obtain InputStream")) { throw new IllegalStateException("Native JAR is nested (OSGi/boot-jar); unpack it or use jna.boot.library.path", e); } throw e; }

Prevention

When it happens

Trigger: extractFromResourcePath on a jar:/bundle:/resource: style URL where openStream yields null - typically a nested/bundled JAR (OSGi, one-jar, Spring Boot nested jars) whose handler cannot open the entry.

Common situations: Running inside OSGi or application servers where JNA's JAR is embedded in another bundle; Spring Boot executable jars with the default nested URL handler; proxy/security managers blocking stream opening.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12). Data as JSON: /api/errors/46263faaff2ad28d. Report an issue: GitHub.