A DESCRIPTION OF THE PROBLEM :
In Provider.java around line 1285, the following code exists.
Service s = serviceMap.get(key);
if (s == null) {
s = legacyMap.get(key);
if (s != null && !s.isValid()) {
legacyMap.remove(key, s);
}
}
There needs to be a "s = null;" after legacyMap.remove() as otherwise a service which fails the isValid() test will be returned as is resulting in a failure later.
Unfortunately this appears to happen with providers using the legacy format which results in NullPointerException further down the track when the JCA tries to create an object using a Service with a null class name. It's not immediately clear how legacy parsing is resulting in the invalid services, but they are created with a null class name. For what it's worth this has only started happening with Java 21.
REGRESSION : Last worked in version 17.0.13
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Requesting an algorithm which does not exist will cause this to happen (sometimes). It also seems to get triggered when attempts are made to match keys to signature providers which we think is why it shows up with the PKCS11 provider.
The code is incorrect by inspection though, if s.isValid() is false s should be getting returned as null, not as an invalid service class.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Request for a service which cannot be fully constructed should result in a NoSuchAlgorithmException not a NullPointerException.
ACTUAL -
NullPointerException
CUSTOMER SUBMITTED WORKAROUND :
Catching NullPointerException and hoping it can be treated like NoSuchAlgorithmException.
FREQUENCY : always