I'm trying to get a simple non-Android Java project working with Dagger2 in IntelliJ (2016.3.3, not AndroidStudio) and Gradle (3.1), but nothing seems to get generated at all, I get no DaggerXXX classes output. Not sure if it's the Dagger annotation processing that doesn't work, the source set configuration in IntelliJ that's wrong, or something else. When building the project I get the following output:
build
|_classes
|_main
|_com
| |_<test classes correctly built>
|_generated
|_<empty, but should contain generated Dagger classes?>
What I've done is:
Configured the project to use annotation processing in the IntelliJ settings.
Used the following config:
buildscript {
repositories {
mavenCentral()
jcenter()
maven {
url("https://plugins.gradle.org/m2/")
}
}
dependencies {
classpath "net.ltgt.gradle:gradle-apt-plugin:0.9"
}
}
apply plugin: 'net.ltgt.apt'
apply plugin: 'java'
apply plugin: 'idea'
repositories {
mavenCentral()
}
dependencies {
compile 'com.google.dagger:dagger:2.8'
apt 'com.google.dagger:dagger-compiler:2.8'
}
sourceSets {
main {
java {
srcDirs 'src/main/java'
}
}
}
Test program:
public class Test {
#Inject
TestPojo testPojo;
public static void main(String[] args){
<no generated Dagger component available for building>
}
}
#Component(modules = Module.class)
public interface Component {
Pojo get();
}
#Module
public class Module {
#Provides
public Pojo get(){
return new Pojo();
}
}
public class Pojo {}
Update:
It's working if I build the project through the command line and not through the IntelliJ gui. That points to the issue being within the IntelliJ environment or its Gradle integration somehow, rather than in the build script itself.
Related
In a regular build script you can easily use extensions on Project like Project.sourceSets, for example build.gradle.kts:
sourceSets {
main {
...
}
}
But when I am developing a Gradle plugin in my buildSrc module, I cannot access these. For example:
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.*
class ExamplePlugin : Plugin<Project> {
override fun apply(target: Project) {
target.sourceSets { // error because `sourceSets` can't be resolved.
}
}
}
This is happening despite including the kotlin-gradle-plugin module in my buildSrc dependencies:
plugins {
`kotlin-dsl`
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31")
}
So, how can I access these extensions from within my Gradle plugin?
class ExamplePlugin : Plugin<Project> {
override fun apply(target: Project) {
target.configure<JavaPluginExtension> {
sourceSets {
println(names)
}
}
}
}
See additional notes here: https://docs.gradle.org/current/userguide/kotlin_dsl.html#project_extensions_and_conventions
Basically for plugins, or other times when the plugins applied are not known, the accessors (sourceSets, configurations, etc) of extensions added by other plugins will need to go through a method call which sort of 'retrieves' that scope or object. Further down the link there is also an example of how to get tasks created by other plugins:
val test by target.tasks.existing(Test::class)
test.configure { useJUnitPlatform() }
// or
val test by target.tasks.existing(Test::class) {
useJUnitPlatform()
}
note that if the 'sourceSet' object does not exist on the project (because the java plugin was not applied), an exception will be thrown .
tested with gradle version 7.2, kotlin-dsl version 2.1.6
Trying to create a custom plugin to share the buildscript logic across projects. I have added the buildscript classpath dependencies but it is still saying that the plugin can't be found. I do not want to manually it in the project that is using the custom plugin because I may have to change the version number in the future. Is there any solution for this?
DependencyManagementPlugin.java
public class DependencyManagementPlugin implements Plugin<Project> {
#Override
public void apply(Project project) {
DependencyHandler dependencies = project.getBuildscript().getDependencies();
dependencies.add("classpath", "org.springframework.boot:spring-boot-gradle-plugin:2.4.10");
dependencies.add(
"classpath",
"io.spring.dependency-management:io.spring.dependency-management.gradle.plugin:1.0.11.RELEASE");
PluginContainer plugins = project.getPlugins();
plugins.apply(MavenPublishPlugin.class);
plugins.apply(JavaPlugin.class);
plugins.apply(JacocoPlugin.class);
plugins.apply("org.springframework.boot");
plugins.apply("io.spring.dependency-management");
}
}
build.gradle
plugins {
id 'groovy-gradle-plugin'
id 'maven-publish'
}
gradlePlugin {
plugins {
dependencyManagementPlugin {
id = 'com.example.dependency-management'
implementationClass = 'com.example.DependencyManagementPlugin'
}
}
}
using the plugin in another build.gradle
plugins {
id 'com.example.dependency-management'
}
...
Error message:
An exception occurred applying plugin request [id: 'com.example.dependency-management']
> Failed to apply plugin 'com.example.dependency-management'.
> Plugin with id 'org.springframework.boot' not found.
The solution is to add the dependency in the dependencies block of the build.gradle of the custom gradle plugin project.
https://docs.gradle.org/current/samples/sample_convention_plugins.html
I need to apply a gradle plugin, in this case errorprone from a custom Gradle plugin.
My Plugin has a build.gradle that looks like this:
gradlePlugin {
plugins {
myErrorprone {
id = 'my-errorprone'
implementationClass = 'com.my.MyErrorpronePlugin'
}
}
}
And the plugin code is:
public class MyErrorpronePlugin implements Plugin<Project> {
List<String> compilerArgs =
Arrays.asList(
"-XepExcludedPaths:.*/proto/.*|.*/protoGeneratedSrc/.*",
"-XepDisableWarningsInGeneratedCode");
#Override
public void apply(Project project) {
project.getPluginManager().apply("net.ltgt.errorprone:");
for (JavaCompile task : project.getTasks().withType(JavaCompile.class)) {
task.getOptions().setCompilerArgs(compilerArgs);
}
}
}
Then, when in another project I apply this plugin (after getting the dependencies in the buildscript)
like this:
apply plugin: 'my-errorprone'
A problem occurred evaluating root project 'my-project.
Failed to apply plugin [id 'my-errorprone']
Plugin with id 'net.ltgt.errorprone' not found.
And it only resolved if i add to buildscript classpath
classpath "net.ltgt.gradle:gradle-errorprone-plugin:0.0.16"
How can I make my plugin work in such way that the project that consumes my plugin will not have to add this direct dependency in the classpath in "net.ltgt.gradle:gradle-errorprone-plugin:0.0.16" ?
In order to solve it, one should apply the plugin by class rather than by ID. This will force you to include error prone dependency in your plugin’s dependency list as it won’t compile until you add the dependency.
import net.ltgt.gradle.errorprone.ErrorPronePlugin.class;
public class MyPlugin implements Plugin<Project> {
public void apply(Project project) {
project.getPluginManager().apply(ErrorPronePlugin.class);
// custom logic here
}
}
and in the build.gradle file:
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
api "net.ltgt.gradle:gradle-errorprone-plugin:1.1.1"
}
I found the answer in Gradle's forum under this topic:
https://discuss.gradle.org/t/apply-a-gradle-plugin-errorprone-from-a-custom-gradle-java-plugin/34645/4
I have a distributes projects with different sub-projects and I want to accomplish the following:
(root)
client
module A
module B
module C
model
I want to put
protoc {
artifact = 'com.google.protobuf:protoc:3.5.0'
}
plugins {
grpc {
artifact = "io.grpc:protoc-gen-grpc-java:1.7.0"
}
}
generateProtoTasks {
all()*.plugins {
grpc {}
}
} }
dependencies {
compile "com.google.api.grpc:proto-google-common-protos:1.0.0"
compile "io.grpc:grpc-netty:1.7.0"
compile "io.grpc:grpc-protobuf:1.7.0"
compile "io.grpc:grpc-stub:1.7.0"
}
for module A, B and C.
For now I have the following in my root build.gradle
subprojects{
apply plugin: 'java'
sourceCompatibility = 1.8
group 'project'
version '0.0.1-SNAPSHOT'
jar {
manifest {
attributes 'Main-Class': "com.project.${project.name}.App"
}
doFirst {
from { configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) } }
}
}
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.9.5'
}
}
So every sub-project use java plugin, and has the defines dependencies and jar task.
How can I only put the first block for some sub-projects ?
I tried using a variable like in Multi-project Builds - Gradle but I couldn't access it in subprojects block.
Thank you in advance. I'm really interested in using Gradle correctly and it's a bit hard to get into it outside of simple Android/Java projects. Feel free to include any documentations I should read :)
Edit:
Thank you. I wouldn't have posted here if I hadn't search before. Apparently I was missing the keyword "subset" who would have gave me the solution you linked.
A solution is described here: https://discuss.gradle.org/t/configure-only-subset-of-subprojects/5379/3
You can run configure() with a list of projects.
project.ext {
subprojectList = subprojects.findAll{
it.name == 'subprojectA' ||
it.name == 'subprojectB' ||
it.name == 'subprojectC'
}
}
configure(project.subprojectList) {
// insert your custom configuration code
}
or
configure([project(':a'), project(':b'), project(':c')]) {
// configuration
}
I am trying to reorganize this Android (Java based) library to use the buildSrc folder to define all versions and dependencies as described in this article.
I already set this successfully up for several times for Kotlin bases projects. This time the project is pure Java.
In the buildSrc folder I created the following buildSrc/src/main/java/org/ligi/snackengage/Dependencies.java file:
package org.ligi.snackengage;
public class Dependencies {
public static class Android { /* ... */ }
public static class GradlePlugins {
public static final String ANDROID = "com.android.tools.build:gradle:3.6.3";
// ...
}
public static class Libs { /* ... */ }
}
Then I refer to the definitions in the project root build.gradle among others:
import org.ligi.snackengage.Dependencies.GradlePlugins
apply plugin: "com.github.ben-manes.versions"
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath GradlePlugins.ANDROID
classpath GradlePlugins.MAVEN
classpath GradlePlugins.VERSIONS
}
}
allprojects {
repositories {
google()
jcenter()
}
}
Here is the work in progress branch. When I build the project then the following error occurs:
* Where:
Build file 'SnackEngage/build.gradle' line: 12
* What went wrong:
A problem occurred evaluating root project 'SnackEngage'.
> Could not get unknown property 'GradlePlugins' for object of type
org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.
Here is the build log.
You have defined GradlePlugins class as an inner static class of Dependencies, so you need to use Dependencies.GradlePlugins to access it from your build script.
Change your dependencies block as follows:
import org.ligi.snackengage.Dependencies // do not import org.ligi.snackengage.Dependencies.GradlePlugins
buildscript {
// ...
dependencies {
classpath Dependencies.GradlePlugins.ANDROID
classpath Dependencies.GradlePlugins.MAVEN
classpath Dependencies.GradlePlugins.VERSIONS
}
}
EDIT you could also use a static import, as follows:
import static org.ligi.snackengage.Dependencies.*
buildscript {
// ...
dependencies {
classpath GradlePlugins.ANDROID
classpath GradlePlugins.MAVEN
classpath GradlePlugins.VERSIONS
}
}
You need to define variable GradlePlugins with def (in Gradle) or public class GradlePlugins (in Java), before attempting to access it. Kotlin class GradlePlugins should also work.
dependencies {
classpath GradlePlugins.ANDROID
classpath GradlePlugins.MAVEN
classpath GradlePlugins.VERSIONS
}
And I think the buildSrc directory belongs into the module directory, as the Gradle manual shows.