Gradle :: runtime.exclude group: 'org.apache.hadoop' affects test scope? - gradle

I have the following in my build.gradle:
configurations {
runtime.exclude group: 'org.apache.spark'
runtime.exclude group: 'org.apache.hadoop'
}
and for some reason this also excludes all Hadoop/Spark code from the test classpath. If I comment out this configuration - the tests are passing fine, otherwise I get all sorts of java.lang.NoClassDefFoundError: org/apache/hadoop/hdfs/MiniDFSCluster$Builder issues.
I tried to use this:
test {
classpath += configurations.compile
}
No luck.
What am I missing here?

In gradle scoping, test inherits from runtime. Your test code is excluding the minicluster dependency because runtime excludes it.
See this diagram for the scope inheritance tree for the java plugin:
Instead of adding a global exclude to the runtime configuration, you might want to make the spark dependencies into compileOnly scoped dependencies which is available since gradle 2.12.
configurations {
compileOnly 'org.apache.spark:spark:2.11'
test 'org.apache.hadoop:hadoop-minicluster:2.7.2'
}
More information about gradle scoping is available in the gradle manual:
Alternatively, you could add another configuration that inherits from runtime, and add exclusions to that, then use that as the basis of your shadowJar. This could be helpful if you want to optionally build a jar with spark dependencies bundled in or not. Your tests will use the configuration without exclusions, but the jar you package won't include the spark dependencies.
configurations {
sparkConfiguration {
extendsFrom runtime
exclude group: 'org.apache.hadoop'
exclude group: 'org.apache.spark'
}
}
task sparkExcludedJar(type: ShadowJar) {
group = "Shadow"
configurations = [project.configurations.sparkConfiguration]
classifier = 'sparkExcluded'
}

Related

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?

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.

Why dont I always see `buildscript` in gradle files? [duplicate]

