Skip to content

Multiple applications using jjwt leading to ServiceConfigurationError io.jsonwebtoken.jackson.io.JacksonSerializer not a subtype #751

@raphisuter

Description

@raphisuter

Describe the bug
Since we updated jjwt from version 0.10.7 to 0.11.X we encounter an error saying io.jsonwebtoken.io.Serializer: Provider io.jsonwebtoken.jackson.io.JacksonSerializer not a subtype
We run multiple cxf rest clients on the same TomEE instance, all of them using our internal security module which is working with jjwt to create and validate jwts. Since we updated from version 0.10.7 to a version starting from 0.11.0 we encounter the problem that only the first application using jjwt functionality works like expected. All others following encounter following problem: io.jsonwebtoken.io.Serializer: Provider io.jsonwebtoken.jackson.io.JacksonSerializer not a subtype while creating a JWT. The order of the webservices creating a token doesn't matter. Trying to mix up which one calls for a jwt first still leads to errors on all other following. Creating a jwt for the first webservice still works after the others tried to get jwts and produce the exception.

This is the code we use to create JWTs:

public static String getNewJWT(@NotNull Key key, String userId, String username, Date expirationDate, HashMap<String, Object> additionalClaims) throws JwtException {
	JwtBuilder builder = Jwts.builder();

	if(!QUtils.mapNullOrEmpty(additionalClaims)) {
		builder.setClaims(additionalClaims);
	}

	return builder.setId(userId).setSubject(username).setExpiration(expirationDate)
		      .setIssuedAt(new Date()).setIssuer(CERTIFICATE_ISSUER).signWith(key)
		      .compact();
}

The Problem happens while doing the compact(). There the serializer is loaded which throws the error mentioned above.

Checking the code I can see the there was a change done starting from 0.11.0 which changed the way the serializer is loaded. Seeing the code my guess is a classLoader problem.

DefaultJwtBuilder.compact(); in V 0.10.7

    if (this.serializer == null) {
        //try to find one based on the runtime environment:
        InstanceLocator<Serializer<Map<String,?>>> locator =
            Classes.newInstance("io.jsonwebtoken.impl.io.RuntimeClasspathSerializerLocator");
        this.serializer = locator.getInstance();
    }`

DefaultJwtBuilder.compact(); in V 0.11.0

    if (this.serializer == null) {
        // try to find one based on the services available
        // TODO: This util class will throw a UnavailableImplementationException here to retain behavior of previous version, remove in v1.0
        // use the previous commented out line instead
        this.serializer = LegacyServices.loadFirst(Serializer.class);
    }`

To Reproduce
Steps to reproduce the behavior:

  1. Doing authentication on first webservice
  2. DefaultJwtBuilder.compact() loads an instance of JacksonSerializer without problem
  3. Doing authentication on any following webservice
  4. DefaultJwtBuilder.compact() fails to load an instance of JacksonSerializer saying io.jsonwebtoken.io.Serializer: Provider io.jsonwebtoken.jackson.io.JacksonSerializer not a subtype

Expected behavior
DefaultJwtBuilder.compact() loads an instance of JacksonSerializer correctly

stacktrace.txt

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions