How to publish and use gradle plugin with dependencies on local project? - java

I am creating gradle plugin which has dependency on my other local module. Some of its gradle build look like this:
dependencies {
compile gradleApi()
compile project(":myDependencyProject")
}
publishing {
publications {
maven(MavenPublication) {
groupId = 'org.my.gradle.plugin'
artifactId = 'some-name'
version = '1.0-SNAPSHOT'
from components.java
}
}
}
gradlePlugin {
plugins {
jsonPlugin {
id = 'org.my.gradle.plugin'
implementationClass = 'my.implementation.class'
}
}
}
When I publish my plugin using gradle publishToMavenLocal and after that I try to use that plugin in another project it fails with this error:
FAILURE: Build failed with an exception.
* What went wrong:
A problem occurred configuring project ':my-project'.
> Could not resolve all artifacts for configuration ':my-project:classpath'.
> Could not find org.my.gradle.plugin:myDependencyProject:1.0-SNAPSHOT.
Searched in the following locations: ...
In simple words it could not find dependency for myDependencyProject project. That is why as a next step I tried to create a fat jar and publish it but I have got the same error (the code for gradle plugin was same except I have changed from components java to artifact shadowJar).
Can someone help me how can I publish gradle plugin with its local dependencies and use it in another project ?
Thank you very much for any help.

We ended up using the Gradle shadow plugin to include our module in the published artifact.
One thing that was important to us though, was to only include the local library in it to prevent our end consumer from having 2 copies of some library (such as Kotlin). So we filtered the dependencies
shadowJar {
dependencies {
include(dependency(':your-module-name:'))
}
}

Related

How to build and consume gradle plugin inside a multi-module project?

