Home > Software engineering >  Use gradle to include classes from sub-project A in the classpath for sub-project B
Use gradle to include classes from sub-project A in the classpath for sub-project B

Time:07-03

I'm very new to gradle and was having problems in a more complicated project which provides context to this overall question, so I decided to create a new, simple project to try to get the concept to work, but I still can't get it to work.

I have one sub-project called core and one sub-project called db. I have a class in the db project called com.kenny.db.DBMain which has a main() function that I want to run. DBMain.main() needs to use com.kenny.core.* classes that are defined in the core project.

I'm able to add a dependency in my db/build.gradle so that it depends on :core, but my code in db isn't able to see the classes from core.

db/build.gradle:

plugins {
    id 'java'
}

dependencies {
    project(":core")
}

db/src/main/java/com/kenny/db/DBMain.java:

package com.kenny.main;

import com.kenny.core.*;

public class DBMain {

    public static void main(String[] args) {
        CoreStuff stuff = new CoreStuff();
        System.out.println("db test, name=" stuff.name);
    }
}

When I try to build DBMain.java, it fails because it can't find com.kenny.core.CoreStuff() which was defined in the core project.

/Users/kenny/projects/gradlewtf/db/src/main/java/com/kenny/db/DBMain.java:3: error: cannot find symbol
import com.kenny.core;
                ^
  symbol:   class core
  location: package com.kenny

How do I get the classes from core available when compiling code in the db project?

-- Edit: Changed the core project code package to com.kenny.core and the db project code package to com.kenny.db. Still the same problem, the db project isn't getting the core code into the classpath so it cannot compile.

CodePudding user response:

I finally got it to work. I tried following the documentation on the gradle website itself, but at every turn, their example code failed to even compile. That's because you need to already understand gradle in order to realize that you need to change their example code, but they don't really tell how/what you need to change. I mean, they try to tell you inside a paragraph later on, but unless you are already a gradle expert, those instructions don't make much sense.

I added this to my core/build.gradle file:

// this will create a configuration with the name "instrumentedJars" 
// that will include the implementation (i.e. my classes and 
// classes from dependencies)
configurations {
    instrumentedJars {
        canBeConsumed = true
        canBeResolved = false
        extendsFrom implementation, runtimeOnly
    }
}

// this will declare an "artifact" (i.e. a produced output) 
// for my :core project. It references the configuration name 
// "instrumentedJars" and says that it should include the 
// outputs of the task named "jar"
artifacts {
    instrumentedJars(jar)
}

Then in my project where I need to include those core classes, I added this to my db/build.gradle file:

dependencies {
    implementation(project(path: ":core", configuration: 'instrumentedJars'))
}

Then I can build my db project and it is able to find the classes I need. Then when I need to run my main() method, I added a run task to my db/build.gradle:

task run(type: JavaExec) {
    dependsOn(":db:compileJava")

    mainClass = 'com.kenny.db.DBMain'
    classpath = sourceSets.main.runtimeClasspath
}
  • Related