Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When importing a bom, allow a bom that it imports to be excluded #317

Open
voduku opened this issue Dec 29, 2021 · 15 comments
Open

When importing a bom, allow a bom that it imports to be excluded #317

voduku opened this issue Dec 29, 2021 · 15 comments

Comments

@voduku
Copy link

voduku commented Dec 29, 2021

I would like to know how to exclude a specific dependency from spring boot dependencies in gradle. I am asking this because due to internal restriction and licensing, I can't pull com.oracle.database.jdbc:ojdbc-bom. Despite trying all exclusion recommendation out there, including instruction from spring boot gradle plugin page, none of them seems to be able to alter detachedConfiguration. I get this error no matter what.

Execution failed for task ':compileJava'.
> Could not resolve all files for configuration ':detachedConfiguration24'.
   > Could not find com.oracle.database.jdbc:ojdbc-bom:21.3.0.0.

My build.gradle:

plugins {
    id 'org.springframework.boot' version '2.6.2'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
}

group = ''
version = '1.0.0'
sourceCompatibility = '17'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

configurations.all {
    exclude group: 'com.oracle.database.jdbc', module: 'ojdbc-bom'
}

repositories {
    ... // some internal repo that mimic mavenCentral() but with licensing restriction
}

bootJar {
    enabled = false
}

jar {
    enabled = true
}


dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-r2dbc'
    implementation 'io.r2dbc:r2dbc-postgresql'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
}

test {
    useJUnitPlatform()
}
@wilkinsona wilkinsona changed the title Unable to exclude a specific dependency from spring boot dependencies When importing a bom, allow a bom that it imports to be excluded Jan 4, 2022
@jonathanq
Copy link

I've run into the same issue. The inclusion of the Oracle BOM which has a commercial license (not open source) is making it difficult to use any springboot project internally.

Is there a way to exclude it? Or stop referencing it by default since it's not an open source license?

@wilkinsona
Copy link
Contributor

wilkinsona commented Mar 3, 2024

As things stand, if you want greater control over this I would recommend using Gradle's built-in platform support instead of the dependency management plugin. You should be able to exclude the Oracle Database bom when you declare the platform dependency on spring-boot-dependencies.

@jonathanq
Copy link

I have't been able to find any way to add an exclusion that works. I will open a ticket with the spring-boot-project and see if they are willing to separate out the oracle dependency (https://github.com/spring-projects/spring-boot/blob/5600a02834d054ed86d2353a30d3c9f90acc7fd8/spring-boot-project/spring-boot-dependencies/build.gradle#L1382-L1392) since it's not licensed as open-source.

@wilkinsona
Copy link
Contributor

This should work with Gradle's platform support:

plugins {
	id 'java'
	id 'org.springframework.boot' version '3.2.3'
}

repositories {
	mavenCentral()
}

dependencies {
	implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)) {
		exclude(group: "com.oracle.database.jdbc")
	}
	implementation("com.oracle.database.jdbc:ojdbc11")
}

Due to the exclusion on the platform dependency, the runtime classpath will fail to resolve as there's no version available for com.oracle.database.jdbc:ojdbc11:

 gradle dependencies --configuration runtimeClasspath        

> Task :dependencies

------------------------------------------------------------
Root project 'exclude-oracle-bom'
------------------------------------------------------------

runtimeClasspath - Runtime classpath of source set 'main'.
+--- org.springframework.boot:spring-boot-dependencies:3.2.3
\--- com.oracle.database.jdbc:ojdbc11 FAILED

I've verified this as best I can by preventing com.oracle.database.jdbc downloads from Maven Central:

plugins {
	id 'java'
	id 'org.springframework.boot' version '3.2.3'
}

repositories {
	mavenCentral() {
		content {
			excludeGroup("com.oracle.database.jdbc")
		}
	}
}

dependencies {
	implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))
	implementation("com.oracle.database.jdbc:ojdbc11")
}

This shows a failure for Boot's bom as well as the ojdbc11 dependency:

$ gradle dependencies --refresh-dependencies --configuration runtimeClasspath                    

> Task :dependencies

------------------------------------------------------------
Root project 'exclude-oracle-bom'
------------------------------------------------------------

runtimeClasspath - Runtime classpath of source set 'main'.
+--- org.springframework.boot:spring-boot-dependencies:3.2.3 -> 3.2.3 FAILED
\--- com.oracle.database.jdbc:ojdbc11 FAILED

