Skip to content

[BUG] Unstopped thread when using Kerberos authentication #918

Closed
@jansohn

Description

Driver version

7.0.0

SQL Server version

Microsoft SQL Server 2016 (SP2) (KB4052908) - 13.0.5026.0 (X64) 
	Mar 18 2018 09:11:49 
	Copyright (c) Microsoft Corporation
	Standard Edition (64-bit) on Windows Server 2016 Standard 10.0 <X64> (Build 14393: ) (Hypervisor)

Client Operating System

Windows 10

JAVA/JVM version

java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)

Problem description

  1. Expected behaviour: All threads should be stopped when shutting down the application in Tomcat

  2. Actual behaviour: One thread is still running after shutdown and produces a possible memory leak

  3. Error message/stack trace:

    WARNING: The web application [test] appears to have started a thread named [Thread-3] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
     sun.net.dns.ResolverConfigurationImpl.notifyAddrChange0(Native Method)
     sun.net.dns.ResolverConfigurationImpl$AddressChangeListener.run(ResolverConfigurationImpl.java:144)
    
  4. I debugged the web application and found out that the thread is started in a static initialization block in sun.net.dns.ResolverConfigurationImpl (see stack trace below):

    static {
      AccessController.doPrivileged(new PrivilegedAction() {
         public Void run() {
            System.loadLibrary("net");
            return null;
         }
      });
      init0();
      ResolverConfigurationImpl.AddressChangeListener var0 = new ResolverConfigurationImpl.AddressChangeListener();
      var0.setDaemon(true);
      var0.start();
    }
    
    Daemon Thread [localhost-startStop-2] (Class load: ResolverConfigurationImpl)	
    	owns: Object  (id=91)	
    	owns: Object  (id=92)	
    	owns: EntityManagerFactoryDelegate  (id=93)	
    	owns: ApplicationContextListener  (id=94)	
    	owns: StandardContext  (id=95)	
    	ResolverConfiguration.open() line: 56 [local variables unavailable]	
    	DnsContextFactory.serversForUrls(DnsUrl[]) line: 149	
    	DnsContextFactory.getContext(String, DnsUrl[], Hashtable<?,?>) line: 81	
    	dnsURLContext.getRootURLContext(String, Hashtable<?,?>) line: 71	
    	dnsURLContext(GenericURLDirContext).getAttributes(String, String[]) line: 100	
    	KrbServiceLocator.lambda$getKerberosService$1(Context, String) line: 168	
    	1747531283.run() line: not available	
    	AccessController.doPrivileged(PrivilegedExceptionAction<T>, AccessControlContext) line: not available [native method]	
    	AccessController.doPrivileged(PrivilegedExceptionAction<T>, AccessControlContext, Permission...) line: 713	
    	KrbServiceLocator.getKerberosService(String, String) line: 166	
    	Config.getKDCFromDNS(String) line: 1171	
    	Config.getKDCList(String) line: 1057	
    	NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]	
    	NativeMethodAccessorImpl.invoke(Object, Object[]) line: 62	
    	DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43	
    	Method.invoke(Object, Object...) line: 498	
    	KerbAuthentication$2.isRealmValid(String) line: 301	
    	KerbAuthentication.getRealmValidator(String) line: 312	
    	KerbAuthentication.enrichSpnWithRealm(String, boolean) line: 254	
    	KerbAuthentication.<init>(SQLServerConnection, String, int) line: 231	
    	SQLServerConnection.logon(SQLServerConnection$LogonCommand) line: 3557	
    	SQLServerConnection.access$000(SQLServerConnection, SQLServerConnection$LogonCommand) line: 81	
    	SQLServerConnection$LogonCommand.doExecute() line: 3541	
    	SQLServerConnection$LogonCommand(TDSCommand).execute(TDSWriter, TDSReader) line: 7240	
    	SQLServerConnection.executeCommand(TDSCommand) line: 2869	
    	SQLServerConnection.connectHelper(ServerPortPlaceHolder, int, int, boolean, boolean, boolean, int) line: 2395	
    	SQLServerConnection.login(String, String, int, String, FailoverInfo, int, long) line: 2042	
    	SQLServerConnection.connectInternal(Properties, SQLServerPooledConnection) line: 1889	
    	SQLServerConnection.connect(Properties, SQLServerPooledConnection) line: 1120	
    	SQLServerDriver.connect(String, Properties) line: 700	
    	DriverManager.getConnection(String, Properties, Class<?>) line: 664	
    	DriverManager.getConnection(String, Properties) line: 208	
    	DefaultConnector.connect(Properties, Session) line: 98	
    	DatabaseLogin(DatasourceLogin).connectToDatasource(Accessor, Session) line: 162	
    	ServerSession(DatabaseSessionImpl).setOrDetectDatasource(boolean) line: 207	
    	ServerSession(DatabaseSessionImpl).loginAndDetectDatasource() line: 760	
    	EntityManagerFactoryProvider.login(DatabaseSessionImpl, Map, boolean) line: 265	
    	EntityManagerSetupImpl.deploy(ClassLoader, Map) line: 731	
    	EntityManagerFactoryDelegate.getAbstractSession() line: 205	
    	EntityManagerFactoryDelegate.createEntityManagerImpl(Map, SynchronizationType) line: 305	
    	EntityManagerFactoryImpl.createEntityManagerImpl(Map, SynchronizationType) line: 337	
    	EntityManagerFactoryImpl.createEntityManager() line: 303	
    	ApplicationContextListener.createEntityManager() line: 229	
    	[...]
    

The thread itself is started by a Java core class but my question is if we can prevent the thread from starting in the first place (stopping it correctly seems to be out of the question as there is no reference available).
I think others using Kerberos for authentication (with username/password) should experience this problem, too. It would be nice to know if this is a general problem or if I'm doing something wrong.
Currently the code is embedded in a bigger web application (with JPA and others) but I'll try to strip it down to a minimal example if necessary.

Metadata

Assignees

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