DEV Community

loading...
Cover image for A Problem with JJWT With Java 11 (9+)

A Problem with JJWT With Java 11 (9+)

Pradipta Sarma
Software Engineer
・2 min read

Originally posted on my blog

I was implementing Spring Security for a service I am working on for work. The project is based on Java 11 and the Spring Boot Framework.
Usign the JWT token, I was supposed to extract user details and roles. The JWT is signed using a secret key with has been stored in properties encoded in base 64.

Jwts.parser().setSigningKey(appProperties.getAuth().getTokenSecret()).parseClaimsJws(authToken);
Enter fullscreen mode Exit fullscreen mode

The above code is used to validate the JWT's authenticity.

The setSigningKey(...) method looks like:

    public JwtParser setSigningKey(String base64EncodedKeyBytes) {
        Assert.hasText(base64EncodedKeyBytes, "signing key cannot be null or empty.");
        this.keyBytes = TextCodec.BASE64.decode(base64EncodedKeyBytes);
        return this;
    }
Enter fullscreen mode Exit fullscreen mode

This method throws an error when it tries to decode the encoded key.
Logs:

java.lang.ClassNotFoundException: javax.xml.bind.DatatypeConverter
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:606) ~[na:na]
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168) ~[na:na]
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522) ~[na:na]
    at io.jsonwebtoken.impl.Base64Codec.decode(Base64Codec.java:26) ~[jjwt-0.5.jar:0.5]
    at io.jsonwebtoken.impl.DefaultJwtParser.setSigningKey(DefaultJwtParser.java:71) ~[jjwt-0.5.jar:0.5]
Enter fullscreen mode Exit fullscreen mode

However, the same Library was being used on other projects I/my team had worked on written in Java 8. There, the decode method calls an api from jaxb, but I obserrved that on the Java 11 project, it wasn't the case. Even with exact same version of jjwt.

The problem lies with JJWT with Java 11 (or any after Java 8).

The jaxb APIs are considered to be Java EE APIs. The API is completely removed from the Java 11 SDK. With the introduction of modules since Java 9, the java.se module is available on the default classpath, and it doesn't include Java EE APIs.

To fix the same, you can pass --add-modules java.xml.bind as a command line argument.
A better fix is to add the jaxb API as a Maven/Gradle dependancy.

<!-- Runtime, com.sun.xml.bind module -->
<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>{version}</version>
</dependency>
Enter fullscreen mode Exit fullscreen mode
compile group: 'javax.xml.bind', name: 'jaxb-api', version: '{version}'
Enter fullscreen mode Exit fullscreen mode

This makes jaxb APIs available in the classpath and the above problem gets fixed.

Sources:

  • Link 1 | StackOverflow


  • Link 2 | ProgrammerSought Blog


  • Link 3 | GitHub
  • Discussion (0)