The big picture
I have a library which is used as a dependency in other projects. The library has some configuration requirements related to test suites for each project depending on it.
This is why I have created a plugin that configures those for me so that I could just add the plugin and be done with it:
plugins {
id("org.my.gradle.plugin") version "internal"
}
Project structure
+ root
+ my-api/... (self-sustained; doesn't depend on anything, pretty much interfaces)
+ my-implementation/... (depends on my-api and `my-gradle-plugin` via `plugins { id("org.my.plugin") }`)
+ my-gradle-plugin/... (the plugin itself)
+ build.gradle.kts
plugins {
`java-gradle-plugin`
`maven-publish`
}
gradlePlugin {
plugins {
create("org.my.gradle.plugin") {
id = "org.my.gradle.plugin"
group = "org.my.gradle.plugin"
implementationClass = "org.my.gradle.plugin.MyGradlePlugin"
version = project.version
}
}
}
+ build.gradle.kts // a bunch of shared task configurations and some repository configuration (mavenLocal, maven(xyz), mavenCentral())
+ gradle.properties - contains only "version=0.0.3-SNAPSHOT"
+ settings.gradle.kts
pluginManagement {
repositories {
mavenLocal()
maven { url = uri("https://xyz") }
gradlePluginPortal()
mavenCentral()
}
resolutionStrategy {
val version: String by settings
eachPlugin {
if (requested.id.id == "org.my.gradle.plugin") {
useVersion(version)
}
}
}
}
The problem
The plugin works fine if it's a separate stand alone project. This, unfortunately, complicates my workflow so I thought I could possibly have it within the same multi-module project.
Unfortunately I am running into problems, because gradle doesn't seem to know it needs to build the plugin in order to use it inside one of the modules and therefore I get:
* Where:
Build file '/workspace/my-implementation/build.gradle.kts' line: 3
* What went wrong:
Plugin [id: 'org.my.gradle.plugin', version: '0.0.3-SNAPSHOT'] was not found in any of the following sources:
- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- Plugin Repositories (could not resolve plugin artifact 'org.my.gradle.plugin:org.my.gradle.plugin.gradle.plugin:0.0.3-SNAPSHOT')
Searched in the following repositories:
MavenLocal(file:/home/jenkins/.m2/repository/)
maven(https://xyz)
Gradle Central Plugin Repository
MavenRepo
Why does it fail?
I know that spring-boot-gralde-plugin is part of the spring boot multi-module gradle project and is consumed within the project itself. Unfortunately I haven't been able to figure out what's the "magic trick" to make it work.
Any ideas what I'm missing here?
Well, this took me the better half of the day, but I finally figured it out.
In order to consume the plugin inside the same repository, you must place a settings.gradle.kts file inside your plugin. This separates the plugin build from the rest of your modules. Then you can use includeBuild() inside the pluginManagement to enforce the building of the plugin before everything else:
// ./root/settings.kotlin.kts
rootProject.name = "root-project"
include("my-api", "my-implementation")
pluginManagement {
includeBuild("my-gradle-plugin")
repositories {
mavenLocal()
maven { url = uri("https://xyz") }
gradlePluginPortal()
mavenCentral()
}
resolutionStrategy {
val version: String by settings
eachPlugin {
if (requested.id.id == "org.my.gradle.plugin") {
useVersion(version)
}
}
}
}
Then you can just use the plugin without any issues:
plugins {
id("org.my.gradle.plugin") version "internal"
}
I'm using gradle 7.5+ so not sure if this works for older versions.
The docs also mention this here:
https://docs.gradle.org/7.6/userguide/composite_builds.html#included_plugin_builds

Gradle to add module dependency in Micronaut project

I have three module as shown below
The fete-bird-apigateway depend on common and fete-bird-product depend on both fete-bird-apigateway and common
In the fete-bird-product settings.gradle I have included the code below
rootProject.name = "fete-bird-product"
include 'fete-bird-apigateway' , 'common'
and in the build.gradle of project
dependencies {
implementation project(':common')
}
Error
Caused by: org.gradle.internal.component.NoMatchingConfigurationSelectionException: No matching configuration of project :common was found.
I don't want to create a multi-module build project describe here https://docs.gradle.org/current/userguide/multi_project_builds.html. Each project should build individually and dependent modules should load while building.
How can I achieve this?
Well I found that I had the wrong concept for different module projects.
Assuming all modules are part of the same multi-module build then in fete-bird-apigateway.gradle and service\build.gradle you add:
plugins {
id 'java'
id 'maven-publish'
}
dependencies {
implementation project(':common')
}
However if common, fete-bird-apigateway and service are separate projects and don't share the same root build.gradle you have to publish the common module into a shared repository and use it like any regular dependency. Easiest to do with Maven Local repository.
To publish to the local maven
In fete-bird-apigateway.gradle
publishing {
publications {
maven(MavenPublication) {
groupId = 'org.gradle.sample'
artifactId = 'library'
version = '1.1'
from components.java
}
}
}
Reference - https://docs.gradle.org/current/userguide/declaring_repositories.html
https://docs.gradle.org/current/userguide/publishing_maven.html#gsc.tab=0
In the dependent project add the dependency as regular
repositories {
mavenLocal()
}
implementation("fete.bird:fete-bird-apigateway:0.1")
We need to run the task or gradle command for publish. I am using Intellj so did with below task
We can run the gradle command gradle publishToMavenLocal

How to prepare a plugin dependency tree in Gradle 5.x? [duplicate]

One can run gradlew dependencies to learn about dependencies of module tasks. It there a way to find transitive dependencies of buildscript dependencies?
Example:
classpath 'com.android.tools.build:gradle:1.0.0' depends directly on:
com.android.tools.build builder
com.android.tools.lint lint
net.sf.proguard proguard-gradle
tools.base project-test-lib
As can be seen on MVNRepository. But this artifacts have their own dependencies. Is there and way to find those out without manually traversing whole dependency tree?
As a clarification, the classpath I'm talking about is defined by:
buildscript {
repositories {}
dependencies { .... }
}
Beginning with Gradle 2.10 you can now get information on buildscript dependencies via
gradle buildEnvironment
With older versions you'll have to explicitly define a task of type DependencyReportTask configured with your build script configuration.
task buildscriptDependencies(type: DependencyReportTask) {
configurations = [buildscript.configurations.classpath]
}
I think you're looking for Gradle's DependencyInsightReportTask
You can use this command:
gradle dependencyInsight --dependency gradle
There is awesome tutorial by Udacity, Gradle for Android, but you can watch this video for more explanation.

Publish Android library with external dependencies

I have an Android closed source module that will be be used as a library in other projects. It contains external dependencies.
To publish it, I'm creating a Maven artifact with the following gradle task:
apply plugin: 'maven'
def coreAarFile = file('...build\\outputs\\aar\\android-sdk-release.aar')
artifacts {
archives coreAarFile
}
uploadArchives {
repositories.mavenDeployer {
repository(url: "file://.\\mvn-repo")
pom.project {
groupId 'a.blabla'
artifactId 'blabla-sdk'
version "1.0.0"
}
}
}
It generates the .aar file, the pom.xml, etc without problems.
Then I create a project that have a dependeny to my library declared. It works until it needs to access to the external dependencies, when throws a class not found exception.
How can I edit my gradle task to include external dependencies or at least a reference to them? They are published in mvnrepository.com and github.com.
I moved uploadArchives to the build.gradle of the module and removed the artifacts element. It works!
Thanks to CommonsWare for pointing to the right direction.

Gradle: gradle install with javadocs

I'm making use of the Gradle maven plugin to build an artefact that is to be used for another unrelated project. Along with the built .jar artefact, I would also like to generate and install the -javadoc.jar artefact along side it.
Using gradle clean build javadoc install generates the JavaDoc in the local build file, and install the built artefact to the local repository, but it currently does not build and install -javadoc.jar along side it.
Is there a way to do this in Gradle using the maven or javadoc plugin? I don't mind writing a custom task to do it, but I rather use the "officially supported" way if one exists.
The build.gradle file:
project.group = "org.example.artefact"
project.version = "1.0-SNAPSHOT"
apply plugin: 'java'
apply plugin: 'maven'
dependencies {
// ...
}
uploadArchives {
repositories {
mavenDeployer {
// Custom repository location
repository(url: "file:///home/user/.m3/repository")
}
}
}
Javadocs are produced by the javadoc task (I think you are mistakenly referring to it as a plugin). This task isn't actually executed by default when running build or install. Additionally you'll want to define a jar task to bundle the javadocs and tell your build to publish that artifact by adding it to the artifacts {...} block.
task javadocJar(type: Jar) {
classifier = 'javadoc'
from javadoc
}
artifacts {
archives javadocJar
}
Running install should then both create the javadoc jar and publish it to maven local. Additionally, running uploadArchives would then publish that artifact to any configured repositories.
Edit: Updated to add definition of javadoc jar task.

Categories

Resources