Gradle Custom Plugin: gradleApi() vs Explicit Dependency - gradle

I'm developing a custom gradle plugin and the dependencies for my plugin project look like this:
dependencies {
compile gradleApi()
compile localGroovy()
compile('com.xxx.oozie:oozie-dsl-parser:1.0.127') {
exclude module: 'groovy-all'
}
testCompile('org.spockframework:spock-core:1.0-groovy-2.3') {
exclude module: 'groovy-all'
}
}
However, in the interest of reproducible builds, I'm wondering if using localGroovy() and gradleApi() is advisable.
After much googling, although I could replace localGroovy() with a specific version of groovy, I can't seem to find a definitive answer on what I would replace gradleApi() with.
Do you guys have any suggestions?
Thanks!

I suggest applying the java-gradle-plugin. It adds the gradleApi() dependency automatically and also includes some other boilerplate configurations: https://docs.gradle.org/current/userguide/javaGradle_plugin.html#gsc.tab=0
The version of the gradleApi() that is added as dependency depends on the Gradle version that you are using the build the project. For example if your wrapper has Gradle 2.14.1 the used Gradle API will be of that version.
You also do not have to worry about localGroovy() because it is already included in the gradleTestKit() dependency which is added by the plugin: https://docs.gradle.org/current/userguide/test_kit.html#sub:test-kit-automatic-classpath-injection&gsc.tab=0
Here is an example:
apply plugin: 'groovy'
apply plugin: 'java-gradle-plugin'
dependencies {
testCompile('org.spockframework:spock-core:1.0-groovy-2.4') {
exclude module: 'groovy-all'
}
}

Looking at https://github.com/gradle/gradle/issues/1835 it seems like there is no explicit dependency you can use for that purpose.
Although not equivalent to gradleApi(), if you are developing for Android you might be interested in the com.android.tools.build:gradle-api:3.3.2 dependency.

Related

Upgrading from gradle 5.2 -> 6.0 gives error: could not find or load main class

