1

I have a problem of block java.security.Provider.getService(String, String) in application after few days of working. Here is stack-trace for subethasmtp, but same story on all other threads (IMAP, HTTPS etc...).

Java Monitor Blocked
 at java.security.Provider.getService(String, String)
 at sun.security.jca.ProviderList$ServiceList.tryGet(int)
 at sun.security.jca.ProviderList$ServiceList.access$200(ProviderList$ServiceList, int)
 at sun.security.jca.ProviderList$ServiceList$1.hasNext()
 at javax.crypto.KeyGenerator.nextSpi(KeyGeneratorSpi, boolean)
 at javax.crypto.KeyGenerator.<init>(String)
 at javax.crypto.KeyGenerator.getInstance(String)
 at sun.security.ssl.JsseJce.getKeyGenerator(String)
 at sun.security.ssl.HandshakeMessage$Finished.getFinished(HandshakeHash, int, SecretKey)
 at sun.security.ssl.HandshakeMessage$Finished.<init>(ProtocolVersion, HandshakeHash, int, SecretKey, CipherSuite)
 at sun.security.ssl.ServerHandshaker.sendChangeCipherAndFinish(boolean)
 at sun.security.ssl.ServerHandshaker.clientHello(HandshakeMessage$ClientHello)
 at sun.security.ssl.ServerHandshaker.processMessage(byte, int)
 at sun.security.ssl.Handshaker.processLoop()
 at sun.security.ssl.Handshaker.process_record(InputRecord, boolean)
 at sun.security.ssl.SSLSocketImpl.readRecord(InputRecord, boolean)
 at sun.security.ssl.SSLSocketImpl.performInitialHandshake()
 at sun.security.ssl.SSLSocketImpl.startHandshake(boolean)
 at sun.security.ssl.SSLSocketImpl.startHandshake()
 at org.subethamail.smtp.command.StartTLSCommand.execute(String, Session)
 at org.subethamail.smtp.server.CommandHandler.handleCommand(Session, String)
 at org.subethamail.smtp.server.Session.runCommandLoop()
 at org.subethamail.smtp.server.Session.run()
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor$Worker)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run()
 at java.lang.Thread.run()

** red block on JFR snapshot image is java.security.Provider.getService block **

Kire Haglin
  • 6,569
  • 22
  • 27
Valentin
  • 36
  • 6

1 Answers1

0

The service provider in the JDK takes a global lock which leads to contention.

I would introduce a cache. If the call to the service provider is in a third party library, I would change to another library.

Kire Haglin
  • 6,569
  • 22
  • 27
  • Thanks! Problem is, application used different libs (smtp, http, etc ...). Rewriting each of impossible due to maintain. – Valentin Jun 26 '18 at 08:52
  • If we look at the implementation of getService we can see there is a cache that remembers the last lookup. If you can structure the application so it doesn't switch between different service types or algorithms, it may speed things up. For instance, bulk all calls to the smltp lib, so they are called for 100 ms, and then process http the next 900 ms. – Kire Haglin Jun 28 '18 at 06:35