microsoft-authentication-library-for-java
microsoft-authentication-library-for-java copied to clipboard
[Bug] NoSuchMethodError (ConfidentialClientApplication$Builder.executorService): mssql-jdbc + msal4j (since v1.15.0)
Library version used
1.15.0
Java version
17.0.6
Scenario
Other - please specify
Is this a new or an existing app?
None
Issue description and reproduction steps
There is Java app connecting to MSSQL db over something called "Microsoft Entra".
After an update of msal4j
from v1.14.x to v1.15.0, there the jdbc driver throws NoSuchMethodError while authenticating.
I reproduced the problem with a the below minimal code snippet
Relevant code snippets
dependencies {
implementation("com.microsoft.sqlserver:mssql-jdbc:12.6.1.jre11")
implementation("com.microsoft.azure:msal4j:1.15.0") // <-- the previous 1.14.3 worked well
implementation("org.slf4j:slf4j-simple:2.0.12")
}
import com.microsoft.sqlserver.jdbc.SQLServerDataSource
fun main() {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
val ds = SQLServerDataSource()
ds.url = "jdbc:sqlserver://ms-sql-server-host:1433;database=some-db;Authentication=ActiveDirectoryServicePrincipal"
ds.user = "?"
ds.setPassword("?")
val con = ds.getConnection()
con.close()
}
Expected behavior
No breaking change expected on minor version upgrade.
Identity provider
Microsoft Entra ID (Work and School accounts and Personal Microsoft accounts)
Regression
1.14.3
Solution and workarounds
Not to upgrade to msal4j v1.15.0 and ignore it by Renovate bot
Most probably it's related to 450757afc5dad refactoring.
Hello @gavvvr : Could you post the exact error/stack trace you're getting? Is it the 'executorService' referenced in your title that's causing the NoSuchMethodError?
Also, it looks like you're using the latest mssql-jdbc:12.6.1.jre11, but that uses msa4lj 1.14.1 . Based on that code snippet I assume you're using Scala, but I'm not too familiar with it or that build system. I assume during runtime it's using version 1.15.0 because of the explicit msal4j dependency rather than the transient 1.14.1?
Hi @Avery-Dunn
It's the simplest Kotlin project built by Gradle. The combination of mssql-jdbc:12.6.1.jre11 + msal4j:1.15.0. Upgrading msal4j from v1.14.3 to v1.15.0 I don't expect backward compatibility issues.
The complete stacktace is below:
Click me
Exception in thread "main" java.lang.NoSuchMethodError: 'com.microsoft.aad.msal4j.AbstractClientApplicationBase$Builder com.microsoft.aad.msal4j.ConfidentialClientApplication$Builder.executorService(java.util.concurrent.ExecutorService)'
at com.microsoft.sqlserver.jdbc.SQLServerMSAL4JUtils.getSqlFedAuthTokenPrincipal(SQLServerMSAL4JUtils.java:137)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.getFedAuthToken(SQLServerConnection.java:6028)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.onFedAuthInfo(SQLServerConnection.java:5963)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.processFedAuthInfo(SQLServerConnection.java:5797)
at com.microsoft.sqlserver.jdbc.TDSTokenHandler.onFedAuthInfo(tdsparser.java:322)
at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:130)
at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:42)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.sendLogon(SQLServerConnection.java:6855)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.logon(SQLServerConnection.java:5402)
at com.microsoft.sqlserver.jdbc.SQLServerConnection$LogonCommand.doExecute(SQLServerConnection.java:5334)
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7739)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:4384)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:3823)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:3348)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectInternal(SQLServerConnection.java:3179)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:1953)
at com.microsoft.sqlserver.jdbc.SQLServerDataSource.getConnectionInternal(SQLServerDataSource.java:1550)
at com.microsoft.sqlserver.jdbc.SQLServerDataSource.getConnection(SQLServerDataSource.java:99)
at org.example.AppKt.main(App.kt:11)
at org.example.AppKt.main(App.kt)
Hello @gavvvr : We're having trouble reproducing this error, however other customers have reported something similar: one after upgrading to 1.15.0 like yourself, and one a few weeks ago after upgrading to 1.14.0
The person who upgraded to 1.15.0 was able to get rid of the issue by purging their local Maven repo, ensuring that fresh versions of every dependency was downloaded the next time they built their package. Could you try deleting any local versions of msla4j (in Maven it's the '.m2' folder, not sure for Gradle), and letting us know if you still have this 'NoSuchMethod' issue?
Hi @Avery-Dunn
I use Gradle instead of Maven.
The build is as simple as the following build.gradle.kts
:
plugins {
application
kotlin("jvm") version "1.9.23"
}
repositories {
mavenCentral()
}
application {
mainClass.set("com.example.AppKt")
}
dependencies {
implementation("com.microsoft.sqlserver:mssql-jdbc:12.6.1.jre11")
implementation("com.microsoft.azure:msal4j:1.15.0")
implementation("org.slf4j:slf4j-simple:2.0.12")
}
and the app gets built on CI on a fresh ephemeral build agents.
The main
method for obtaining jdbc connection was listed above. It's a hello-world setup.
To reproduce an issue, you need a db using MS Entra authentication method.
Well, we did have the the same issue. We pin the exact versions of many dependencies (due to the dependencyConvergence rule), and we pinned msal4j
to 1.15.0
(to stay up-to-date, and higher minor versions should be compatible).
Due this issue, we changed msal4j
to 1.14.3
, which gets rid of the error.
The cause of the error seems quite straight-forward, not requiring reproduction. As already mentioned by @gavvvr, version 1.15.0
of msal4j
removes the executorService method from AbstractClientApplicationBase#Builder and moves it to AbstractApplicationBase$Builder
. If you take a look at that stack trace also posted by gavvvr, that method is called by com.microsoft.sqlserver.jdbc.SQLServerMSAL4JUtils.getSqlFedAuthTokenPrincipal(SQLServerMSAL4JUtils.java:137)
, which will fail since that method was removed.
Hi @Avery-Dunn
The problem is obvious to me now.
After moving of public T executorService(ExecutorService val)
method from AbstractClientApplicationBase.Builder<T extends AbstractClientApplicationBase.Builder<T>>
into the AbstractApplicationBase.Builder<T extends AbstractApplicationBase.Builder<T>>
, the executorService
-method signature has changed.
Previously it returned AbstractClientApplicationBase$Builder
, but since v1.15.0 it returns AbstractApplicationBase$Builder
.
It's a backward-incompatible change in runtime for mssql-jdbc:12.6.1
compiled against of msal4j:1.14.1
and expecting old method signature. For compile-time there is no issue though...
Here is the code for reproducing the problem.
Supposed you have 2 Maven modules: app
and lib
(Gradle's subprojects in my case).
Here is the Builder.java
from lib
:
package org.example.lib;
public class Builder extends AbstractBuilder<Builder> {
@Override
Builder self() {
return this;
}
}
abstract class AbstractBuilder<T extends AbstractBuilder<T>> /*extends BuilderBase<T>*/ {
public T executorService() {
return self();
}
abstract T self();
}
abstract class BuilderBase<T extends BuilderBase<T>> {
public T executorService() {
return self();
}
abstract T self();
}
And the App.java
in app
is:
package org.example.app;
import org.example.lib.Builder;
public class App {
public static void main(String[] args) {
var builder = new Builder();
System.out.println(builder.executorService());
}
}
If you build the app without extending BuilderBase
, and then build an updated lib.jar
with with uncommented extends BuilderBase<T>
and commented out AbstractBuilder#executorService
/AbstractBuilder#self
methods, then you will get a:
Exception in thread "main" java.lang.NoSuchMethodError: 'org.example.lib.AbstractBuilder org.example.lib.Builder.executorService()'
at org.example.app.App.main(App.java:10)
I've created a repository with README.md
which reproduces the problem: https://github.com/gavvvr/msal4j-806
I have encountered what sounds like the same issue as @gavvvr where I'm using the latest com.microsoft.azure.kusto.kusto-data:5.0.5
, which is compiled against com.microsoft.azure.msal4j:1.13.10
. After updating the azure-sdk-bom to the latest (which uses 1.15.0), I am getting this error:
java.lang.NoSuchMethodError: 'com.microsoft.aad.msal4j.AbstractClientApplicationBase$Builder com.microsoft.aad.msal4j.ConfidentialClientApplication$Builder.httpClient(com.microsoft.aad.msal4j.IHttpClient)'
at com.microsoft.azure.kusto.data.auth.ApplicationKeyTokenProvider.getClientApplication(ApplicationKeyTokenProvider.java:31)
at com.microsoft.azure.kusto.data.auth.ConfidentialAppTokenProviderBase.initializeWithCloudInfo(ConfidentialAppTokenProviderBase.java:38)
at com.microsoft.azure.kusto.data.auth.CloudDependentTokenProviderBase.initialize(CloudDependentTokenProviderBase.java:41)
at com.microsoft.azure.kusto.data.auth.TokenProviderBase.acquireAccessToken(TokenProviderBase.java:30)
at com.microsoft.azure.kusto.data.ClientImpl.generateIngestAndCommandHeaders(ClientImpl.java:405)
at com.microsoft.azure.kusto.data.ClientImpl.executeToJsonResult(ClientImpl.java:213)
at com.microsoft.azure.kusto.data.ClientImpl.executeImpl(ClientImpl.java:173)
at com.microsoft.azure.kusto.data.ClientImpl.lambda$execute$0(ClientImpl.java:122)
at com.microsoft.azure.kusto.data.instrumentation.MonitoredActivity.invoke(MonitoredActivity.java:33)
at com.microsoft.azure.kusto.data.ClientImpl.execute(ClientImpl.java:121)
at com.microsoft.azure.kusto.data.ClientImpl.execute(ClientImpl.java:116)
Edit:
Just confirmed that downgrading to the expected version works fine, and that the httpClient
method (property on base class with annotation) was removed in 1.15.0, breaking the Kusto data library. So, yeah the same breaking of backwards compatability in minor version release.
Running into the same issue when upgrading our dependencies.
mssql-jdbc(12.4.2) comes with spring-boot(3.2.6) msal4j(1.15.0) comes from azure-identity(1.12.0) which comes from spring-cloud-azure-dependencies(5.12.0)
So this bug actually makes the version mapping incorrect at https://github.com/Azure/azure-sdk-for-java/wiki/Spring-Versions-Mapping
spring-boot 3.2.x is not compatible with 5.x.x when using mssql+entra id auth.
Staying with spring-cloud-azure-dependencies:5.11.0 does not have this problem
Hi, I have the same issue: Using azure-identity with mssql-jdbc. We need update azure-identity to version 1.12.2 due to a vulnerability CVE-2024-35255 and currently there is no compatible version of msal4j with with any mssql-jdbc library.
Hi, I have a different issue but it's related to upgrading to v1.15.0 and 1.15.1. The error I'm getting is
Correct the classpath of your application so that it contains compatible versions of the classes com.microsoft.sqlserver.jdbc.SQLServerMSAL4JUtils and com.microsoft.aad.msal4j.PublicClientApplication$Builder
.
Purged my local directory and all, nothing works.
Reproduce on com.microsoft.azure:msal4j:1.15.1
"C:\Program Files\Microsoft\jdk-21.0.3.9-hotspot\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2024.1.3\lib\idea_rt.jar=54324:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2024.1.3\bin" -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath C:\Users\yuanzhao\IdeaProjects\quick01\target\classes;C:\Users\yuanzhao.m2\repository\com\azure\azure-identity\1.12.2\azure-identity-1.12.2.jar;C:\Users\yuanzhao.m2\repository\com\azure\azure-core\1.49.1\azure-core-1.49.1.jar;C:\Users\yuanzhao.m2\repository\com\azure\azure-xml\1.0.0\azure-xml-1.0.0.jar;C:\Users\yuanzhao.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.13.5\jackson-annotations-2.13.5.jar;C:\Users\yuanzhao.m2\repository\com\fasterxml\jackson\core\jackson-core\2.13.5\jackson-core-2.13.5.jar;C:\Users\yuanzhao.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.13.5\jackson-databind-2.13.5.jar;C:\Users\yuanzhao.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.13.5\jackson-datatype-jsr310-2.13.5.jar;C:\Users\yuanzhao.m2\repository\org\slf4j\slf4j-api\1.7.36\slf4j-api-1.7.36.jar;C:\Users\yuanzhao.m2\repository\io\projectreactor\reactor-core\3.4.38\reactor-core-3.4.38.jar;C:\Users\yuanzhao.m2\repository\org\reactivestreams\reactive-streams\1.0.4\reactive-streams-1.0.4.jar;C:\Users\yuanzhao.m2\repository\com\azure\azure-core-http-netty\1.15.1\azure-core-http-netty-1.15.1.jar;C:\Users\yuanzhao.m2\repository\io\netty\netty-handler\4.1.110.Final\netty-handler-4.1.110.Final.jar;C:\Users\yuanzhao.m2\repository\io\netty\netty-resolver\4.1.110.Final\netty-resolver-4.1.110.Final.jar;C:\Users\yuanzhao.m2\repository\io\netty\netty-transport\4.1.110.Final\netty-transport-4.1.110.Final.jar;C:\Users\yuanzhao.m2\repository\io\netty\netty-handler-proxy\4.1.110.Final\netty-handler-proxy-4.1.110.Final.jar;C:\Users\yuanzhao.m2\repository\io\netty\netty-codec-socks\4.1.110.Final\netty-codec-socks-4.1.110.Final.jar;C:\Users\yuanzhao.m2\repository\io\netty\netty-buffer\4.1.110.Final\netty-buffer-4.1.110.Final.jar;C:\Users\yuanzhao.m2\repository\io\netty\netty-codec\4.1.110.Final\netty-codec-4.1.110.Final.jar;C:\Users\yuanzhao.m2\repository\io\netty\netty-codec-http\4.1.110.Final\netty-codec-http-4.1.110.Final.jar;C:\Users\yuanzhao.m2\repository\io\netty\netty-codec-http2\4.1.110.Final\netty-codec-http2-4.1.110.Final.jar;C:\Users\yuanzhao.m2\repository\io\netty\netty-transport-native-unix-common\4.1.110.Final\netty-transport-native-unix-common-4.1.110.Final.jar;C:\Users\yuanzhao.m2\repository\io\netty\netty-transport-native-epoll\4.1.110.Final\netty-transport-native-epoll-4.1.110.Final-linux-x86_64.jar;C:\Users\yuanzhao.m2\repository\io\netty\netty-transport-classes-epoll\4.1.110.Final\netty-transport-classes-epoll-4.1.110.Final.jar;C:\Users\yuanzhao.m2\repository\io\netty\netty-transport-native-kqueue\4.1.110.Final\netty-transport-native-kqueue-4.1.110.Final-osx-x86_64.jar;C:\Users\yuanzhao.m2\repository\io\netty\netty-transport-classes-kqueue\4.1.110.Final\netty-transport-classes-kqueue-4.1.110.Final.jar;C:\Users\yuanzhao.m2\repository\io\netty\netty-tcnative-boringssl-static\2.0.65.Final\netty-tcnative-boringssl-static-2.0.65.Final.jar;C:\Users\yuanzhao.m2\repository\io\netty\netty-tcnative-classes\2.0.65.Final\netty-tcnative-classes-2.0.65.Final.jar;C:\Users\yuanzhao.m2\repository\io\netty\netty-tcnative-boringssl-static\2.0.65.Final\netty-tcnative-boringssl-static-2.0.65.Final-linux-x86_64.jar;C:\Users\yuanzhao.m2\repository\io\netty\netty-tcnative-boringssl-static\2.0.65.Final\netty-tcnative-boringssl-static-2.0.65.Final-linux-aarch_64.jar;C:\Users\yuanzhao.m2\repository\io\netty\netty-tcnative-boringssl-static\2.0.65.Final\netty-tcnative-boringssl-static-2.0.65.Final-osx-x86_64.jar;C:\Users\yuanzhao.m2\repository\io\netty\netty-tcnative-boringssl-static\2.0.65.Final\netty-tcnative-boringssl-static-2.0.65.Final-osx-aarch_64.jar;C:\Users\yuanzhao.m2\repository\io\netty\netty-tcnative-boringssl-static\2.0.65.Final\netty-tcnative-boringssl-static-2.0.65.Final-windows-x86_64.jar;C:\Users\yuanzhao.m2\repository\io\projectreactor\netty\reactor-netty-http\1.0.45\reactor-netty-http-1.0.45.jar;C:\Users\yuanzhao.m2\repository\io\netty\netty-resolver-dns\4.1.109.Final\netty-resolver-dns-4.1.109.Final.jar;C:\Users\yuanzhao.m2\repository\io\netty\netty-codec-dns\4.1.109.Final\netty-codec-dns-4.1.109.Final.jar;C:\Users\yuanzhao.m2\repository\io\netty\netty-resolver-dns-native-macos\4.1.109.Final\netty-resolver-dns-native-macos-4.1.109.Final-osx-x86_64.jar;C:\Users\yuanzhao.m2\repository\io\netty\netty-resolver-dns-classes-macos\4.1.109.Final\netty-resolver-dns-classes-macos-4.1.109.Final.jar;C:\Users\yuanzhao.m2\repository\io\projectreactor\netty\reactor-netty-core\1.0.45\reactor-netty-core-1.0.45.jar;C:\Users\yuanzhao.m2\repository\io\netty\netty-common\4.1.110.Final\netty-common-4.1.110.Final.jar;C:\Users\yuanzhao.m2\repository\com\azure\azure-json\1.1.0\azure-json-1.1.0.jar;C:\Users\yuanzhao.m2\repository\com\microsoft\azure\msal4j\1.15.1\msal4j-1.15.1.jar;C:\Users\yuanzhao.m2\repository\com\nimbusds\oauth2-oidc-sdk\11.9.1\oauth2-oidc-sdk-11.9.1.jar;C:\Users\yuanzhao.m2\repository\com\github\stephenc\jcip\jcip-annotations\1.0-1\jcip-annotations-1.0-1.jar;C:\Users\yuanzhao.m2\repository\com\nimbusds\content-type\2.3\content-type-2.3.jar;C:\Users\yuanzhao.m2\repository\com\nimbusds\lang-tag\1.7\lang-tag-1.7.jar;C:\Users\yuanzhao.m2\repository\com\nimbusds\nimbus-jose-jwt\9.37.3\nimbus-jose-jwt-9.37.3.jar;C:\Users\yuanzhao.m2\repository\net\minidev\json-smart\2.5.0\json-smart-2.5.0.jar;C:\Users\yuanzhao.m2\repository\net\minidev\accessors-smart\2.5.0\accessors-smart-2.5.0.jar;C:\Users\yuanzhao.m2\repository\org\ow2\asm\asm\9.3\asm-9.3.jar;C:\Users\yuanzhao.m2\repository\com\microsoft\azure\msal4j-persistence-extension\1.3.0\msal4j-persistence-extension-1.3.0.jar;C:\Users\yuanzhao.m2\repository\net\java\dev\jna\jna\5.13.0\jna-5.13.0.jar;C:\Users\yuanzhao.m2\repository\net\java\dev\jna\jna-platform\5.6.0\jna-platform-5.6.0.jar;C:\Users\yuanzhao.m2\repository\com\microsoft\sqlserver\mssql-jdbc\12.7.0.jre11-preview\mssql-jdbc-12.7.0.jre11-preview.jar org.example.App Hello World! Exception in thread "main" java.lang.NoSuchMethodError: 'com.microsoft.aad.msal4j.AbstractClientApplicationBase$Builder com.microsoft.aad.msal4j.PublicClientApplication$Builder.executorService(java.util.concurrent.ExecutorService)' at com.microsoft.sqlserver.jdbc.SQLServerMSAL4JUtils.getSqlFedAuthToken(SQLServerMSAL4JUtils.java:100) at com.microsoft.sqlserver.jdbc.SQLServerConnection.getFedAuthToken(SQLServerConnection.java:6034) at com.microsoft.sqlserver.jdbc.SQLServerConnection.onFedAuthInfo(SQLServerConnection.java:6001) at com.microsoft.sqlserver.jdbc.SQLServerConnection.processFedAuthInfo(SQLServerConnection.java:5835) at com.microsoft.sqlserver.jdbc.TDSTokenHandler.onFedAuthInfo(tdsparser.java:346) at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:130) at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:42) at com.microsoft.sqlserver.jdbc.SQLServerConnection.sendLogon(SQLServerConnection.java:6894) at com.microsoft.sqlserver.jdbc.SQLServerConnection.logon(SQLServerConnection.java:5440) at com.microsoft.sqlserver.jdbc.SQLServerConnection$LogonCommand.doExecute(SQLServerConnection.java:5372) at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7775) at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:4397) at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:3834) at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:3391) at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectInternal(SQLServerConnection.java:3200) at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:1974) at com.microsoft.sqlserver.jdbc.SQLServerDataSource.getConnectionInternal(SQLServerDataSource.java:1550) at com.microsoft.sqlserver.jdbc.SQLServerDataSource.getConnection(SQLServerDataSource.java:99) at org.example.App.main(App.java:24)
Process finished with exit code 1
Hi guys,
The changes on PR #828 should hopefully fix all of these issues. Let's wait till the fix is released and then see if the issue still reproduces.
Hi guys,
The changes on PR #828 should hopefully fix all of these issues. Let's wait till the fix is released and then see if the issue still reproduces.
Hello @Mr-Vinti do you know how long it usually takes to be released?
Hello all, sorry for the long delay on getting this fixed but version 1.16.0 has now been released to fix this issue. The methods that were moved have been restored to their original class while keeping the new ones in place, so it should be compatible with both pre- and post-1.15.0 versions.
If anyone is still getting this error or having similar issues feel free to re-open this thread or start a new one.