I'm upgrading gradle for my Grails application from version 5.2 to 6.0 following their official guide: https://docs.gradle.org/current/userguide/upgrading_version_5.html
This is not going that well, as I can now not start any of my subprojects. The one I'm testing is called integration, and after the upgrade (and changing compile to implementation), the build.gradle looked like this:
buildscript {
repositories {
mavenLocal()
maven { url "https://repo.grails.org/grails/core" }
maven artifactory
}
dependencies {
classpath "org.jsonschema2pojo:jsonschema2pojo-gradle-plugin:$jsonToPojoVersion"
classpath "org.grails:grails-gradle-plugin:$grailsVersion"
classpath "org.grails.plugins:views-gradle:$grailsViewsGradleVersion"
classpath "com.bertramlabs.plugins:asset-pipeline-gradle:$assetPipelineVersion"
classpath "org.codehaus.groovy:groovy-all:$groovyVersion"
}
}
apply plugin: "war"
apply plugin: "org.grails.grails-web"
apply plugin: "org.grails.plugins.views-json"
apply from: "${rootProject.rootDir}/gradle/common.gradle"
apply from: "${rootProject.rootDir}/gradle/deployable.gradle"
apply from: "${rootProject.rootDir}/gradle/json2pojo.gradle"
springBoot {
mainClassName = 'dk.erst.plandata.integration.Application'
}
dependencies {
profile "org.grails.profiles:rest-api"
implementation group: 'org.hibernate', name: 'hibernate-validator', version: hibernateValidatorVersion
implementation "org.grails.plugins:cache-ehcache:$ehcacheVersion"
implementation group: 'com.googlecode.json-simple', name: 'json-simple', version: googleJsonSimpleVersion
implementation group: 'com.itextpdf', name: 'itextpdf', version: "$itextpdfVersion"
implementation "org.xhtmlrenderer:core-renderer:$xhtmlRenderVersion"
implementation "com.jcraft:jsch:$jcraftVersion"
implementation "org.grails.plugins:rendering:$grailsRenderingVersion"
implementation "org.grails.plugins:views-json"
implementation "org.grails.plugins:views-json-templates"
implementation "net.sf.json-lib:json-lib:$netsfJsonVersion"
implementation "person-og-organisation:pogo-grails-plugin:$pogoGrailsPlugin"
implementation "person-og-organisation:pogo-common:$pogoCommonsVersion"
implementation "beskedfordeler:beskedfordeler-plugin:$beskedfordelerPlugin"
implementation group: 'dokumentlager', name: 'dokumentlager-grails4-plugin', version: "$dokumentlagerPlugin"
implementation "erkerne:text-manager-plugin:$textmanagerPlugin"
implementation "erkerne:text-manager-api:$textmanagerApiVersion"
implementation "sag:sagslager-grails-plugin:$sagslagerGrailsPlugin"
implementation "sag:sag-enums:$sagEnumVersion"
implementation "sag:sagslager-api:$sagslagerApiVersion"
implementation "sag:sagslager-interface:$sagslagerInterfaceVersion"
implementation "sag:sagsindeks-grails-plugin:$sagsindeksPluginVersion"
implementation "sag:sagsindeks-object-marshallers:$sagsindeksPluginVersion"
implementation "sag:sagsindeks-api:$sagsindeksApiVersion"
implementation project(":model")
implementation project(":utils")
implementation project(":validering")
}
assets {
minifyJs = false
minifyCss = false
maxThreads = 1
}
However, I can no longer run my application, and now get this error:
> Task :integration:bootRun FAILED
Error: Could not find or load main class dk.erst.plandata.integration.Application
This was not a problem in gradle 5.2. I have tried to apply the "application" plugin, changing springBoot {} to application {} but it made no difference. I have also tried to remove mainClassName altogether, but same result.
I can see that other grails projects in my unit use gradle 6.0, but don't even specify mainClassName and it seems to work.
As was already noted in the comments, it’s hard to say what’s going wrong with this little information and especially without knowing what the applied Gradle scripts contain. So here’s just a guess: I’ve sometimes seen weird errors when upgrading the Gradle version because of outdated build/ and/or .gradle/ directories. Deleting those directories after an upgrade often does wonders.

Maven Project in IntelliJ, include Gradle Plugin

I'm new to IntelliJ and Gradle
I've got a Maven Project with a lot of dependencies which works on it's own.
Now I should use the libraries from that Project and create a Plugin for IntelliJ in Gradle.
I tried various ways to add the dependencies in the IntelliJ Module Settings, which allowed me to use the needed classes to write my code and build it. However, when I tried to start the plugin, it couldn't find the classes anymore.
I think I need to specify these in the build.gradle but I don't understand exactly how, as all the ways I tried didn't worked.
build.gradle:
plugins {
id 'java'
id 'org.jetbrains.intellij' version '0.6.5'
}
group 'com.ast.devmate.intellij'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
**compile 'com.ast.devmate.intellij:root:1.0.0-SNAPSHOT'**
}
// See https://github.com/JetBrains/gradle-intellij-plugin/
intellij {
version '2019.1'
}
patchPluginXml {
changeNotes """
Add change notes here.<br>
<em>most HTML tags may be used</em>"""
}
gets me this:
Could not find com.ast.devmate.intellij:root:1.0.0-SNAPSHOT.
without the line marked with ** I got a lot of
error: package foo does not exist
import foo;
It looks like you're trying to access a custom library using Gradle. You will probably need to use a file dependency: How to add local .jar file dependency to build.gradle file?

Gradle: disable autodownloading dependencies