This is to be expected as the complete state of spring-boot-dependencies cannot be resolved.

@jonathanq
Copy link

I tried that first example:

dependencies {
	implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)) {
		exclude(group: "com.oracle.database.jdbc")
	}
}

However in Gradle 8.6 (I'm using a Kotlin build file) - it doesn't compile. I tried removing the group: and it still doesn't work. What version of Gradle were you trying that on?

@wilkinsona
Copy link
Contributor

My example's for the Groovy DSL. The equivalent in the Kotlin DSL, working around what appears to be a Gradle Kotlin DSL bug, is:

plugins {
	java
	id("org.springframework.boot") version "3.2.3"
}

repositories {
	mavenCentral() {
		content {
			excludeGroup("com.oracle.database.jdbc")
		}
	}
}

dependencies {
	implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)) {
		(this as ExternalModuleDependency).exclude(group = "com.oracle.database.jdbc")
	}
	implementation("com.oracle.database.jdbc:ojdbc11")
}

@jonathanq
Copy link

That solves the error I was getting - nice find.

So using the platform exclusion changes the error to just that it can't resolve the missing BOM file. Sorry if this is a dumb question - but is there a way to make the rest of the Spring Boot dependencies usable?

For example:

dependencies {
    implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)) {
        (this as ExternalModuleDependency).exclude(group = "com.oracle.database.jdbc")
    }

    implementation("org.springframework.cloud:spring-cloud-gateway-mvc:4.+")
}

Will still fail with missing Oracle bom

> Task :compileJava FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':compileJava'.
> Could not resolve all files for configuration ':compileClasspath'.
   > Could not resolve org.springframework.boot:spring-boot-dependencies:3.2.3.
     Required by:
         project :
      > Could not resolve org.springframework.boot:spring-boot-dependencies:3.2.3.
         > Could not parse POM maven/org/springframework/boot/spring-boot-dependencies/3.2.3/spring-boot-dependencies-3.2.3.pom
            > Could not find com.oracle.database.jdbc:ojdbc-bom:21.9.0.0.
   > Could not resolve org.springframework.cloud:spring-cloud-gateway-mvc:4.+.
     Required by:
         project :
      > Could not resolve org.springframework.cloud:spring-cloud-gateway-mvc:4.1.1.
         > Could not parse POM maven/org/springframework/cloud/spring-cloud-gateway-mvc/4.1.1/spring-cloud-gateway-mvc-4.1.1.pom
            > Could not resolve org.springframework.cloud:spring-cloud-gateway:4.1.1.
               > Could not resolve org.springframework.cloud:spring-cloud-gateway:4.1.1.
                  > Could not parse POM maven/org/springframework/cloud/spring-cloud-gateway/4.1.1/spring-cloud-gateway-4.1.1.pom
                     > Could not resolve org.springframework.cloud:spring-cloud-build:4.1.0.
                        > Could not resolve org.springframework.cloud:spring-cloud-build:4.1.0.
                           > Could not parse POM maven/org/springframework/cloud/spring-cloud-build/4.1.0/spring-cloud-build-4.1.0.pom
                              > Could not resolve org.springframework.cloud:spring-cloud-build-dependencies:4.1.0.
                                 > Could not resolve org.springframework.cloud:spring-cloud-build-dependencies:4.1.0.
                                    > Could not parse POM maven/org/springframework/cloud/spring-cloud-build-dependencies/4.1.0/spring-cloud-build-dependencies-4.1.0.pom
                                       > Could not resolve org.springframework.boot:spring-boot-dependencies:3.2.0.
                                          > Could not resolve org.springframework.boot:spring-boot-dependencies:3.2.0.
                                             > Could not parse POM maven/org/springframework/boot/spring-boot-dependencies/3.2.0/spring-boot-dependencies-3.2.0.pom
                                                > Could not find com.oracle.database.jdbc:ojdbc-bom:23.3.0.23.09.

I am assuming as long as the com.oracle.database.jdbc:ojdbc-bom is a dependency of the spring-boot-dependencies there is no way to use it without including that. Excluding the BOM is not enough as it's still a required dependency.

@wilkinsona
Copy link
Contributor

Can you share a build script that reproduces that error? I can see that you're using Spring Cloud which you haven't mentioned thus far.

@jonathanq
Copy link

