简体   繁体   中英

Gradle provided dependencies with Intellij

I'm trying to build a Bukkit plugin. The plugin also uses exp4j . The final result needs to have the exp4j code included in the released jar but not have the Bukkit code included.

I followed the advice of this answer to copy the dependencies in and used this answer to declare Bukkit as provided. My build.gradle now looks like this:

apply plugin: 'java'
apply plugin: 'idea'

configurations {
    provided
}

sourceSets {
    main.compileClasspath += configurations.provided
    test.compileClasspath += configurations.provided
    test.runtimeClasspath += configurations.provided
}

dependencies {
    provided "org.bukkit:bukkit:1.8.8-R0.1-SNAPSHOT"
    compile "net.objecthunter:exp4j:0.4.5"
}

jar {
    // copy the dependencies across
    from {
        configurations.compile.collect {
            it.isDirectory() ? it : zipTree(it)
        }
    }
}

This works great and I can build and run the project happily using Gradle from the command line. The trouble is that Intellij (or maybe it's the Gradle idea plugin) doesn't recognise the provided dependencies, thus, importing anything from Bukkit causes it to incorrectly report an error.

How can I get the provided dependencies to play nicely with idea?

Other things I've tried:

I've also tried declaring the provided scope like this:

configurations {
    provided
    compile.extendsFrom provided
}

But this causes the provided dependencies to be copied into the final jar. I've also tried the plugins as recommended by this answer , but both cause Bukkit to be copied into the created jar. I've further tried declaring Bukkit to be runtime scope instead provided, but that simply caused lots of compile errors (but interestingly Intellij did have Bukkit listed as a dependency)

I have trouble believing that this has not been asked before, but I've searched and cannot find a full solution. I'm new to Gradle, so apologies if this is a super simple thing to do.

In Gradle 2.12 and later, there is a configuration called compileOnly that has the provided semantics you are looking for.

More about this configuration on the Gradle blog post on the subject.

Before 2.12, you can use the nebula.provided-base plugin to create a provided configuration with all the correct semantics.

See Gradle issue here .

There isn't a provided configuration in gradle, though there really should be one. The most reasonable workaround currently seems to be, to create your own configuration:

configurations {
    provided
}

and then:

sourceSets {
    main {
      compileClasspath += configurations.provided
    }
}

The problem with extendsFrom is that the provided dependency will end up being bundled in your distribution anyway unless if you add another explicit exclude, defeating the whole point of provided.

Edit: To tell idea to use the provided dependencies, you could apply the 'idea' plugin and then:

idea {
  module {
    scopes.PROVIDED.plus += [ configurations.provided ]
  }
}

see more here.

I did find a very hacky solution. But it's so bad I feel bad posting it here :P

  1. Declare the provided dependencies as runtime dependencies
  2. Regenerate the idea files: gradle cleanIdea idea
  3. Idea should now recognise the dependences
  4. Change the provided dependencies back to provided
  5. Go into the project settings and convert all the dependencies with runtime scope to Intellij's provided scope
  6. Stuff works :) (Just don't ever regenerate the idea files)

Obvious problems, anyone using your project has to do the same hack. And every time you regenerate the idea files, the same thing will have to be repeated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM