testCompile fails for project A importing project B, despite apparent good classpath setup


(Petula Guimaraes) #1

I have a project structure as follows:

|-rootProject |------projectA |-----------src/ |-----------config/ |-----------build.gradle |------projectB |-----------src/ |-----------config/ |-----------build.gradle |------projectC |-----------src/ |-----------config/ |-----------build.gradle |------projectD |-----------src/ |------------------build.gradle |-----------config/

All projects have their own classes and tests. projectA, however, depends on B, C and D for its compilation and tests.

The code that needs projects C and D compiles just fine. The code that needs B does not. They are all being imported for compile project and for testCompile project in a similar way.

The failure in A compiling code that depends on B is a funy one, as it does not “like” the reference to a java enum variable reference. if I import the enum only it is fine. But if I import static or just use the enum, that part of the code gets a "cannot find symbol).

Here is my gradle of project B

sourceSets {
    main {
    java.srcDirs = [ 'src/packages']
    resources.srcDirs = [ 'src/packages',
'src/xml', 'src/scripts', 'src/sql', 'src/generic_reports', 'src/config', 'src/asrc'
]
     runtimeClasspath = project.sourceSets.main.compileClasspath +
                    project.sourceSets.test.compileClasspath +
                    fileTree("${buildDir}/resources/test") + fileTree("${buildDir}/resources/main") + fileTree("${projectDir}") +
                    project.sourceSets.test.output + project.sourceSets.main.output
      compileClasspath = compileClasspath + configurations.legacy
       }
   test {
  java.srcDirs = [
'src/tests/packages']
  resources.srcDirs = [ 'src/tests/packages', 'src/packages', 'src/xml', 'src/scripts', 'src/tests', 'src/testsuite', 'src/sql', 'src/generic_reports', 'src/config', 'src/asrc' ]
    runtimeClasspath = project.sourceSets.main.compileClasspath +
                    project.sourceSets.test.compileClasspath +
                    fileTree("${buildDir}/resources/test") + fileTree("${buildDir}/resources/main") + fileTree("${projectDir}") +
                    project.sourceSets.test.output + project.sourceSets.main.output
   }
}
  evaluationDependsOn(':projectB)
evaluationDependsOn(':projectC')
evaluationDependsOn(':projectD')
  dependencies {
   compile project(':projectC')
  testCompile project (':projectC').sourceSets.test.runtimeClasspath
 testCompile project (':projectC').sourceSets.main.compileClasspath
                    compile project (':projectD')
 testCompile project (':projectD').sourceSets.test.runtimeClasspath
    compile (project(':projectB')) {
  exclude group: 'fidev', module: 'jfidcore'
 }
    //testCompile project (path: ':stsjava', configuration: 'spi')
//tried, but nothing came out of it
 testCompile project (':projectB').sourceSets.main.runtimeClasspath
    (...
//more on dependencie)
}
  task printClasspath(dependsOn:processResources) {
         println "<><>projectA test compile classpath is:- "
         sourceSets.test.compileClasspath.getFiles().each { file ->
                 println "<><>projectA damn file: \"" + file + "\""
         }
  }

I apparently have what I need in the classpath, the annoying enumeration:

21:02:05 17:02:04.289 [QUIET] [system.out] <><>projectA damn file: "/var/tmp/pjenkbld/jenkins/workspace/ird-trend-continuous-alternative/ird/trend/alternative/src/projectB/src/packages/com/msdw/ird/stsjava/sts/enumz/ExternalSource.java"

The sort of errors I get:

16:41:03 12:41:03.138 [ERROR] [system.err] symbol
: variable UTI
16:41:03 12:41:03.138 [ERROR] [system.err] location: class com.msdw.ird.projectA.itm2sts.service.builder.ParameterizedExternalRefFactoriesTest
16:41:03 12:41:03.138 [ERROR] [system.err]
           validateReference(references, UTI, uti.getIdentifier(), _enableUtiBackbridge);
    16:41:02 12:41:02.171 [ERROR] [system.err] symbol
: static PriorUTIPrefix
16:41:02 12:41:02.171 [ERROR] [system.err] location: class com.msdw.ird.projectB.sts.enumz.ExternalSource
16:41:02 12:41:02.171 [ERROR] [system.err] import static com.msdw.ird.projectB.sts.enumz.ExternalSource.PriorUTIPrefix;

I am failing to understand what works for the correct import of projects C and D, but not B.

Any suggestions?

Thanks! Petula


(Petula Guimaraes) #2

I would stress I have an alledgedly good classpath:

sourceSets {
     main {
       java.srcDirs = [ 'src/packages']
       resources.srcDirs = [ 'src/packages',
'src/xml', 'src/scripts', 'src/sql', 'src/generic_reports', 'src/config', 'src/asrc'
]
        runtimeClasspath = project.sourceSets.main.compileClasspath +
                    project.sourceSets.test.compileClasspath +
                    fileTree("${buildDir}/resources/test") + fileTree("${buildDir}/resources/main") + fileTree("${projectDir}") +
                    project.sourceSets.test.output + project.sourceSets.main.output
       compileClasspath = compileClasspath + configurations.legacy
                   }
    test {
        java.srcDirs = [
'src/tests/packages']
        resources.srcDirs = [ 'src/tests/packages', 'src/packages', 'src/xml', 'src/scripts', 'src/tests', 'src/testsuite', 'src/sql', 'src/generic_reports', 'src/config', 'src/asrc' ]
        runtimeClasspath = project.sourceSets.main.compileClasspath +
                    project.sourceSets.test.compileClasspath +
                    fileTree("${buildDir}/resources/test") + fileTree("${buildDir}/resources/main") + fileTree("${projectDir}") +
                    project.sourceSets.test.output + project.sourceSets.main.output
    }
}

Again, the code for the dependencies:

evaluationDependsOn(':projectB)
evaluationDependsOn(':projectC')
evaluationDependsOn(':projectD')
  dependencies {
    compile project(':projectC')
        testCompile project (':projectC').sourceSets.test.runtimeClasspath
    testCompile project (':projectC').sourceSets.main.compileClasspath
                  compile project (':projectD')
    testCompile project (':projectD').sourceSets.test.runtimeClasspath
    compile (project(':projectB')) {
        exclude group: 'fidev', module: 'jfidcore'
    }
        testCompile project (':projectB').sourceSets.main.runtimeClasspath
        (...
//more on dependencie)
}

(Petula Guimaraes) #3

I still could not get what is wrong with this particular dependency.

I have tried several approaches such as importing the main or test classpaths (variations on runtime and compile time)

compile project(':projectC')
        testCompile project (':projectC').sourceSets.test.runtimeClasspath
    testCompile project (':projectC').sourceSets.main.compileClasspath

I also tried a not-very-nice explicit reference to the output folder of the dependency

compile project(':projectC')
        testCompile project (':projectC').sourceSets.main.output

and the section of sourceSets is now so promiscuous that I even forced the source folders on test and on main>

files(sourceSets.main.java.srcDirs) + files(sourceSets.test.java.srcDirs)

It is very strange that all of those yield to my sources of projectC to be in the classpath, but the tests compilation cannot succeed.

Why can’t a normal project dependency be available in the classpath on the moment of test compilation?

Any ideas?


(Peter Niederwieser) #4

I recommend to simplify the build until you arrive at a minimal failing example, and then study that. The existing code is too complicated/convoluted to reason about, in particular from a distance.


(Petula Guimaraes) #5

I am back to the original situation and I can’t make it work.

sourceSets is very clean:

sourceSets {
    main {
    java.srcDirs = [ 'src/packages']
    resources.srcDirs = [ 'src/packages',
'src/xml', 'src/scripts', 'src/sql', 'src/generic_reports', 'src/config', 'src/asrc'
]
      compileClasspath = compileClasspath + configurations.legacy
              runtimeClasspath += project.sourceSets.main.compileClasspath +
                    project.sourceSets.test.compileClasspath
 }
   test {
  java.srcDirs = [
'src/tests/packages']
   resources.srcDirs = [ 'src/tests/packages', 'src/packages', 'src/xml', 'src/scripts', 'src/tests', 'src/testsuite', 'src/sql', 'src/generic_reports', 'src/config', 'src/asrc' ]
    runtimeClasspath += project.sourceSets.main.compileClasspath +
                    project.sourceSets.test.compileClasspath
 }
}

dependency is clear:

evaluationDependsOn(':projectC')
  dependencies {
 compile (project(':projectC')) {
  exclude group: 'fidev', module: 'jfidcore'
 }
  testCompile project (':projectC').sourceSets.main.compileClasspath
 testCompile project (':projectC').sourceSets.test.runtimeClasspath
   }

The problematic class is in the classpath.

18:22:56 14:22:54.888 [QUIET] [system.out] <><>service damn file: "/var/tmp/pjenkbld/jenkins/workspace/ird-trend-continuous-alternative/ird/trend/alternative/src/projectC/src/packages/com/msdw/ird/projectB/sts/enumz/ExternalSource.java"

Which I logged like this from :

sourceSets.test.compileClasspath.getFiles().each

And I still get cannot find symbol in any test that included this referred class.

Any ideas why it does not work for this class to be found on compileTest?


(Petula Guimaraes) #6

Thanks. I provided new snippets


(Petula Guimaraes) #7

I am totally lost here. I replaced the testCompile dependencies above with something more elaborate, trying to make a separate configuration with this dependency that does not want to be resolved and IT STILL DOES NOT WORK.

Am I so offtrack here?

That is what I did to the project I depend upon, projectC

configurations {
    spi
}
    dependencies {
...
}
  task spiJar(type: Jar) {
        baseName = 'projectc-spi'
        dependsOn classes
        from sourceSets.main.output
        include('com/msdw/ird/**')
    }
  artifacts {
 spiJar
}

and how I am using it

testCompile project (path: ':projectC', configuration: 'spi')

I am sure those thing should work on a “by the book” analysis. I still see all I need in the classpath but somehow my compilation goes somewhere else to resolve my code?


(Petula Guimaraes) #8

FIXED

it turned out all this time I had a nested dependency that I did not suspect was causing the issue. One of my literally hundreds of dependencies was bringing in a jar that contains an older version of this Enum. Nasty.

Therefore, I can only say the approaches above work.

However, not sure why I am not being successful in removing this dependency via configurations.exclude. It always end up in the classpath. My workaround on this is

compileTestJava {
 classpath = classpath.filter {
   it.name != 'oldProjectC.jar'
 }
}

Anyways, I guess this would be subject of another thread. For now it is ok, tests are compiling and executing.

Cheers, Petula