apache/skywalking · error · UnexpectedException

Can not locate oap core jar file by path

Error message

Can not locate oap core jar file by path:{}

What it means

UnexpectedException thrown at the end of WorkPath's lookup: neither branch succeeded in turning the class resource path of org.apache.skywalking.oap.server.core.WorkPath into a directory — either the resource URL was null / not jar-shaped in a recognizable way, or the jar file derived from it did not exist on disk. The message echoes classResourcePath, the resource name used for ClassLoader.getResource(...).

Solutions

  1. Run from the standard dist layout (oap-libs/*.jar as plain files) or the official Docker image
  2. If running under JPMS/jlink, put server-core on the class path (not module path) so its URL is file:-based
  3. In tests, avoid code paths that call WorkPath; or pre-set the working directory mechanism the code exposes instead of relying on classpath probing
  4. Verify with a snippet that getClassLoader().getResource('org/apache/skywalking/oap/server/core/WorkPath.class') returns a file: URL before launching

Example fix

// diagnostic before launch
ClassLoader cl = WorkPath.class.getClassLoader();
System.out.println(cl.getResource("org/apache/skywalking/oap/server/core/WorkPath.class"));
// must print a file:/...!/... URL; jrt:/ or null reproduces error 188
Defensive patterns

Strategy: try-catch

Validate before calling

URL u = WorkPath.class.getClassLoader().getResource("org/apache/skywalking/oap/server/core/WorkPath.class");
if (u == null || !("file".equals(u.getProtocol()) || "jar".equals(u.getProtocol()))) {
    throw new IllegalStateException("Unsupported classloader for OAP core; resource URL: " + u);
}

Try / catch

try {
    File dir = WorkPath.lookup();
} catch (UnexpectedException e) {
    // fall back to an explicitly configured working directory if your wrapper supports it
    LOGGER.error("Cannot derive work path from classpath ({}); use the standard dist layout", e.getMessage());
    throw e;
}

Prevention

When it happens

Trigger: Loading WorkPath through a classloader whose getResource returns null (some embedded/OSGi setups) or returns a URL whose file: prefix does not map to an existing File (e.g. jrt:/ JPMS modules, remote/http classloaders, in-memory classloaders). The isInJar branch falls through when agentJarFile.exists() is false, reaching the final throw.

Common situations: Running OAP classes inside a custom container/IDE with a non-file classloader; JPMS jlink runtime; tests instantiating core classes with a classpath the path logic cannot map; bytecode-manipulation agents altering resource URLs.

Related errors


AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14). Data as JSON: /api/errors/72b6eeccef97088c. Report an issue: GitHub.

Appendix: source

Thrown at oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/WorkPath.java:75

                File agentJarFile = null;
                try {
                    agentJarFile = new File(new URL(urlString).toURI());
                } catch (MalformedURLException e) {
                    throw new UnexpectedException("Can not locate oap core jar file by url:" + urlString, e);
                } catch (URISyntaxException e) {
                    throw new UnexpectedException("Can not locate oap core jar file by url:" + urlString, e);
                }
                if (agentJarFile.exists()) {
                    return agentJarFile.getParentFile();
                }
            } else {
                int prefixLength = "file:".length();
                String classLocation = urlString.substring(prefixLength, urlString.length() - classResourcePath.length());
                return new File(classLocation);
            }
        }

        throw new UnexpectedException("Can not locate oap core jar file by path:" + classResourcePath);
    }
}

View on GitHub (pinned to 102af09b4a)