I commented out the cloud-gateway. I was trying to use that in a project. But even without that, this gradle file doesn't work when you try to run the application with ./gradlew bootRun

plugins {
    java
    id("org.springframework.boot") version "3.2.3"
    id("io.spring.dependency-management") version "1.1.4"
}

java {
    sourceCompatibility = JavaVersion.VERSION_17
}

group = "dev.quail"
version = "1.0"

dependencies {
    implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)) {
        (this as ExternalModuleDependency).exclude(group = "com.oracle.database.jdbc")
    }

    //implementation("org.springframework.cloud:spring-cloud-gateway-mvc:4.+")

    implementation("org.springframework.boot:spring-boot-starter-web")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
}

@wilkinsona
Copy link
Contributor

You should remove the dependency management plugin. Using a platform dependency with an exclusion is intended as a workaround for the fact that the feature requested in this issue does not exist. This works for me:

plugins {
	java
	id("org.springframework.boot") version "3.2.3"
}

java {
	sourceCompatibility = JavaVersion.VERSION_17
}

repositories {
	mavenCentral() {
		content {
			excludeGroup("com.oracle.database.jdbc")
		}
	}
}

group = "dev.quail"
version = "1.0"

dependencies {
	implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)) {
		(this as ExternalModuleDependency).exclude(group = "com.oracle.database.jdbc")
	}
	implementation("org.springframework.boot:spring-boot-starter-web")
	testImplementation("org.springframework.boot:spring-boot-starter-test")
}

@jonathanq
Copy link

Can you run a basic SpringBoot app with that? When I try to run it with Gradle I just get the error about the missing dependency (run using ./gradlew bootRun

 ./gradlew bootRun
> Task :compileJava FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':compileJava'.
> Could not resolve all files for configuration ':compileClasspath'.
   > Could not resolve org.springframework.boot:spring-boot-dependencies:3.2.3.
     Required by:
         project :
      > Could not resolve org.springframework.boot:spring-boot-dependencies:3.2.3.
         > Could not parse POM /maven/org/springframework/boot/spring-boot-dependencies/3.2.3/spring-boot-dependencies-3.2.3.pom
            > Could not find com.oracle.database.jdbc:ojdbc-bom:21.9.0.0.

That is with a basic Java app defined:

package dev.quail;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class QualDevApp {

    public static void main(final String[] args) {
        SpringApplication.run(QualDevApp.class, args);
    }
}

@wilkinsona
Copy link
Contributor

Yes, I could. Perhaps it's because you genuinely have no access to com.oracle.database.jdbc:ojdbc-bom:21.9.0.0 whereas I am relying on the exclude group configuration when I declare the Maven Central repository?

@aluferraz
Copy link

aluferraz commented May 6, 2024

Any workarounds ? I'm facing the same issue. My company's internal repo doesn't have any com.oracle.database.jdbc version.

@wilkinsona
Copy link
Contributor

Yes, use Gradle's platform support as described above. Beyond that, spring-projects/spring-boot#39945 will help once it has been released later this month.

@aluferraz
Copy link

aluferraz commented May 10, 2024

Thanks! I was not able to compile using that approach. Since I don't need ojdbc, I created a local maven repo holding only the XML Pom (no jar files), and did this :

    repositories {
        maven {
.....
 exclusiveContent {
            forRepository {
                maven {
                    name = "Local"
                    url = uri("file://${System.getProperty('user.dir')}/repo/maven2")
                    metadataSources {
                        // This is to say, we only have the artifacts (a pom, jar, ...).
                        mavenPom()
                    }
                    content {
                        // We only want to look for things from these group/module/versions in our "repo"
                        includeGroup("com.oracle.database.jdbc")
                        includeModule("com.oracle.database.jdbc", "ojdbc-bom")
                        includeVersion("com.oracle.database.jdbc", "ojdbc-bom", "21.9.0.0")
                        includeVersion("com.oracle.database.jdbc", "ojdbc-bom", "23.3.0.23.09")
                        includeVersion("com.oracle.database.jdbc", "ojdbc-bom", "19.3.0.0")
                        includeVersion("com.oracle.database.jdbc", "ojdbc-bom", "21.7.0.0")

                    }
                }
            }
            filter {
                // this repository *only* contains artifacts with group "com.oracle.database.jdbc"
                includeGroup("com.oracle.database.jdbc")
            }
        }
...        

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants