开发者

My gradle configuration does not use the correct classpath during build

开发者 https://www.devze.com 2023-03-06 13:41 出处:网络
I have a multi-project setup (ProjectB -> ProjectA), and I\'m using flatDir to specify a single lib directory in each project.

I have a multi-project setup (ProjectB -> ProjectA), and I'm using flatDir to specify a single lib directory in each project.

ProjectA:

repositories {
    flatDir name: 'localRepository', dirs: 'lib'
}

dependencies {
    compile group: 'com.google.guava', name: 'guava', version: 'r08'
    compile group: 'com.miglayout', name: 'miglayout', version: '3.7.4'
    testCompile group: 'junit', name: 'junit', version: '4.+'
    testCompile group: 'org.easymock', name: 'easymock', version: '2.5.2'
}

ProjectB:

repositories {
    flatDir name: 'localRepository', dirs: 'lib'
}

dependencies {
    compile group: 'yan', name: 'yan', version: '5.0.2'
    runtime group: 'yan', name: 'jfunutil', version: '5.0.2'
    compile project(':ProjectA')
    testCompile group: 'junit', name: 'junit', version: '4.+'
    testCompile group: 'org.easymock'开发者_如何学Go, name: 'easymock', version: '2.5.2'

}

When I use gradle dependencies for ProjectB, the correct dependency list is generated, showing transitive dependencies from ProjectA (eg, including guava-r08). However, when I gradle build, the actual classpath used for javac only includes the direct dependencies of ProjectB, and the jar generated by building ProjectA.

Another annoyance is it seems for testCompile, I have to re-declare the dependency on junit for ProjectB otherwise gradle dependencies will not be successful.

Any pointers much appreciated - I am new to Gradle.


About your project structure...

It seems like a better idea to have a single lib folder instead of having one for each project.

Your directory structure is like this:

project/settings.gradle
project/ProjectA/lib
project/ProjectA/src
project/ProjectB/lib
project/ProjectB/src

Any particular reason why you want to have a lib folder for each subproject? This seems like a better idea:

project/settings.gradle
project/lib
project/ProjectA/src
project/ProjectB/src

You can create a build.gradle in the root of the project (project/build.gradle) that contains the following:

subprojects{
   apply plugin: 'java'
   repositories {
        flatDir name: 'localRepository', dirs: "$rootProject.projectDir/lib"
   }
}

This way you can drop all your dependencies into project/lib.

About your test depencendies...

You may also place your testCompile dependencies into this root build.gradle file. It becomes:

subprojects{
   apply plugin: 'java'
   repositories {
        flatDir name: 'localRepository', dirs: "$rootProject.projectDir/lib"
   }
   dependencies{
        testCompile group: 'junit', name: 'junit', version: '4.+'
        testCompile group: 'org.easymock', name: 'easymock', version: '2.5.2'
   }
}

This way you do not have to specify the testCompile dependency in each subproject's build.gradle file.

However, when I gradle build, the actual classpath used for javac only includes the direct dependencies of ProjectB, and the jar generated by building ProjectA.

In order to compile ProjectB, you only need ProjectA. Only ProjectA is your compile dependency; ProjectA compile dependencies become ProjectB's transitive dependencies.


I agree with the previous answer. After a number of attempts we have the same structure

> shared
 - build.gradle
 - gradle.properties
 - settings.gradle
> project-a 
 - gradle.properties
 - settings.gradle
> project-b 
 - gradle.properties
 - settings.gradle

Shared has all the common code, in our case it handles checkins, module deploy, code quality (cobertura), compile etc Shared also defines the classpath which is inherited by sub-projects which can then add additional dependencies.

For your problem:

Have you defined the following in your Project A?

settings.gradle includeFlat('Project B')

Have you defined the following in Project B?

settings.gradle includeFlat('Project A')


The build scripts in your original post are fine. The reason why transitive dependency resolution doesn't work is that a project will only ever use its own repositories for resolving its configurations. Hence, one way to overcome your problem is to have just one lib directory. Another solution is to declare a second repository for B that points to A's lib directory.

Another annoyance is it seems for testCompile, I have to re-declare the dependency on junit for ProjectB otherwise gradle dependencies will not be successful.

Not sure what you are saying here, but it might be a consequence of what I explained above. Maybe the following information also helps: Depending on a project doesn't pull in its testCompile/testRuntime dependencies. It's expected that you have to declare JUnit for each project that needs it. To avoid repetition, you can use configuration injection to declare the commonalities between your projects. Previous answers already gave concrete examples for this (e.g. subprojects { ... }).

0

精彩评论

暂无评论...
验证码 换一张
取 消