apache/skywalking · error · UnexpectedException

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

Error message

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

What it means

UnexpectedException thrown while resolving the OAP server's working directory: WorkPath locates the server-core jar via its own class resource URL, and when the class is inside a jar (a '!' appears in the URL) it converts the 'file:...!...' prefix into a java.io.File. This variant is the MalformedURLException catch: new URL(urlString) rejected the trimmed URL string, meaning the URL does not start with a protocol WorkPath expected after substring surgery.

Source

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

    private static File findPath() {
        String classResourcePath = WorkPath.class.getName().replaceAll("\\.", "/") + ".class";

        URL resource = ClassLoader.getSystemClassLoader().getResource(classResourcePath);
        if (resource != null) {
            String urlString = resource.toString();

            LOGGER.debug("The beacon class location is {}.", urlString);

            int insidePathIndex = urlString.indexOf('!');
            boolean isInJar = insidePathIndex > -1;

            if (isInJar) {
                urlString = urlString.substring(urlString.indexOf("file:"), insidePathIndex);
                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)

Solutions

  1. Run OAP from the official apache-skywalking dist layout (unpacked tarball/docker image) where server-core.jar sits as a plain file
  2. If embedding, ensure org.apache.skywalking.oap.server.core.WorkPath is loaded from a normal file-system jar URL (file:/path/server-core.jar!/...)
  3. Check for nested-jar classloading and switch to a classpath-based launch
  4. As a diagnostic, print the resource URL for WorkPath.class before it fails to see the malformed prefix
Defensive patterns

Strategy: try-catch

Validate before calling

URL u = WorkPath.class.getClassLoader().getResource("org/apache/skywalking/oap/server/core/WorkPath.class");
boolean jarShape = u != null && u.toString().contains("!") && u.toString().startsWith("file:");
if (!jarShape) {
    LOGGER.warn("Non-standard classpath layout: {}", u);
}

Try / catch

try {
    File workPath = WorkPath.getAndSet(); // or equivalent lookup
} catch (UnexpectedException e) {
    throw new IllegalStateException("OAP must run from the standard dist layout; classpath URL was not a file-jar: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: Running OAP from a classpath layout where the class resource URL contains '!' but the 'file:' index/substring extraction produces a non-URL string (e.g. nested jars from Spring Boot thin launches, jshell/custom classloaders, or URLs like jar:file: read oddly). new URL(...) then throws MalformedURLException wrapped in UnexpectedException.

Common situations: Custom packaging/embedding OAP classes outside the official dist tarball; running with a shaded/uber jar or a launcher that produces unusual resource URLs; JDK changes in URL handling across versions.

Related errors


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