diff --git a/build.gradle b/build.gradle index e82d740d60..1aeb3b192f 100644 --- a/build.gradle +++ b/build.gradle @@ -402,6 +402,17 @@ allprojects { // Spring AI's pgvector-store brings in its own PostgreSQL JDBC driver; force ours force "org.postgresql:postgresql:${postgresqlDriverVersion}" + // professional's spring-ai-bedrock/spring-ai-bedrock-converse pull a newer software.amazon.awssdk + // release than awsSdkVersion (used directly by embedded, cloudServices, and professional itself). + // Every software.amazon.awssdk artifact must be the same version -- that's why AWS publishes an + // SDK-wide BOM -- so a skew here leaves two different copies of classes like + // software.amazon.awssdk.regions.Region loaded across the embedded/module classloader boundary, + // which surfaces at runtime as a LinkageError (loader constraint violation), not a build failure. + eachDependency { DependencyResolveDetails details -> + if (details.requested.group == "software.amazon.awssdk") + details.useVersion(awsSdkVersion) + } + dependencySubstitution { // Because the client api artifact name is not the same as the directory structure, we use // Gradle's dependency substitution so the dependency will appear correctly in the pom files that diff --git a/gradle.properties b/gradle.properties index 9713b4d47d..8b3704dfe9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -105,7 +105,7 @@ apacheTomcatVersion=11.0.24 # tika asmVersion=9.10.1 -awsSdkVersion=2.29.50 +awsSdkVersion=2.41.22 # Microsoft library for sending OAuth2-authenticated notification emails via the Microsoft Graph API azureIdentityVersion=1.18.4 diff --git a/server/embedded/src/org/labkey/embedded/LabKeySpringBootClassLoader.java b/server/embedded/src/org/labkey/embedded/LabKeySpringBootClassLoader.java index 7e3a4d3f77..64100971f9 100644 --- a/server/embedded/src/org/labkey/embedded/LabKeySpringBootClassLoader.java +++ b/server/embedded/src/org/labkey/embedded/LabKeySpringBootClassLoader.java @@ -102,6 +102,17 @@ protected boolean filter(String name, boolean isClassName) { return true; } + // The AWS SDK is bundled both by the embedded boot classpath (e.g., for the SSM-backed + // application.properties/secrets support) and by modules that call the SDK directly (e.g., + // CloudServices, professional). Independently defining the same classes in both classloaders + // -- even at identical versions -- triggers a loader constraint violation whenever code loaded by + // one side hands an AWS SDK type to code loaded by the other. Deferring here means the module + // classloader reuses whichever copy the parent already loaded, falling back to its own bundled + // jars only for SDK modules (e.g., Bedrock) that the parent doesn't carry. + if (name.startsWith("software.amazon.awssdk.")) + { + return true; + } return super.filter(name, isClassName); }