Unable to resolve class HTTPBuilder inside gradler task - gradle

Why do some imports work for my regular groovy files inside the project
compile group: 'org.codehaus.groovy.modules.http-builder', name:
'http-builder', version: '0.7.1'
import groovyx.net.http.HTTPBuilder
import static groovyx.net.http.ContentType.*
import static groovyx.net.http.Method.*
When I try to use HTTPBuilder inside build.gradle is unable to resolve the class.
Am I missing a step for make them work inside a gradler task?

You need to make the http-builder module classes available to the build script classpath, using the dedicated script block buildscript:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath ("org.codehaus.groovy.modules.http-builder:http-builder:0.7.1")
}
}
See:
https://docs.gradle.org/current/userguide/tutorial_using_tasks.html#sec:build_script_external_dependencies
https://docs.gradle.org/current/dsl/org.gradle.api.Project.html#org.gradle.api.Project:buildscript(groovy.lang.Closure)

Related

build.gradle buildscript dependencies vs. dependencies?

Can someone explain to me how depedencies listed in the "buildscript" in the build.gradle file are different than regular dependencies listed in the dependencies block { } ? and why they have to be listed with the syntax "implementation"? I've googled this and responses say the dependencies in the buildscript and used to "build the project" but I don't understand this? can anyone give a more clear picture and answer?
buildscript:
buildscript
{
repositories
{
maven {
url 'myMavenFeed'
credentials {
username "myUsername"
password myPassword
}
}
mavenCentral()
jcenter()
}
dependencies
{
classpath "com.microsoft.azure.sdk.iot:iot-device-client:1.14.1"
}
}
Dependencies block:
dependencies
{
compile group: 'com.microsoft.azure.sdk.iot', name: 'iot-device-client', version: '1.16.0'
}
Can someone explain to me how depedencies listed in the "buildscript" in the build.gradle file are different than regular dependencies listed in the dependencies block { } ?
Dependencies defined in the buildscript { } block are dependencies to use to build your project. These dependencies are available to use in your Gradle build file (build.gradle or build.gradle.kts)
Dependencies defined in the dependencies { } are for your application code.
So for your samples in your questions, does it make sense for Gradle (the build system) to have iot-device-client on its classpath? Why does a build system need iot-device-client on its classpath to build your project? It doesn't make sense therefore it should be removed.
Now let's say you are developing an application the requires some functionality or class from iot-device-client. You need a way to add this library to your application's code/classpath. You when then declare it as a dependency as you have done above:
dependencies {
implementation("com.microsoft.azure.sdk.iot:iot-device-client:1.16.0")
}
References:
External dependencies for the build script
Declaring depenedncies
and why they have to be listed with the syntax "implementation"?
implementation is known as a configuration: A Configuration represents a group of artifacts and their dependencies
There are many more configurations depending on the plugins you apply to your project. For example, if you apply the Java plugin:
plugins {
id("java")
}
The following configurations are available to use:
implementation
compileOnly
compileClasspath
...and many more
Each one has their own meaning/usage and I strongly suggest reading about them here.

Construction call to super fails for Groovy object inheriting 3rd-Party Java object

The Situation
I have a Groovy subclass of a Java class. The Java class is from a dependency, not my own local package:
// A basic idea of the Java class' construction
public class JavaArea<PS, S> {
public JavaArea(PS initialStyle, BiConsumer, S otheStyle, Biconsumer) {
// constructs class...
}
}
class GroovyArea extends JavaArea<Collection<String>, Collection<String>> {
GroovyArea(Object unrelated arguments) {
super(Collections.emptyList(), defaultBiConsumer, otherStyle, defaultBiConsumer)
// do some other stuff to GroovyArea's fields
}
}
For some reason, the compilation of the class fails with:Constructor call must be the first statement in a constructor despite the constructor call being the first statement...
Exception executing
org.gradle.api.internal.tasks.compile.ApiGroovyCompiler#7a1c5b43
in compiler daemon:
org.gradle.api.internal.tasks.compile.CompilationFailedException:
Compilation failed; see the compiler error output for details..
super(Collections.emptyList(), otherParams)
^
The Gradle Build files
I have the following build file for the root project:
subprojects {
apply plugin: 'groovy'
repositories {
mavenCentral()
}
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.4.6'
testCompile "org.spockframework:spock-core:1.0-groovy-2.4"
testRuntime "cglib:cglib-nodep:3.2.3"
testRuntime "org.objenesis:objenesis:2.4"
}
}
... and the following build file for the actual module containing the error:
version '1.0-SNAPSHOT'
apply plugin: 'groovy'
repositories {
maven {
url 'https://oss.sonatype.org/content/repositories/snapshots/'
}
}
dependencies {
compile 'org.codehaus.groovyfx:groovyfx:0.4.0'
compile project(':diagrammer')
compile group: 'org.reactfx', name: 'reactfx', version: '2.0-M5'
compile group: 'org.fxmisc.wellbehaved', name: 'wellbehavedfx', version: '0.3'
compile (group: 'org.fxmisc.richtext', name: 'richtextfx', version: '1.0.0-SNAPSHOT') {
exclude group:'org.reactfx', module: 'reactfx'
}
}
My Question
What's causing the problem and how do I fix it? Is this a bug with Groovy? Or an issue with my build environment?
IDE: IntelliJ 2016.1.3
I don't think it's the IDE because it performs syntax highlighting correctly and provides the correct documentation when I hover over the 'super' keyword
Gradle: Gradle 2.12
Groovy: Groovy 2.4.6
What I have tried
I've tried changing the versions of Gradle (via sdkman) and then Groovy (via build file). None of these have fixed the problem:
Gradle: 2.12, 2.14
using Groovy: 2.4.5, 2.4.6, 2.4.7
Updates
Creating a new Gradle project in IntelliJ that only has the necessary components to rebuild the GroovyArea class will fail with the same exception when I run gradle build.
Looks to be a bug in Groovy. Filed as GROOVY-7868

