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

File URL url could not be properly decoded

Error message

File URL url could not be properly decoded

What it means

When the resolved resource URL uses the file protocol, JNA converts it to a File and checks existence; if the file the URL points to does not exist (e.g. the URL was built from a path with characters that failed URI decoding, or the target was deleted), it throws IOException 'File URL <url> could not be properly decoded'. It guards against silently using a wrong file path obtained from a malformed file: URL.

Source

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

            String path = System.getProperty("java.class.path");
            if (loader instanceof URLClassLoader) {
                path = Arrays.asList(((URLClassLoader)loader).getURLs()).toString();
            }
            throw new IOException("Native library (" + resourcePath + ") not found in resource path (" + path + ")");
        }
        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();
                }

View on GitHub (pinned to d036ad9781)

Solutions

  1. Move the JNA JAR/classpath entry to a path without spaces or special characters, or properly URL-encode the path
  2. Verify the file in the message exists at the decoded path; fix the classpath entry if it points at a stale location
  3. Rebuild/redeploy the artifact if the referenced file was removed (stale deployment)
  4. As a workaround, install the native library on disk and load via jna.boot.library.path rather than resource extraction

Example fix

// before
URL url = new File("/opt/My Lib/jna.jar").toURL(); // legacy, unencoded
// after
URL url = new File("/opt/My Lib/jna.jar").toURI().toURL(); // properly encoded file URI
Defensive patterns

Strategy: validation

Validate before calling

// check that the file: URL path survives URI round-trip and exists
URL u = loader.getResource(res);
if (u != null && "file".equals(u.getProtocol())) {
    File f = new File(u.getPath());
    if (!f.exists()) throw new IllegalStateException("Classpath file URL broken (spaces/special chars?): " + u);
}

Try / catch

try { Native.extractFromResourcePath(res, loader); } catch (IOException e) { if (String.valueOf(e.getMessage()).startsWith("File URL ")) { throw new IllegalStateException("Path with spaces/unicode or stale classpath entry: " + e.getMessage(), e); } throw e; }

Prevention

When it happens

Trigger: extractFromResourcePath resolving a file: URL whose path contains spaces, unicode, or '+' characters that URL-decoding mangles, producing a nonexistent File; or the classpath entry pointing at a file removed after JVM start.

Common situations: Classpath directories with spaces or non-ASCII names; loading JNA from a UNC/mounted path; jars-in-paths whose name changed while the JVM ran; frameworks constructing file: URLs manually without proper encoding.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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