I created a Gradle project in Eclipse, and the following build.gradle was created.
// Apply the java plugin to add support for Java
apply plugin: 'java'
// In this section you declare where to find the dependencies of your project
repositories {
// Use 'jcenter' for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
}
// In this section you declare the dependencies for your production and test code
dependencies {
// The production code uses the SLF4J logging API at compile time
compile 'org.slf4j:slf4j-api:1.7.18'
// Declare the dependency for your favourite test framework you want to use in your tests.
// TestNG is also supported by the Gradle Test task. Just change the
// testCompile dependency to testCompile 'org.testng:testng:6.8.1' and add
// 'test.useTestNG()' to your build script.
testCompile 'junit:junit:4.12'
}
Afterwards, the slf4j module was downloaded and cached in ~/.gradle.
But I didn't want it!! My Linux distribution contains slf4j in the repositories, so I'd rather use pacman/apt-get/etc. to install the needed module.
I'd rather Gradle errored out that the module is missing, or download the needed modules only if a flag is specified.
How can I stop Gradle from being overzealous?

How to configure a plugin to depend on a specific version of gradle?

I am writing a set of Gradle plugins, but I want to control the specific versions of groovy and gradle that are used.
I don't want the plugins to depend on whatever versions of Gradle/Groovy are installed, like the following would do:
dependencies {
compile localGroovy()
compile gradleApi()
}
Another reason I don't want to use the local method - when you use a proper dependency specification, Gradle then knows about the source code for those libs and the IDE plugins can hookup the source automatically.
Below are the relevant sections of my build script:
allprojects { Project iProject ->
apply plugin: 'idea'
apply plugin: 'maven'
repositories {
jcenter()
}
}
subprojects { Project iProject ->
apply plugin: 'groovy'
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.3.2'
}
}
project(':eclipsei2g') {
group = 'eclipsei2g'
version = '0.0.1-SNAPSHOT'
dependencies {
compile 'org.gradle:gradle-core:2.0'
}
}
project(':g2idea13') {
group = 'g2idea13'
version = '0.0.1-SNAPSHOT'
dependencies {
compile 'org.gradle:gradle-core:2.0'
compile 'org.gradle-plugins:gradle-ide:2.0'
}
}
When I run this I get an error resolving the gradle-ide dependency:
Could not resolve all dependencies for configuration ':g2idea13:compile'.
> Could not find org.gradle:gradle-ide:2.0.
Searched in the following locations:
http://jcenter.bintray.com/org/gradle/gradle-ide/2.0/gradle-ide-2.0.pom
http://jcenter.bintray.com/org/gradle/gradle-ide/2.0/gradle-ide-2.0.jar
Required by:
g2idea13:g2idea13:0.0.1-SNAPSHOT
There doesn't seem to be anything on the jcenter repository since 0.9 for the plugins stuff.
I also tried 'org.gradle:gradle-ide:2.0'.
Is this even how I should be doing this? Is there another way to specify a specific gradle version? Am I just using the wrong repository? I couldn't even get gradle-core to resolve on mavenCentral(). Is there an official Gradle repository somewhere that I should be using?
gradleApi() is the way to go. There isn't currently a public list of dependencies for Gradle plugins.

How to add buildscript dependencies in custom plugin to project dependency?

I wrote a custom gradle plugin which comes with an additional compile step. For the compilation some classes of the plugin itself are needed, since it is an annotation processor.
I try to solve it by adding the plugin as a compile dependency this way:
// in the custom plugin
project.dependencies {
compile "com.thilko.spring:gradle-springdoc-plugin:0.1.SNAPSHOT"
compile localGroovy()
}
This solution is working but introduces duplication since I have to declare the same plugin version that is already declared in the build script section of the project that uses the plugin:
// build.gradle of the project that uses the plugin
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "com.thilko.spring:gradle-springdoc-plugin:0.1"
}
}
apply plugin: 'springdoc'
Is there a way to reuse the dependencies defined in the buildscript section?
If you think it's worth it, you can declare an extra property inside the buildscript block (e.g. ext.springdocPlugin = "com.thilko.spring:gradle-springdoc-plugin:0.1.SNAPSHOT"), and then reuse it from outside (e.g. dependencies { compile buildscript.springdocPlugin }).
If you add the dependency to the pom of the your plugin, it will be added to the buildscript dependencies of the project you apply your plugin to.

Resources