How to exclude particular class from a jar in gradle - gradle

I want to exclude particular class from a jar in gradle dependency
dependencies {
compile("com.example:myapp") {
exclude("org/springframework/**")
}
}
Any suggestions? I am stuck with the dirty class.

You can unzip a jar using the Copy task, exclude the desired class and then add a file dependency on the extracted classes.
For example:
task unzipJar(type: Copy) {
from zipTree('commons-collections-3.2.jar')
into ("$buildDir/libs/commons-collection")
include "**/*.class"
exclude "**/Unmodifiable.class"
}
dependencies {
compile files("$buildDir/libs/commons-collection") {
builtBy "unzipJar"
}
}

Related

How to pass #Input String in a task in buildSrc

This custom plugin exists in gradle's buildSrc/:
abstract class MyTask : DefaultTask() {
#get:Input
abstract val buildDir: Property<String>
#TaskAction
fun someTask() {
// do stuff
}
}
class DevelopmentPlugin : Plugin<Project> {
override fun apply(project: Project) {
project.tasks.run {
register("myTask", MyTask::class.java) {
inputs.property("buildDir", project.buildDir)
println(inputs.getProperties())
}
}
}
}
and by running the task with e.g. $ ./gradlew myTask fails with:
Could not determine the dependencies of task ':myTask'.
> Cannot query the value of task ':myTask' property 'rootDir' because it has no value available.
Also the prinln outputs {buildDir=null} meaning that the inputs.property("buildDir", project.buildDir) has failed.
How to pass the project.buildDir value from the Plugin in the task?
Using project.buildDir directly from inside the task is not an acceptable answer due to Gradle's incubating build-cache functionality.
Firstly, there is a class type issue which is not visible in Gradle.
buildDir is of type File while the property is String.
So "${project.buildDir}" should be used.
Secondly, since the property is abstract val it can directly be accessed in the closure. Therefore it can be set with:
// instead of:
inputs.property("buildDir", "${project.buildDir}")
// just this:
buildDir.set("${project.buildDir}")

Gradle: how to pass classes defined in script to JavaExec?

Gradle: how to pass classes defined in script to JavaExec? e.g.,
build.gradle
public class Foo {
...
}
javaexec {
classpath ...
main example.Executor
args "fooClass", "Foo"
}
The class example.Executor needs to load the class Foo.class defined in build.gradle script. Is this possible?
How to add build script in the javaexec classpath?

How to add dependency to configuration in gradle plugin

I'm developing Gradle custom plugin. I want to add dependency to the existing configuration. I'm trying to do it like this:
open class MyApplicationExtension #Inject constructor(objects: ObjectFactory) {
val version: Property<String> = objects.property(String::class)
}
class MyApplicationPlugin : Plugin<Project> {
override fun apply(project: Project) {
project.plugins.apply(ApplicationPlugin::class)
val extension = project.extensions.create<MyApplicationExtension>("myApp")
val implConfig = project.configurations["implementation"]
implConfig.defaultDependencies {
add(project.dependencies.create("com:my-app:${extension.version.get()}"))
}
}
}
But when I try to use application in gradle project the added dependency is not added. I'm trying to use it like this:
apply<MyApplicationPlugin>()
the<MyApplicationExtension>().version.set("0.1.0")
dependencies {
// This overrides the default dependencies
implementation("com:another:0.2.0")
}
And when I invoke dependencies task my dependency is not shown there. So how to add configurable dependency to the implementation configuration from custom plugin? Running with Gradle 5.3.1 in Kotlin DSL.
Default dependencies are only used if no other dependency is added to the configuration.
Since that does not seem to be your use case, you should simply add the dependency in a normal fashion.
implConfig.defaultDependencies {
add(project.dependencies.create("com:my-app:${extension.version.get()}"))
}
needs to become
implConfig.dependencies.add(project.dependencies.create("com:my-app:${extension.version.get()}"))

How to set the main class classpath for JavaExec task in Gradle?

I got that if I want to run a main from a Main class, by using the sourceSets.main.runtimeClasspath classpath, I have to put the Main class inside of src/main/java and use something like:
apply plugin: 'java'
dependencies {
}
task myTask (type: JavaExec){
dependsOn classes
classpath sourceSets.main.runtimeClasspath
main = 'Main'
}
What I want is understand how I can specify a different classpath from which to retrieve the class containing the main().
What if I want to run the main from a class which is not in src/main/java but it is in the same folder as the build.gradle?
I'm aware that it has no sense to do something like that, but I wish to find a solution as an exercise to learn Gradle.
As you still need to compile such class and in the case the class is not in the standard src/main/java directory, you will need to define additional SourceSet to that path and use the same approach as you described:
sourceSets {
main {
custom {
srcDirs = ['custom/path']
}
}
}
task myTask (type: JavaExec){
dependsOn classes
classpath sourceSets.custom.runtimeClasspath
main = 'Main'
}

Access property from settings.gradle in Gradle plugin

I am in the process of building a custom Gradle plugin using the following guide. I want to define a property in the settings.gradle file and read it in the plugin class, but every attempt failed so far.
Here is the error I am getting:
Could not find property 'MyProperty' on root Project 'MyProject'
Here is my settings.gradle file:
gradle.ext.MyProperty = "The Value"
and here is the file containing my plugin:
package myplugin.gradle
import org.gradle.api.Project
import org.gradle.api.Plugin
class FirstPlugin implements Plugin<Project> {
void apply(Project project) {
project.task('myTask') << {
def instance = project.MyProperty
println "VALUE : " + instance
}
}
}
I can access MyProperty if I put project.ext.set("MyProperty", "Property Value") in build.gradle, but I can't find a way to set it in the settings.gradle file.
I guess one way to fix this issue would be to read the content of settings.gradle in build.gradle and send it to the plugin using project.ext.set(...), but is there a more direct way?
Apparently, the way to go (which is better anyways) is to use an extension object. This extension object allows to send data from the build.gradle file to the plugin. The build.gradle file reads the content of the variable in the settings.gradle file and puts it in the extension object.
In the file containing the plugin:
package myplugin.gradle
import org.gradle.api.Project
import org.gradle.api.Plugin
class MyExtension {
String myProperty
}
class FirstPlugin implements Plugin<Project> {
void apply(Project project) {
project.extensions.create('myExtensionName', MyExtension)
project.task('myTask') << {
def instance = project.myExtensionName.myProperty
println "VALUE : " + instance
}
}
}
In the build.gradle file:
apply plugin: 'myPluginName'
...
myExtensionName {
myProperty = gradle.ext.myPropertyInSettings
}
And finally, in the settings.gradle file :
gradle.ext.myPropertyInSettings = "The Value"
Also, I recommend this tutorial instead of the one provided by Gradle.
I have a gradle project where a property set in settings.gradle is accessed from 3 places:
settings.gradle itself
build.gradle (including subprojects {} )
a gradle plugin in ./buildSrc
Accessing from settings.gradle and build.gradle:
gradle.ext.MY_PROPERTY_NAME
Accessing from a gradle plugin's apply() method:
(plugin is applied from subprojects {} closure)
project.rootProject.gradle.ext.MY_PROPERTY_NAME
This seems to work fine in Gradle 4.7 and Gradle 5.2

Resources