I am new to Gradle and I am reading the documentation but I don't understand some parts of it. One of these parts is connected with buildscript block. What is its purpose?
If your build script needs to use external libraries, you can add them to the script's classpath in the build script itself. You do this using the buildscript() method, passing in a closure which declares the build script classpath.
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath group: 'commons-codec', name: 'commons-codec', version: '1.2'
}
}
Ok but what is the difference with:
repositories {
mavenCentral()
}
dependencies {
compile group: 'commons-codec', name: 'commons-codec', version: '1.2'
}
For example, why it is necessary to use buildscript?
The buildScript block determines which plugins, task classes, and other classes are available for use in the rest of the build script. Without a buildScript block, you can use everything that ships with Gradle out-of-the-box. If you additionally want to use third-party plugins, task classes, or other classes (in the build script!), you have to specify the corresponding dependencies in the buildScript block.
The global level dependencies and repositories sections list dependencies that required for building your source and running your source etc.
The buildscript is for the build.gradle file itself. So, this would contain dependencies for say creating RPMs, Dockerfile, and any other dependencies for running the tasks in all the dependent build.gradle
I appreciate Peter's answer... but it was not immediately obvious to me what the rest of the build script meant as emphasized in the answer and in the documentation.
Usually bringing in dependent functionality is for use in the Java program or whatever other program you might be writing. Bringing in Spring say, is not to be used in the build script, but in the Java program. Putting it in the buildscript closure ensures that the dependencies are available for use within the gradle build itself. Not the output program.
A bit more explanation by demonstrating Android top-level gradle file.
buildscript {
// this is where we are going to find the libraries defined in "dependencies block" at below
repositories {
google()
jcenter()
maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' }
}
// everything listed in the dependencies is actually a plugin, which we'll do "apply plugin" in our module level gradle file.
dependencies {
classpath 'com.android.tools.build:gradle:3.4.2' // this is android gradle plugin
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // kotlin gradle plugin
}
}
module level gradle file
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
What is "plugin"? They are just java classes, which implement Plugin interface. Under the interface, it has a method "apply" to add multiple task objects with different names. Task is a class where we can implement the workflow. For instance, the build task consists of the flow of building the app.
So, what does buildscript do? It defines where to find the plugins. What does plugin do? It encompasses multiple tasks. What does task do? It provides us with the build, install, lint, etc.
My understanding might be wrong. Please don't hesitate to correct me if you find anything is misleading.
The "buildscript" configuration section is for gradle itself (i.e. changes to how gradle is able to perform the build). So this section will usually include the Android Gradle plugin.
It's a bit high level but hope helps.
For me, clear distinction started to shape once I start to understand what is a building block, method, and task. How the syntax looks like, how you can configure them etc. So I suggest you go through all these. After that, you can begin to make sense out of this syntax.
Then it's very important to know what's the type of the object build.gradle (an instance of Project class) so to know what can you have inside a build.gradle file. That would answer where that 'buildScript' and others come from. And to extend your capabilities/features (let's say android), see how plugins can help.
Last but not least, there's a very good tutorial here that talks about closures, delegates which are the concepts essential to understand the script.
buildscript block is used for the build script, NOT for the gradle build output (for example, an Android app apk). In the following code example, the encoding code is used in build script, not in the gradle build output program; so the dependecies should be added to buildscript block.
https://docs.gradle.org/current/userguide/tutorial_using_tasks.html#sec:build_script_external_dependencies
External dependencies for the build script
Instead of manipulating the
script classpath directly, it is recommended to apply plugins that
come with their own classpath. For custom build logic, the
recommendation is to use a custom plugin. If your build script needs
to use external libraries, you can add them to the script’s classpath
in the build script itself. You do this using the buildscript()
method, passing in a block which declares the build script classpath.
The block passed to the buildscript() method configures a ScriptHandler instance.
You declare the build script classpath by adding dependencies to the
classpath configuration. This is the same way you declare, for
example, the Java compilation classpath. You can use any of the
dependency types except project dependencies.
Having declared the build script classpath, you can use the classes in
your build script as you would any other classes on the classpath. The
following example adds to the previous example, and uses classes from
the build script classpath.
import org.apache.commons.codec.binary.Base64
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath group: 'commons-codec', name: 'commons-codec', version: '1.2'
}
}
tasks.register('encode') {
doLast {
def byte[] encodedString = new Base64().encode('hello world\n'.getBytes())
println new String(encodedString)
}
}
You can imagine the buildScript block as contents from the Gradle core, like plugins{} block that already goes into Gradle internally.
So all plugins from buildScript of parent build.gradle will be available in all nested build.gradle modules.
I believe that everything in the buildscript {} will be available for the current build script itself and then the all its subprojects.
And for the properties declared in the file itself outside of the buildscript {} it will not become immediately available to for buildscript of the given project itself, but to all its subprojects.
So if you want to declare something and use it for the buildscript itself right away (current buildscript and not just subproject's buildscript), declare them in the buildscript {} for the current project and it also has the side effect to let subproject use it later on.
If you just want to declare something globally (for sub-projects's buildscripts) you can declare them directly as ext {} in parent project. The parent project won't be able to use them for itself's buildscript but it will be available all the subproject to use, in or out of the buildscript clause.
For example in parent project:
ext {
kotlin_version_XX = '1.7.10'
}
buildscript {
ext {
kotlin_version = '1.7.10'
}
// kotlin_version will be available here since declared in buildscript{}
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// will NOT be available here -- error due to kotlin_version_XX declared in project
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version_XX"
}
And if you have a subproject:
dependencies {
// both kotlin_version and kotlin_version_XX can be used here, since it was declared in parent project
implementation "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version_XX"
}
buildscript {
// both kotlin_version and kotlin_version_XX can even be used here for subproject's script's use, since it was already declared in parent project
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version_XX"
}

Difference between depends and dependencies in gradle

What's the difference between depends keyword and dependencies keywords in a gradle build file? I encountered these keywords in the following contexts:
depends:
project(':tools:bnd-module-plugin') {
description = "bnd plugin to build moduleinfo with ${rootProject.description}"
sourceSets.main.java.srcDirs += project(':asm').sourceSets.main.java.srcDirs
depends = ['biz.aQute.bnd:biz.aQute.bnd:3.4.0']
}
dependencies:
subprojects {
apply plugin: 'com.github.sherter.google-java-format'
googleJavaFormat.toolVersion = '1.4'
compileTestJava {
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
}
dependencies {
requires.each { projectName -> compile project(projectName) }
depends.each { artifactName -> compile artifactName }
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.1.0',
'org.junit.jupiter:junit-jupiter-params:5.1.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.1.0'
testCompile project(':asm-test')
}
}
The dependencies keyword is provided by a method of the Project instance, which the build.gradle file is evaluated against. It allows the configuration of multiple types of dependencies via a DependencyHandler. You can add file dependencies, project dependencies and module dependencies, which can be resolved from Maven and Ivy repositories.
Since it is provided by the Project instance directly, it is available in every Gradle project.
The depends keyword does not exist in the Gradle API. However, Gradle provides a lot of possibilities to extend and program your build scripts. Via so-called extra properties it is possible to define additional properties in the scope of Gradle objects, like tasks and projects. Then these additional properties can be used like regular Gradle properties as in your example.
I found the full build script from your examples online. In the beginning of the script a subprojects closure is used to define extra properties for all subprojects:
subprojects {
[...]
ext.provides = [] // The provided java packages, e.g. ['org.objectweb.asm']
ext.requires = [] // The required Gradle projects, e.g. [':asm-test']
ext.depends = [] // The external dependencies, e.g. ['junit:junit:4.12']
[...]
}
provides, required and depends are Groovy lists, which are then later used to store strings.
Your first code example sets a new list to the depends extra property of the :tools:bnd-module-plugin subproject.
Your second uses these lists to add module (depends) or project (requires) dependencies to all subprojects.
As you can see, depends is just part of a custom Gradle script and not part of the official Gradle API, unlike dependencies.

How to refer or link the Java src with test structure in Gradle

I'm new to gradle currently I'm facing a problem while compiling test classes I'm referring the Java Classes in Test Classes to test program but I couldn't compile. Problem I wouldn't understand to how to link or refer Java src structure with test structure. Could somebody help me how to resolve the issues.
Below I provided the screenshot of Src and Test package structure and compilation problem.
Java Src and Test structure
Compilation Error
build.properties
apply plugin: 'java'
sourceCompatibility = '1.7'
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
// NetBeans will automatically add "run" and "debug" tasks relying on the
// "mainClass" property. You may however define the property prior executing
// tasks by passing a "-PmainClass=<QUALIFIED_CLASS_NAME>" argument.
//
// Note however, that you may define your own "run" and "debug" task if you
// prefer. In this case NetBeans will not add these tasks but you may rely on
// your own implementation.
if (!hasProperty('mainClass')) {
ext.mainClass = ''
}
jar {
manifest {
attributes 'Main-Class': 'com.gradle.shopcart.ShopCartApp'
}
}
repositories {
mavenCentral()
// You may define additional repositories, or even remove "mavenCentral()".
// Read more about repositories here:
// http://www.gradle.org/docs/current/userguide/dependency_management.html#sec:repositories
}
dependencies {
// TODO: Add dependencies here ...
// You can read more about how to add dependency here:
// http://www.gradle.org/docs/current/userguide/dependency_management.html#sec:how_to_declare_your_dependencies
testCompile group: 'junit', name: 'junit', version: '4.12'
}
EDIT::
I'm using netbeans, with help of gradle plugin i created this project structure below you can find the screenshot. If I miss anything please correct me.
Please let me know in case of more information.

Resources