Exclude dependency using Java instead of Groovy (aka closures in Java)

I’m writing a Gradle plugin where I want to achieve this:

    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }

I managed to do this:

public class MyPlugin implements Plugin<Project> {

  @Override
  public void apply(Project project) {
    project.getDependencies().add("testImplementation", "org.springframework.boot:spring-boot-starter-test");
  }
}

but can’t figure out how to do the exclude part (in Java). Can someone help me?

In java, its much cleaner to code against the Action interface instead of Closure. Many of the Gradle APIs allow both but not all have been provided. Its easy enough to write an adapter. Eg:

import gradle.api.Action;
import groovy.lang.Closure;
public class ActionClosure<T> extends Closure<Object> {
    private final Action<T> action;
    public ActionClosure(Action<T> action) {
        super(null);
        this.action = action;
    } 
    @Override
    public Object call() {
        action.execute((T) getDelegate());
        return null;
    } 
} 

Then, in java, you can do something like

Action<ModuleDependency> action = (dependency) -> {
   dependency.exclude(...);
};
project.getDependencies().add("testImplementation", "org.springframework.boot:spring-boot-starter-test", new ActionClosure<>(action));

Or another option is

ModuleDependency dep = (ModuleDependency)  project.getDependencies().add("testImplementation", "org.springframework.boot:spring-boot-starter-test");
dep.exclude(...);
1 Like

Thanks. I ended up with the second option, which works just great.

Regarding the first option, I had to add non-null owner in the ActionClosure constructor:

import gradle.api.Action;
import groovy.lang.Closure;
public class ActionClosure<T> extends Closure<Object> {
    private final Action<T> action;
    public ActionClosure(Object owner, Action<T> action) {
        super(owner);
        this.action = action;
    } 
    @Override
    public Object call() {
        action.execute((T) getDelegate());
        return null;
    } 
} 

and I passed project as owner (though I think it could have been anything). Otherwise I got IllegalArgumentException saying “Value is null”.

1 Like