call java function in gradle script

I have a java class which does some kind of functionality, one of these function returns something that I need to use it into gradle script to set the project properties.
I had achieved it by creating an artifact of project and used that artifact by adding it into classpath, that gave me accessibility of that class and function.
buildscript {
repositories {
jcenter()
maven{
url 'http:localhost:8081/artifactory/temp'
}
}
dependencies {
classpath "utility:sampleutility:1.0"
}
}
import com.polsys.utility.MyUtil
dependencies {
compile 'org.slf4j:slf4j-api:1.7.13'
compile 'HRP:'+new MyUtil().callMe()+':1.0'
//callme function returns the name of artifact.
testCompile 'junit:junit:4.12'
}
Now, I had achieved it by the way as mentioned above that is by creating artifact, add that artifact into classpath, then import classes and use function. Is this any way by which I can call functions of current project? so I can merge that functionality which is available in the artifact into current project.
Simple way is to put your Java/Groovy code under buildSrc dir. Gradle will compile it and you'll be able to call this code from your buildscript. Check https://docs.gradle.org/current/userguide/custom_plugins.html and related docs.
To make your java code available to gradle script you need to have your java code under the directory hierarchy given below:
ProjectRootDirectory
buildSrc
src
main
groovy/java
YourPackages(in my case java packages and classes)
This is the path where gradle script looking for external plugins. Now you can import and access classes into gradle script(you will not end up with "unable to resolve class" error).

specify classpath for plugin inside apply method

How to specify classpath for custom gradle plugin inside class, that implements interface Plugin?
class TaskPlugin implements Plugin<Project> {
void apply(Project project) {
project.task('task') << {
println 'simple task'
}
}
}
I saw something similar there
https://github.com/gradle/gradle/blob/6277a4dc70fbeea83c111e75c95ba851d1e56ffc/subprojects/plugins/src/main/groovy/org/gradle/api/plugins/WarPlugin.java#L25
However I don't know how to apply it for my case. Specifically I want to use both test and main sourcesets.
I want to get rid of classpath dependencies, related to my project. Because I have the same dependencies in dependencies and in buildscript { dependencies {
Every time I add plugin I have to add classpath dependencies, which that plugin is using.
apply plugin: 'my-plugin'
task {
... do something
}
buildscript {
repositories {
flatDirs dir('.')
}
dependencies {
classpath ("my-group:my-plugin:my-version")
classpath ("dependency:dependency:dependency")
}
}
The problem is that when I specify basic dependencies (not inside buildscript) I may have the same dependencies
dependencies {
compile ("dependency:dependency:dependency")
}
Sometimes I need some compiled project dependencies compile project(":my-project") which I have to specify using classpath files("path to compiled").
How to adjust plugin implementation to remove those dependency duplicates? Like for example if I declared dependency using compile or runtime - plugin will know about it and there is no need to declare dependency in classpath explicitly.

Creating a Gradle plugin with a dependency on another (external) plugin

I want to create a plugin that automatically applies other (external plugins). This requires setting the buildscript dependency for the plugin before I call "apply plugin". However it seems like I can't add buildscript dependencies in a plugin or I get:
You can't change a configuration which is not in unresolved state!
Is there a solution to this ?
My sample (non-working) code:
import org.gradle.api.Project
import org.gradle.api.Plugin
class SamplePlugin implements Plugin<Project>{
void apply(Project project) {
project.buildscript.dependencies.add("classpath","net.sourceforge.cobertura:cobertura:1.9.4.1");
project.configure(project){
apply plugin: 'cobertura'
}
}
}
The way to go about this is to publish a pom.xml or ivy.xml along with the plugin Jar that describes the plugin's dependencies. Alternatively, you can write a script plugin that declares its dependencies in a buildscript {} section. A script plugin is simply a reusable build script that gets applied with apply from: ....

Resources