My Gradle project depends on commons-io 2.4, but G

2019-08-08 10:16发布

问题:

I've been iterating on features in my first Gradle plugin. I determined early on that I needed commons-io, so I added a dependency on commons-io 2.4, being the latest version.

This has been going well for a while, with the build working from the command line, and no errors in Eclipse.

I just started trying to integrate some code that uses "FileUtils.write(File,String)". I didn't need that method before. I got everything un-redded in Eclipse, and then I tried a command line build.

This failed with errors like the following:

    ... error: cannot find symbol
                FileUtils.write(serviceLoaderFile,
                         ^
  symbol:   method write(File,String)
  location: class FileUtils

This confused me. I went to the failing lines in Eclipse, and no issues were indicated. I navigated into the "write()" method, and it looked fine to me. I then ran my command-line build with "--debug" to get some clues.

When I found the "javac" line, I found that "$GRADLE_HOME\lib\commons-io-1.4.jar" (where "GRADLE_HOME" is just my Gradle 2.3 distribution) was in the classpath BEFORE my dependency jar. I then inspected the code in the 1.4 jar, and I determined that the "FileUtils" class in that version didn't have a "write" method.

What am I supposed to do about this?

Update:

I suppose it's likely my "dependencies" block would be useful, which is this:

dependencies {
  compile ("org.codehaus.groovy:groovy-all:2.3.9")
  compile gradleApi()
  compile "org.opendaylight.yangtools:yang-parser-impl:0.7.0-SNAPSHOT"
  compile "org.opendaylight.yangtools:binding-java-api-generator:0.7.0-SNAPSHOT"
  compile "org.opendaylight.yangtools:binding-generator-api:0.7.0-SNAPSHOT"
  compile "org.opendaylight.yangtools:binding-generator-impl:0.7.0-SNAPSHOT"
  compile "org.opendaylight.controller:yang-jmx-generator:0.3.0-SNAPSHOT"
  compile "commons-io:commons-io:2.4"

  testCompile("org.spockframework:spock-core:1.0-groovy-2.3") {
    exclude group: "org.codehaus.groovy"
  }

I tried commenting out the "gradleApi" reference, and that had no effect. I also tried adding an "exclude" for commons-io associated with the "groovy-all" reference, but that also didn't appear to make any difference. }

回答1:

You probably added gradleApi() under dependencies {} block - see the docs. The problem is that it ships all dependencies gradle requires - including commons-io in version 1.4 - see the extract below:

[opal@opal-mac-2]~/.gvm/gradle/current/lib % pwd
/Users/opal/.gvm/gradle/current/lib
[opal@opal-mac-2]~/.gvm/gradle/current/lib % ll commons-io-1.4.jar 
-rw-rw-r--  1 opal  staff  109043 23 gru 13:17 commons-io-1.4.jar
[opal@opal-mac-2]~/.gvm/gradle/current/lib % 

You probably added version 2.4 separately and that's why conflict occurred. You can also run

gradle dependencies

to view the full dependency tree and verify the problem.

There's no possibility to exclude a transitive dependency from gradleApi().



回答2:

The solution to this required adding the following block to the "sourceSets" block:

main {
    compileClasspath = configurations.compile.minus files("$gradle.gradleHomeDir/lib/commons-io-1.4.jar")
}

This is pretty simple, but I wish there was a cleaner solution for this. I'm not sure what that would look like.