{"record":{"id":"31fd473552830585","repo":"jwtk/jjwt","slug":"unable-to-find-an-implementation-for-spi-using","errorCode":null,"errorMessage":"Unable to find an implementation for ${spi} using java.util.ServiceLoader. Ensure you include a backing implementation .jar in the classpath, for example jjwt-jackson.jar, jjwt-gson.jar or jjwt-orgjson.jar, or your own .jar for custom implementations.","messagePattern":"Unable to find an implementation for (.+?) using java\\.util\\.ServiceLoader\\. Ensure you include a backing implementation \\.jar in the classpath, for example jjwt-jackson\\.jar, jjwt-gson\\.jar or jjwt-orgjson\\.jar, or your own \\.jar for custom implementations\\.","errorType":"exception","errorClass":"UnavailableImplementationException","httpStatus":null,"severity":"critical","filePath":"impl/src/main/java/io/jsonwebtoken/impl/lang/Services.java","lineNumber":99,"sourceCode":"        Assert.notNull(spi, \"Service interface cannot be null.\");\n        Object obj = SERVICES.get(spi);\n        if (obj != null) {\n            return Assert.isInstanceOf(spi, obj, \"Unexpected cached service implementation type.\");\n        }\n        return null;\n    }\n\n    private static <T> T loadFirst(Class<T> spi) {\n        for (ClassLoaderAccessor accessor : CLASS_LOADER_ACCESSORS) {\n            ServiceLoader<T> loader = ServiceLoader.load(spi, accessor.getClassLoader());\n            Assert.stateNotNull(loader, \"JDK ServiceLoader#load should never return null.\");\n            Iterator<T> i = loader.iterator();\n            Assert.stateNotNull(i, \"JDK ServiceLoader#iterator() should never return null.\");\n            if (i.hasNext()) {\n                return i.next();\n            }\n        }\n        throw new UnavailableImplementationException(spi);\n    }\n\n    /**\n     * Clears internal cache of service singletons. This is useful when testing, or for applications that dynamically\n     * change classloaders.\n     */\n    public static void reload() {\n        SERVICES.clear();\n    }\n\n    private interface ClassLoaderAccessor {\n        ClassLoader getClassLoader();\n    }\n}\n","sourceCodeStart":81,"sourceCodeEnd":114,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/lang/Services.java#L81-L114","documentation":"Services.loadFirst uses java.util.ServiceLoader to locate a runtime implementation of a JJWT SPI (e.g. Serializer/Deserializer). When no provider is registered on the classpath it throws UnavailableImplementationException with a message instructing the developer to add a backing implementation jar such as jjwt-jackson, jjwt-gson, or jjwt-orgjson.","triggerScenarios":"Calling Jwts.builder().serializeTo(...) / Jwts.parser()... on the classpath containing only jjwt-api (and jjwt-impl) without a JSON serializer implementation.","commonSituations":"Adding jjwt-api and jjwt-impl dependencies but forgetting jjwt-jackson (or gson/orgjson); shaded/Thin classpaths that dropped META-INF/services entries; runtime classpath differing from the compile-time one.","solutions":["Add a runtime implementation dependency, e.g. implementation 'io.jsonwebtoken:jjwt-jackson:0.12.x' (or jjwt-gson / jjwt-orgjson).","Verify the jar's META-INF/services files are intact if you shade/repackage dependencies.","Ensure the ServiceLoader-visible classloader includes the implementation jar (check runtime vs. compile classpath)."],"exampleFix":"// before (build.gradle)\nimplementation 'io.jsonwebtoken:jjwt-api:0.12.6'\nruntimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.6'\n// after\nimplementation 'io.jsonwebtoken:jjwt-api:0.12.6'\nruntimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.6'\nruntimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.6'","handlingStrategy":"try-catch","validationCode":"// fails fast at startup if no JSON implementation is on the classpath\nstatic {\n    try {\n        io.jsonwebtoken.impl.lang.Services.get(io.jsonwebtoken.io.Serializer.class);\n    } catch (io.jsonwebtoken.lang.Classes.UnknownClassException | RuntimeException e) {\n        throw new IllegalStateException(\n            \"No JJWT JSON implementation found. Add jjwt-jackson, jjwt-gson or jjwt-orgjson to the runtime classpath.\", e);\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    String jwt = Jwts.builder()...compact();\n} catch (io.jsonwebtoken.lang.Classes.UnknownClassException | io.jsonwebtoken.io.SerializationException e) {\n    throw new IllegalStateException(\"Missing JJWT serializer implementation; add jjwt-jackson/jjwt-gson/jjwt-orgjson\", e);\n}","preventionTips":["Always declare jjwt-api + jjwt-impl + one implementation (jjwt-jackson/gson/orgjson) together","Smoke-test JWT creation at application startup to fail fast on missing implementations","If shading jars, keep META-INF/services entries intact (ServicesResourceTransformer etc.)"],"tags":["classpath","dependency","serviceloader"],"backgroundTag":"missing-dependency","analyzedSha":"fb71496164c71442d08adec4571d9616ed5e1b8d","analyzedAt":"2026-09-09T00:33:09.982Z","contentChangedAt":"2026-09-09T00:33:09.982Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}