Impact of final JCenter shutdown on Gradle Plugin Portal

Table of Contents

Introduction

ℹ️ Update on July 15, 2024
We have found errors causing false positive in failed plugin resolution. 4 plugins have been removed from the list, resulting in 9 removed dependencies. We also added 105 plugins that depend on one or more affected plugins. These will fail to resolve transitively. Not taking exclude into account caused the first change, the second one came from not taking plugin dependencies into account.

Now that JFrog has confirmed that JCenter will become a permanent redirect to Maven Central, we felt that it was important for the Gradle Plugin Portal users to understand the impact of that decision on the portal and their builds. This post follows our report after JCenter redirected to Maven Central for a day.

Users still directly using JCenter should also refer to our original blog post about the changes in JCenter and their impact on Gradle builds in general.

Upcoming Plugin Portal changes #

JCenter will become a permanent redirect to Maven Central. As a consequence, the Gradle Plugin Portal will no longer act as a JCenter proxy and will instead become a Maven Central proxy.

The Gradle Plugin Portal will continue to return redirects (303 See Other) for artifact queries it cannot serve. Starting July 15, 2024, these redirects will be towards Maven Central instead of JCenter.

This change might impact existing Gradle builds:

  • Build using plugins with dependencies that are exclusively available on JCenter will fail to resolve.
  • Builds configured to use the Gradle Plugin Portal as a regular artifact repository (which is not recommended) may be impacted. For more information, refer to our original blog post.

We aim to document the potential impact on Gradle plugins provided by the Plugin Portal. Read our analysis below to learn how to minimize the impact on your builds.

Impact analysis #

We have performed two major analyses:

  1. For all the plugins known to the Gradle Plugin Portal, determine which ones would fail to resolve if their transitive dependencies are resolved on Maven Central only. See Plugin resolution impact below.
  2. For all the existing redirect traffic on the Gradle Plugin Portal, determine how much would fail if the redirect was towards Maven Central instead of JCenter. See Dependency resolution impact below.

Plugin resolution impact #

At the time of the analysis (June 6, 2024), the Plugin Portal served more than 7,400 plugins, each with at least one published version. Taking into account only the most recent version of each plugin, we found the following:

  1. 322 unique plugin IDs fail to resolve, even with JCenter available. This indicates that their usage requires additional repository configuration. These were excluded from the rest of the investigation.
  2. 351 unique plugin IDs fail to resolve because a transitive dependency is missing when using Maven Central as the proxy target.
  3. These failures point at 206 unique <group>:<artifact>, for a total of 244 unique dependencies (unique <group>:<artifact>:<version>) that are available on JCenter but not on Maven Central.
  4. In addition, 104 plugins have a dependency on one or more of the 351 failing plugins above. They will most likely fail to resolve as well because of the transitive dependency.

See our testing methodology in the appendix below for details on how we obtained these numbers.

We also analyzed this data based on the publication year of each plugin version. You can see the breakdown in the following table:

Publication year Failed plugins count Total plugins analyzed
2024 2 1350
2023 3 1205
2022 7 790
2021 53 828
2020 76 803
2019 54 698
2018 42 531
2017 39 533
2016 23 323
2015 50 261
2014 2 61

As we can see from the data, recent plugins are less affected by the change, while older plugins are more likely to be affected. This means that older builds are more likely to be impacted by the upcoming change.

Next steps #

The 351 affected plugins’ latest version descriptions on the Plugin Portal will be updated to indicate that they rely on dependencies that are not available on Maven Central.

We will also email the affected plugin authors to inform them about the issue. We hope that those still maintaining their plugins will be able to address the situation.

To check if your build is impacted, refer to the resources section below, which provides files listing the affected plugins and dependencies.

Dependency resolution impact #

In addition to downloading plugins, the Gradle Plugin Portal is used as a regular artifact repository for project dependencies. While this was never recommended, it worked because the Plugin Portal is effectively a proxy for JCenter in the past and Maven Central in the future.

Over 7 days, the Gradle Plugin Portal served more than a billion redirects (303 See Other) for artifacts it cannot serve. When analyzing this traffic, we limited ourselves to requests for files matching a Maven repository pattern. These amounted to 5 million different GAVs. Out of these, we reduced the total to 4.8 million by focusing on requests with a .pom, .module, or .jar file extension.

From the data, we can see that builds request company internal artifacts that we do not expect to find on a public repository. Gradle has a repository content filtering feature that can speed up builds and hide that information. We also see builds or mirrors that are misconfigured. For those reasons, we will not make this data public.

Sonatype, the steward of Maven Central, confirmed that out of the 4.8 million requests, only 25% match GAVs that are known to Maven Central.

We also looked at data shared by JFrog about JCenter and found that only an additional 3% of the failed requests were resolved on JCenter. As a reminder, JCenter was itself serving all of Maven Central’s content and the files it hosted.

From the Plugin Portal side, when requests fail to find dependencies on Maven Central, we cannot know if the build that made the request failed. This is because the requesting build can have additional repositories configured.

We continue to discourage using the Gradle Plugin Portal as a proxy. If your build logic requires non-plugin dependencies, add a repository like Maven Central to your build configuration. And make sure that it has the dependency you require!

Resources #

Here is the list of the resources we collected during our analysis. They might be useful in assessing the impact of the upcoming change on your builds.

What about the org.gradle coordinates present in these analysis results? #

A number of Gradle artifacts are impacted by this change: dependencies and plugins.

org.gradle:gradle-* dependencies #

Several Gradle artifacts for older versions, 2 and 3, were published to JCenter. They are also published to a repository managed by Gradle and should be used from that location.

However, the plugins that are broken because they depend on those artifacts should not have that dependency in the first place. A plugin, when running in the build, will use the classes from the Gradle distribution in use. There is no way to load a different version of these classes. We can thus consider the metadata of those affected plugins as incorrect. We recommend that impacted users clean up those dependencies through component metadata rules or add the repository indicated above to their plugin resolution.

org.gradle.guides.* plugins #

Some older Gradle plugins are impacted as they depend on packages available on JCenter only. Those plugins have been consolidated under three Gradle Documentation plugins, which have more recent versions that are not impacted. Users should upgrade their plugin dependency.

Annex #

Plugin resolution testing methodology #

This section describes the testing methodology for determining the plugin resolution impact.

  1. Write a Gradle build that resolves plugins as regular dependencies using gradlePluginPortal() as the repository. This means we did not try applying the plugins.
    • We added one more repository with the following configuration to account for the Android ecosystem that relies on the Google repository:
       google() {
       	content {
        	includeGroupByRegex("com\\.android.*")
        	includeGroupByRegex("com\\.google.*")
        	includeGroupByRegex("androidx.*")
        	includeGroupByRegex("android.*")
       	}
       }
      
  2. Collect the failures from these resolution attempts. These failures are the 322 failed plugins, even with JCenter available.
  3. Collect the direct dependencies of successful resolutions.
  4. Resolve these direct dependencies against Maven Central, taking dependency exclusions into account. Once again, with the additional google() repository configuration shown above. Plugin dependencies were excluded at this stage, as they are expected to resolve against the Plugin Portal only.
  5. Collect the failures. These failures are the 351 failing plugins if Maven Central is used instead of JCenter.
  6. Process the dependency data. This is what gave us the 244 dependencies for 206 unique <group>:<artifact>.
  7. Take into account the plugins having a plugin dependency on one of the failed plugins. This adds back 104 plugins.

Discuss