Gradle design causes binary-incompatibilities and failed builds

Maven loads each mojo in a separate classloader, which allows them to interoperate even if written using very different versions of dependencies.

Gradle combines everything into one program that runs in its uber-jar.

When plugins aren’t binary-compatible with the uber-jar, builds fail. For example:

[2019-09-06T01:15:49.953Z] Caused by: java.lang.NoSuchMethodError: okhttp3.Cookie.toString(Z)Ljava/lang/String;
[2019-09-06T01:15:49.953Z] at okhttp3.JavaNetCookieJar.saveFromResponse(JavaNetCookieJar.java:43)
[2019-09-06T01:15:49.953Z] at okhttp3.internal.http.HttpHeaders.receiveHeaders(HttpHeaders.kt:207)
[2019-09-06T01:15:49.953Z] at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:86)
[2019-09-06T01:15:49.953Z] at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
[2019-09-06T01:15:49.953Z] at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:71)
[2019-09-06T01:15:49.953Z] at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
[2019-09-06T01:15:49.953Z] at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
[2019-09-06T01:15:49.953Z] at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.kt:184)
[2019-09-06T01:15:49.953Z] at okhttp3.RealCall.execute(RealCall.kt:66)
[2019-09-06T01:15:49.953Z] at com.blackducksoftware.integration.hub.rest.CredentialsRestConnection.clientAuthenticate(CredentialsRestConnection.java:86)
[2019-09-06T01:15:49.953Z] at com.blackducksoftware.integration.hub.rest.RestConnection.connect(RestConnection.java:128)
[2019-09-06T01:15:49.953Z] at com.blackducksoftware.integration.hub.rest.RestConnection.handleExecuteClientCall(RestConnection.java:350)
[2019-09-06T01:15:49.953Z] at com.blackducksoftware.integration.hub.rest.RestConnection.handleExecuteClientCall(RestConnection.java:317)
[2019-09-06T01:15:49.953Z] at com.blackducksoftware.integration.hub.request.HubRequest.executePost(HubRequest.java:85)
[2019-09-06T01:15:49.953Z] at com.blackducksoftware.integration.hub.api.bom.BomImportRequestService.importBomFile(BomImportRequestService.java:55)
[2019-09-06T01:15:49.953Z] at com.blackducksoftware.integration.hub.buildtool.BuildToolHelper.deployHubOutput(BuildToolHelper.java:71)
[2019-09-06T01:15:49.953Z] at com.blackducksoftware.integration.gradle.task.BuildBomTask.deployHubBDIO(BuildBomTask.java:240)
[2019-09-06T01:15:49.953Z] at com.blackducksoftware.integration.gradle.task.BuildBomTask.performTask(BuildBomTask.java:153)
[2019-09-06T01:15:49.953Z] at com.blackducksoftware.integration.gradle.task.BuildBomTask.task(BuildBomTask.java:130)
[2019-09-06T01:15:49.953Z] at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:103)
[2019-09-06T01:15:49.953Z] at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:48)

I understand that launching separate classloaders for each mojo is slower than running one giant program, provided the one giant program doesn’t crash.

But when it crashes, like above, then the build fails, and a failed build is infinitely slow compared to a Maven build that finishes successfully.

(And because blackduck is archived, the only way we can fix the above problem is either forking blackduck, or finding an alternative to blackduck. Or not upgrade Gradle.)