Use Repository Manager to proxy Gradle Central Plugin Repository

We have now tighten our network, thus we cannot access the Gradle Central Plugin Repository any more.

All our dependencies are retrieved from Nexus Repository Manager. How can we also use Nexus for the Gradle plugins?
Adding repository to buildscript does not seem to work

buildscript {
    repositories {
        maven {
            url nexusUrl + "/gradle-plugins"
        }
    }
}

I have added the Gradle Plugin Repository to our Nexus as a proxy repository to https://plugins.gradle.org/m2/

I tried following the documentation and define Plugin Repository in the settings.gradle
https://docs.gradle.org/current/userguide/plugins.html#sec:custom_plugin_repositories

pluginManagement {
    repositories {
        maven {
            url nexusUrl + "/gradle-plugins"
        }
    }
}

However it still cannot find the plugins in our Nexus.

- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- Plugin Repositories (could not resolve plugin artifact 'com.diffplug.gradle.spotless:com.diffplug.gradle.spotless.gradle.plugin:3.26.0')
  Searched in the following repositories:
    maven(https://nexus.company.com:8443/repository/gradle-plugins)

Edit: It seems there is no JAR files in the Gradle Central Plugin Repository
https://plugins.gradle.org/m2/

Edit: It seems to work. The Nexus goes into the Gradle Central Plugin Repository, but only retrieves the POM files, as there is only pom files. After running gradle I have checked that the Nexus Gradle proxy repository does contain various plugins, but only the POM files and no JAR files.
Is the URL to Gradle Central Plugin Repository I am using correct?

There are not only just POM files at https://plugins.gradle.org/m2. There are JAR files not available on JCenter as well.

Specifically, there are POM files that map the plugin ID to the actual artifact coordinates for the plugin. There’s no JAR at the location of the marker interface, but plugins published directly to the plugin repository then have a POM and JAR at the actual coordinates. Third party dependencies redirect to JCenter, but there’s also some plugins that only publish their JAR to JCenter and rely on this redirect logic as well. Effectively, the plugin portal is a superset of JCenter with additional POMs and JARs.

So I could use JCenter as the Plugin Repository proxy in my Nexus?
We are using Maven Central as the Maven Repository proxy.

Edit: Just made an attempt, but it could not find the plugins in JCenter

pluginManagement {
    repositories {
        maven {
            url "https://jcenter.bintray.com/"
        }
    }
}

It is only the plugins that are not official Gradle plugins that we are not getting when using Nexus.

plugins {
    id 'com.diffplug.gradle.spotless' version '3.26.0'
    id 'com.google.osdetector' version '1.6.2'
    id 'nebula.ospackage' version '8.0.3'
    id 'org.openjfx.javafxplugin' version '0.0.8'
    id 'org.beryx.runtime' version '1.8.0'
    id 'de.undercouch.download' version '4.0.1'
}

With the legacy plugin application one could specify the repository for these plugins in the buildscript section. However that does not work either, it still goes to gradle central plugin repository.
https://plugins.gradle.org/plugin/com.diffplug.gradle.spotless

No, the Plugin Portal is a superset, not a subset of JCenter. Some requests end up going to JCenter, but there are JARs and POMs in the Plugin Portal that are not available directly in JCenter.

I was specifically addressing this point. There are JARs present, but not for every POM present. Some POMs reference other artifacts which are only on JCenter or only on the plugin portal. You would need to follow the dependency trail to see exactly which is the case for a given plugin. However, the plugin portal handles this transparently to the end user.

For Gradle plugin access through Nexus, setting up a proxy repository to https://plugins.gradle.org/m2/ and using that as the repository in buildscript or pluginManagement is enough. There’s really no way to tell what’s wrong with what you’ve provided. With what you’ve provided, your issues seem most likely environmental or in Nexus.

Ok. If that should work I will check into why it is not working in my case.
When browsing the Nexus I can see that it has downloaded the POMs, but not the JARs.

By adding my Maven Central proxy repository in addition to the Gradle Central Plugin Repository proxy seemed to get me a bit closer.

pluginManagement {
    repositories {
        maven {
            url nexusUrl + "/gradle-plugins"
        }
        maven {
            url nexusUrl + "/maven-public"
        }
    }
}

With this configuration it could find the spotless-gradle-plugin from diffplug

However it could still no find two of the other plugins. The badass-runtime-plugin, and osdetector

   > Could not find gradle.plugin.com.google.gradle:osdetector-gradle-plugin:1.6.2.
     Searched in the following locations:
       - https://nexus.company.com:8443/repository/gradle-plugins/gradle/plugin/com/google/gradle/osdetector-gradle-plugin/1.6.2/osdetector-gradle-plugin-1.6.2.pom
       - https://nexus.company.com:8443/repository/maven-public/gradle/plugin/com/google/gradle/osdetector-gradle-plugin/1.6.2/osdetector-gradle-plugin-1.6.2.pom
     Required by:
         project : > com.google.osdetector:com.google.osdetector.gradle.plugin:1.6.2
   > Could not find gradle.plugin.org.beryx:badass-runtime-plugin:1.8.0.
     Searched in the following locations:
       - https://nexus.company.com:8443/repository/gradle-plugins/gradle/plugin/org/beryx/badass-runtime-plugin/1.8.0/badass-runtime-plugin-1.8.0.pom
       - https://nexus.company.com:8443/repository/maven-public/gradle/plugin/org/beryx/badass-runtime-plugin/1.8.0/badass-runtime-plugin-1.8.0.pom
     Required by:
         project : > org.beryx.runtime:org.beryx.runtime.gradle.plugin:1.8.0

I even tried adding jcenter to my maven-public. What am I still missing?

You should not need /maven-public in the list or JCenter added to the Plugin Repository proxy.

However, looking at the images you originally posted, leaving the Validate that all content uploaded to this repository is of a MIME type appropriate for the repository format option enabled can cause issues with retrieving some of the files. Try unchecking this box and see where you’re at.

Tried to uncheck the “Strict Content Type Validation” and removed the maven-public from pluginManagement.

I also tried to set the following configuration as it seemed to make sense, since the Plugin Repository does lookup within it self for the plugins.
HTTP request settings:
Enable redirects to the same location (may be required by some servers)
Enable cookies

   > Could not find gradle.plugin.org.beryx:badass-runtime-plugin:1.8.0.
     Searched in the following locations:
       - https://nexus.company.com:8443/repository/gradle-plugins/gradle/plugin/org/beryx/badass-runtime-plugin/1.8.0/badass-runtime-plugin-1.8.0.pom
     If the artifact you are trying to retrieve can be found in the repository but without metadata in 'Maven POM' format, you need to adjust the 'metadataSources { ... }' of the repository declaration.
     Required by:
         project : > org.beryx.runtime:org.beryx.runtime.gradle.plugin:1.8.0

This plugin can be found on the Gradle Central Plugin Repository with POM and JARs and all.
https://plugins.gradle.org/m2/gradle/plugin/org/beryx/badass-runtime-plugin/1.8.0/
However my proxy cache contains only the bare plugin POM, that should point to the actual plugin.

https://nexus.company.com:8443/repository/gradle-plugins/org/beryx/runtime/org.beryx.runtime.gradle.plugin/1.8.0/org.beryx.runtime.gradle.plugin-1.8.0.pom

This seems to correspond to the following in the Gradle Central Plugin Repository:

https://plugins.gradle.org/m2/org/beryx/runtime/org.beryx.runtime.gradle.plugin/1.8.0/org.beryx.runtime.gradle.plugin-1.8.0.pom

Seems it does not fetch the dependencies from that POM.

I am at a loss. Cannot find out why it is not working.

* What went wrong:
Plugin [id: 'com.diffplug.gradle.spotless', version: '3.26.0'] was not found in any of the following sources:

- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- Plugin Repositories (could not resolve plugin artifact 'com.diffplug.gradle.spotless:com.diffplug.gradle.spotless.gradle.plugin:3.26.0')
  Searched in the following repositories:
    maven(https://nexus.company.com:8443/repository/gradle-plugins/)

Only the POM files are retrieved, but none of the actual plugins that those POM files points to.
https://plugins.gradle.org/m2/com/diffplug/gradle/spotless/com.diffplug.gradle.spotless.gradle.plugin/3.26.0/com.diffplug.gradle.spotless.gradle.plugin-3.26.0.pom

<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.diffplug.gradle.spotless</groupId>
  <artifactId>com.diffplug.gradle.spotless.gradle.plugin</artifactId>
  <version>3.26.0</version>
  <packaging>pom</packaging>
  <dependencies>
    <dependency>
      <groupId>com.diffplug.spotless</groupId>
      <artifactId>spotless-plugin-gradle</artifactId>
      <version>3.26.0</version>
    </dependency>
  </dependencies>
</project>

This plugin does not exist in the Gradle Central Plugin Repository. Perhaps that is why it cannot find it?
https://plugins.gradle.org/m2/gradle/plugin/com/diffplug/

The other plugin I was using did exist in the Gradle Central Plugin Repository
https://plugins.gradle.org/m2/gradle/plugin/org/beryx/badass-runtime-plugin/1.8.0/

How come it should be so cumbersome to add a simple plugin repository proxy.

There should not be anything at that location. That’s a completely invalid location for any artifact related to this plugin.

Are you sure you’re looking for the JAR files in the correct location? There will absolutely be a POM file in specific locations that has no accompanying JAR files. Screenshots of the details that are leading you to make this conclusion might be helpful to verify what’s working as expected or not.

Setting this up should generally take less than 5 minutes. There’s either something odd specific to your environment or a details that aren’t really being captured in the discussion. Remember that Nexus is serving as a caching proxy. If you’re rapidly changing many things, but not considering what the cache state may be, you might be jumping past working configurations before you truly see the result of those changes.

This is cached in my Nexus proxy for the Gradle Central Plugin Repository.
https://plugins.gradle.org/m2/org/beryx/runtime/org.beryx.runtime.gradle.plugin/1.8.0/org.beryx.runtime.gradle.plugin-1.8.0.pom

This POM points to the plugin at

<dependency>
  <groupId>gradle.plugin.org.beryx</groupId>
  <artifactId>badass-runtime-plugin</artifactId>
  <version>1.8.0</version>
</dependency>

https://plugins.gradle.org/m2/gradle/plugin/org/beryx/badass-runtime-plugin/1.8.0/badass-runtime-plugin-1.8.0.jar
The latter one is not being retrieved and cached in Nexus.

I have tried with a clean environment, no Gradle cache lying around.

I was specifically concerned about the caching mechanisms in Nexus, not Gradle. If you go through configurations A, B, and C, it’s possible that only B works, but you actually were still seeing the results of A, until the cache expires, and then you see the results of C, completely missing the results of B if you’re trying things quickly.

I struggle with exactly the same.

Any solution?

The plugin portal has some artifacts itself and some maybe not like for example transitive dependencies of the plugins.
For artifacts it does not have itself, the plugin portal used to redirect to JCenter.
JCenter in turn served what it has and for things it did not have forwarded to Maven Central.

Due to repeated problems with JCenter, Gradle now added a mirror / caching proxy of JCenter to which it redirects instead, but the remaining logic stays the same.

So if your caching proxy does not follow redirect responses, it might not be enough to proxy the plugin portal, but you also need to either proxy the JCenter proxy of Gradle, or JCenter directly, or probably even better Maven Central directly and maybe JCenter too on a lower priority to make it work properly.

Thanks
Yeah, it can be the extra proxy around JCenter that you have that messed this up.

I have now re-created the proxy in Nexus for plugins.gradle.org and now it works. But the root cause cold also have been your extra proxy cache. It is hard to tell.

But it doesn’t look like the POM files for the actually plugin is in plugins.gradle.org?

Best regards
Lucas

My proxy?
I’m just a user like you.
Where the POM file actually lives depends on the plugin.
Some are only published to Maven Central in total.
Some are only published to JCenter in total.
Some are only published to Gradle Plugin Portal in total.
Some are split, like the actual code artifact published to Maven Central, the plugin marker artifact to Gradle Plugin Portal.

When using the Gradle Plugin Portal this is more or less transparent as the Plugin Portal redirects to JCenter (or its proxy) which forwards to Maven Central if some artifact is not found in the own repository. But at least the plugin marker artifacts for most of the plugins should actually live inside Gradle Plugin Portal, as otherwise the respecitve plugin is also not discoverable via the search on plugins.gradle.org.

I am trying to follow the beaten path. I just publish the plugin as suggested by the Gradle documentation. So I wasn’t expecting the plugin to go to JCenter. But that what it looks like when I just click around in plugins.gradle.org/m2

As you say it is kid of transparent until it fails or not updated as it should. (Or maybe there’s some delay between the updates.)

In former times they were deployed to JCenter, but that is long past.
That was not the case anymore even before JCenter was made read-only.
But latest now that JCenter is read-only that is not the case anymore.
The actual plugin code should be actually in the Gradle Plugin Portal now if you publish iirc, at least if you use the recent version of the publish plugin.