Unable to resolve a plugin using the new plugin mechanism in Gradle - gradle

While trying to upgrade some of our scripts to Gradle 4.0.1 on of the plugins we are using is failing and I thought of fixing that plugin first. The plugin is a third party open source project.
So I have cloned the project and tried to compile it. However it fails with following message:
c:\source\gradle-xld-plugin>gradlew build
FAILURE: Build failed with an exception.
* Where:
Build file 'C:\source\gradle-xld-plugin\build.gradle' line: 2
* What went wrong:
Plugin [id: 'com.gradle.plugin-publish', version: '0.9.7'] was not found in
any of the following sources:
- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- maven(https://artifactory/java-v) (Could not resolve plugin artifact 'com.gradle.plugin-publish:com.gradle.plugin-publish.gradle.plugin:0.9.7')
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --
debug option to get more log output.
BUILD FAILED in 0s
The build.gradle script for the plugin starts like this:
plugins {
id "com.gradle.plugin-publish" version "0.9.7"
id "com.github.hierynomus.license" version "0.11.0"
id 'nebula.nebula-release' version '4.0.1'
id "com.jfrog.bintray" version "1.7.3"
}
In addition to this the company policy dictates we have to go through an internal artifactory server, so following has been added to the settings.gradle file:
pluginManagement {
repositories {
maven {
url "https://artifactory/java-v"
}
}
}
The jar file exists at following location: https://artifactory/java-v/com/gradle/publish/plugin-publish-plugin/0.9.7/plugin-publish-plugin-0.9.7.jar
but when I look at the error message I am a little puzzled that it says that it cannot find com.gradle.plugin-publish:com.gradle.plugin-publish.gradle.plugin:0.9.7.
It seems to have suffixed the id with .gradle.plugin.
Does anyone know whether I am looking at the wrong location or how come it is suffixing the id with .gradle.plugin. And shouldn't it look at a location that has the GAV like this: com.gradle.plugin-publish:com.gradle.plugin-publish:0.9.7?
And does anyone know about how the resolution mechanism for the new plugin mechanism in Gradle works.
Thanks in advance
Edit
Thanks to Mateusz Chrzaszcz I was able to progress.
The only caveat I have with the solution is that it seems like a workaround rather than a solution. But it works!
In addition to his solution you had to resolve the plugins. I was able to hack my way to actually resolve the appropriate names.
In order to do so one has to do as follows:
In a webbrowser go for the plugin: id "com.github.hierynomus.license" version "0.11.0" go to following URL: https://plugins.gradle.org/api/gradle/4.0.1/plugin/use/com.github.hierynomus.license/0.11.0
The json returned contains the GAV needed in the useModule call. Use that
The following serves as an example:
resolutionStrategy {
eachPlugin {
if (requested.id.namespace == 'com.gradle' && requested.id.name == 'plugin-publish') {
useModule('com.gradle.publish:plugin-publish-plugin:0.9.7')
} else if(requested.id.namespace == 'com.github.hierynomus' && requested.id.name == 'license') {
useModule('nl.javadude.gradle.plugins:license-gradle-plugin:0.11.0')
}
}
}

Try to implement Plugin Resolution Rules.
According to gradle documentation:
Plugin resolution rules allow you to modify plugin requests made in plugins {} blocks, e.g. changing the requested version or explicitly specifying the implementation artifact coordinates.
To add resolution rules, use the resolutionStrategy {} inside the pluginManagement {} block
like that:
pluginManagement {
resolutionStrategy {
eachPlugin {
if (requested.id.namespace == 'com.gradle.plugin-publish') {
useModule('com.gradle.plugin-publish:0.9.7') //try a few combinations
}
}
}
repositories {
maven {
url 'https://artifactory/java-v'
}
}
}
Keep in mind this is incubating feature though.

Related

using jib for multiple project build

I have a multimodule project that I am trying to use gradle 7.5.1 and jib to build and deploy each service artifact to ECR.
I have a ~/.docker/config.json file
{
"credsStore": "desktop"
}
{
"credHelpers": {
"public.ecr.aws": "ecr-login",
"xxxxxxx.dkr.ecr.us-east-1.amazonaws.com": "ecr-login"
}
}
and my AWS keys are in ~/.aws/credentials
Each of my modules has a settings.gradle that defines the rootProject.name to be the service (artifactId), as well as the plugin 'maven-publish'.
In my main project I have a build.gradle:
plugins {
id 'java'
id 'groovy'
id 'com.google.cloud.tools.jib' version '3.3.0'
id 'maven-publish'
}
..
jib {
from {
image = 'azul/zulu-openjdk:17-jre'
}
to {
image = 'xxxxxxx.dkr.ecr.us-east-1.amazonaws.com/${rootProject.name}'
// I have also tried image = 'xxxxxxx.dkr.ecr.us-east-1.amazonaws.com/${artifactId}'
}
}
When I try to build them via gradle jib I get the following error:
> Task :jib FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':jib'.
> Invalid image reference xxxxxxx.dkr.ecr.us-east-1.amazonaws.com/${rootProject.name}, perhaps you should check that the reference is formatted correctly according to https://docs.docker.com/engine/reference/commandline/tag/#extended-description
For example, slash-separated name components cannot have uppercase letters
The stacktrace also mentioned the invalid reference.
I am following several tutorials and the Google jib documentation, but I do not see what I am doing wrong - anyone else know?
Use double quotes instead of single quotes to make Gradle expand properties.

Gradle cannot find plugin declared in buildscript

I'm trying to factor out common Gradle tasks in a reusable file. Here is an excerpt of a build-root.gradle file:
buildscript {
// Repository declaration
ext {
isSnapshot = version.endsWith("-SNAPSHOT")
repos = {
def mavenRepo = { repoName, repoUrl ->
maven {
credentials {
username System.env.<some env var>
password System.env.<some env var>
}
name repoName
url repoUrl
}
}
mavenLocal()
mavenRepo('repo1', 'https://repo1.url')
mavenRepo('repo2', 'https://repo2.url')
mavenRepo('repo3', 'https://repo3.url')
}
}
// Versions and libraries declaration
ext {
versions = [
... some stuff
// Gradle
gradleRelease : '2.8.1',
... more stuff
]
libs = [
... some stuff
// Gradle
gradleRelease : "net.researchgate:gradle-release:$versions.gradleRelease",
... more stuff
]
}
repositories repos
dependencies {
classpath libs.gradleRelease
}
apply plugin: 'net.researchgate.release'
}
... more common stuff
The idea is for subprojects to apply from that file and get all the goodies from it.
On the "apply plugin" line I get the following error - > Plugin with id 'net.researchgate.release' not found.
I printed the libs.gradleRelease string, it looks fine: net.researchgate:gradle-release:2.8.1
We are currently using Gradle 5.2.1, but I also tried 6.0.1 - same error. Any ideas why it can't find the plugin? BTW, this is not exclusive to this particular plugin, I tried others and still get the same error.
After pulling whatever was left of my hair and banging my head against the wall, I came across this => https://discuss.gradle.org/t/how-do-i-include-buildscript-block-from-external-gradle-script/7016
Relevant comment from #Peter_Niederwieser:
"Secondly, externalizing a build script block into a script plugin isn’t supported. (It’s a tough problem, and can’t think of a good way to implement this.) You may have to live with some duplication, at least for the time being. Remember that dependencies specified in a project’s ‘buildscript’ block are visible to all subprojects. Hence, as long as you don’t need dependencies to be available in a script plugin, you just need to declare them in the root project’s build script."
Which is exactly what I was trying to do. I'm not going to curse here...

Task and plugin conflict in Gradle (Failed to apply plugin [class 'org.gradle.langu...)

I tried to run a task from build.gradle using the following command:
gradle footype
However the build failed and displayed these two error messages that I want to fix:
> Configure project :
The Task.leftShift(Closure) method has been deprecated and is scheduled to
be removed in Gradle 5.0. Please use Task.doLast(Action) instead.
And this message as well:
* What went wrong:
An exception occurred applying plugin request [id: 'java']
> Failed to apply plugin [class
'org.gradle.language.base.plugins.LifecycleBasePlugin']
> Declaring custom 'assemble' task when using the standard Gradle
lifecycle plugins is not allowed.
Here is the code of the build.gradle file:
plugins{
id "com.gradle.build-scan" version "1.10.2"
id "org.arquillian.spacelift" version "1.0.0-alpha-17"
id "java"
}
group 'k'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
task fooType {
doLast {
def foo = "bar"
println "$foo + foo = ${foo + "foo"}"
}
}
I searched on other posts and they all seem to mention a task called clean() which doesn't appear in my code, so I'd like to know what's the problem.
Thank you muchly for reading this post.
When it comes to this message:
Configure project :
The Task.leftShift(Closure) method has been deprecated and is scheduled to
be removed in Gradle 5.0. Please use Task.doLast(Action) instead.
it is just a warning. It states that one (possibly more) plugin you applied uses << which will be removed in version 5.0 of gradle in favour of doLast. You are not using << directly in your script and that's ok. To eliminate this warning first of all you need to know which plugin uses it, then raise an issue on plugin's site asking for deprecated code elimination.
When it comes to the second message it's an error and in single build script nothing can be done about it. Two plugins java and org.arquillian.spacelift have declared a task with the same name (it's assemble) - this is a conflict. Maybe you can split you project into a multimodule?

Utilize ant in settings.gradle during configuration phase

I want to apply a shared gradle file to my projects settings.gradle. The shared file is located in a jar which must be downloaded and extracted during the configuration phase. This is because is applies a plugin which must be applied in the configuration phase. I found this related question: How to share a common build.gradle via a repository? My preferred way is described in this answer: https://stackoverflow.com/a/39228611/987860
However, this appears to be working in build.gradle only. I tried to move the buildscript block to my settings.gradle.
settings.gradle
buildscript {
ext {
dependencyVersion = '0.1.2'
}
repositories {
maven {
credentials {
username 'user'
password 'password'
}
url 'https://my-private-maven-repo.com'
}
}
dependencies {
classpath "my.group:myartifact:$dependencyVersion"
}
dependencies {
def gradleScripts = new File(rootDir, '/build/gradle')
delete gradleScripts
def jars = configurations.classpath.files as List<File>
ant.unjar(src: jars.find { it.name.matches '.*myartifact.*' }, dest: gradleScripts) {
patternset {
include(name:'*.gradle')
}
}
}
}
apply from: new File(rootDir, '/build/gradle/myscript.gradle')
But this results in the following exception:
FAILURE: Build failed with an exception.
* Where:
Settings file 'settings.gradle' line: 24
* What went wrong:
A problem occurred evaluating settings 'journal'.
> Could not get unknown property 'ant' for object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: 0.019 secs
Could not get unknown property 'ant' for object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.
Is there any way to utilize ant int the confiuration phase before my settings.gradle is evaluated? I need to have the dependency downloaded and extractet before the to-be-downloaded file gets applied.
This is a really unusual way to do things. I'd really recommend not doing what you're trying to do because it'll make your build much slower than it should be. You're deleting build/gradle and extracting the contents of the plugin's jar on every build.
Everything inside a build.gradle (or settings.gradle) can be put into a plugin and distributed that way. You already have a jar that needs to be downloaded, so converting myscript.gradle into a plugin is very easy to roughly convert.
Put this in src/main/groovy/some/package/MyPlugin.groovy in the project that's producing the plugin jar already:
package some.package
import org.gradle.api.*
class MyPlugin implements Plugin<Project> {
void apply(Project project) {
project.with {
// contents of script
}
}
}
For plugins applied to settings.gradle:
package some.package
import org.gradle.api.*
class MyPlugin implements Plugin<Settings> {
void apply(Settings settings) {
settings.with {
// contents of script
}
}
}
Then you can just add the dependency to the plugin and use apply plugin: some.package.MyPlugin.
There are a lot of other advantages of developing/distributing plugins in this way. You can find more information on plugin development in the Gradle Guides.
Alternatively, if you absolutely must keep the separate .gradle script. If you can serve it separately (outside of the jar), you can do:
apply from: "http://example.com/some/url/myscript.gradle"
The downside with this is that it'll download the file on every build (this is fixed in Gradle 4.2).

Changing configuration with the gretty plugin?

I haven't done anything with Gradle for a while, so it appears I've forgotten how configuration resolution works.
I'm trying to use the gretty plugin (instead of core, deprecated jetty), but I cannot seem to create a custom configuration.
I've boiled it down to a very short, simple script (using Gradle 3.4):
buildscript {
repositories {
maven {
url 'https://plugins.gradle.org/m2/'
}
}
dependencies {
classpath 'org.akhikhl.gretty:gretty:1.4.0'
}
}
plugins {
id 'org.akhikhl.gretty' version '1.4.0'
}
configurations {
fooTest
}
configurations.fooTest.each {
println it.toString()
}
It seems to not like me iterating over the fooTest configuration.
Assuming I need to know the dependencies for that configuration (I stripped that part from the code above)
What am I doing wrong here?
The script above gives me this:
org.gradle.api.InvalidUserDataException: Cannot change strategy of configuration ':fooTest' after it has been resolved.
The key point here was that I needed an unresolved configuration to loop over. Admittedly this information was neglected in the initial description as I didn't know it was critical information. We needed to loop over the files in the dependency and copy/unzip them into certain locations.
However, we cannot do that with a resolved configuration. That said, we can copy the configuration into a unresolved one, and loop over that instead:
configurations.fooTest.copy().each {
println it.toString()
}
This will successfully print out the files involved in the dependency (or unzip them, as my case needs).

Resources