shadow
shadow copied to clipboard
IntelliJ IDEA unable to resolve classes of project dependency shadow jar
Shadow: 1.2.4 Gradle: 2.5
From what I understand compile project(path: ':common', configuration: 'shadow')
should result in the shaded artifact being selected as a dependency. This appears to work, however, IntelliJ IDEA will not resolve the contents of the shaded artifact.
Now here is the weird thing, if I change the configuration of the project dependencies to compile, the IDE is able to resolve the classes but the compiler cannot. If I change it back to shadow the compiler can resolve the classes and the IDE cannot... o.O
root build.gradle
buildscript {
repositories {
mavenCentral()
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
maven { url 'https://plugins.gradle.org/m2/' }
}
}
plugins {
id 'nebula.provided-base' version '3.0.3'
id 'com.github.johnrengelman.shadow' version '1.2.4'
}
subprojects {
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'java'
apply plugin: 'nebula.provided-base'
apply plugin: 'maven'
apply plugin: 'com.github.johnrengelman.shadow'
idea {
module {
scopes.PROVIDED.plus += [configurations.shadow]
}
}
tasks.withType(AbstractCompile) {
classpath += configurations.shadow
}
ext {
junit = '4.12'
lombok = '1.16.8'
guava = '19.0'
gson = '2.3.1'
log4j = '2.0-beta9'
jsonrpc2 = '1.15'
json_smart = '1.3.1'
reflections = '0.9.10'
javassist = '3.12.1.GA'
zip4j = '1.3.2'
}
repositories {
mavenLocal()
mavenCentral()
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
maven { url 'https://oss.sonatype.org/content/repositories/releases/' }
}
dependencies {
testCompile group: 'junit', name: 'junit', version: junit
provided group: 'net.minidev', name: 'json-smart', version: json_smart
provided group: 'org.projectlombok', name: 'lombok', version: lombok
provided group: 'com.google.guava', name: 'guava', version: guava
provided group: 'org.apache.logging.log4j', name: 'log4j-core', version: log4j
provided group: 'com.google.code.gson', name: 'gson', version: gson
provided group: 'net.lingala.zip4j', name: 'zip4j', version: zip4j
}
shadowJar {
relocate 'com.google.gson', 'com.enjin.shaded.gson'
relocate 'net.minidev.json', 'com.enjin.shaded.json'
}
}
subproject core build.gradle
sourceCompatibility = 1.7
dependencies {
compile group: 'com.google.code.gson', name: 'gson', version: gson
}
shadowJar {
dependencies {
include(dependency('.*:json-smart'))
include(dependency('.*:gson'))
}
}
subproject rpcapi build.gradle
sourceCompatibility = 1.7
dependencies {
compile project(path: ':core', configuration: 'shadow')
compile group: 'com.thetransactioncompany', name: 'jsonrpc2-client', version: jsonrpc2
}
shadowJar {
dependencies {
include(project(':core'))
include(dependency('com.thetransactioncompany:.*'))
}
}
And so on...
Any ideas as to why I would experience this issue @johnrengelman ?
Same Issue here. Using Intellij 2016.3 and gradle 2.14.1
Only workaround I found was to add all transitive project dependencies as a shadow dependency in every single build file. So 'rpcapi' has 'core', 'common' has 'rpcapi' and 'core', and so on. Not really an ideal solution, but it'll do the job until this issue is resolved.
Does someone have a simple project on github that exhibits the problem?
Unfortunately not as this issue is part of a large project I work on for the company I'm contracted with. I can work on making an example project that replicates the issue, but I can't get to that immediately.
For an example, you can look at https://github.com/TNG/JGiven, where the same problem exists. Neither using ./gradlew idea
nor importing the project as a gradle project into IntelliJ works.
There is also an open defect for IntelliJ regarding this issue: https://youtrack.jetbrains.com/issue/IDEA-163411
Why is this causing compile errors in one file in my fairly large Android Studio project? See the issue referenced by @dariuszeweryn above.
When I update my rxandroidble-parent
project in Android Studio to v. 1.10.2, I get these "cannot resolve symbol" errors in the file RxBleGattCallback.java
: bleshadow
(lines 26 & 27), Inject
(line 59), and Named
(line 60).
Everything else compiles OK.
Is there any workaround for this?
workaround I came up with: use shadow jars for the libraries that depend on the core jar, but set configurations to an empty in their config, and set it to project.configurations.compile on the core jar build.gradle
@MicleBrick Can you post some example configuration please? I don't know how to apply your mentioned workaround.
if you're having the same issue you should just be able to make the changes i mentioned in the relevant places. make all of the sub projects use shadow to make their jars. check the docs to see how to configure which configurations shadow packs into the jar.
@johnrengelman you asked if anyone has a project on github that exhibits the problem. I have an open source project at https://github.com/autonomousapps/dependency-analysis-android-gradle-plugin/tree/pub-antlr. If you check out that branch and import it into IDEA, you should see the problem. It compiles from the command line but the class ImportFinderTask.kt
has three unresolved references. I've tried a couple of workarounds suggested by Cedric and Stefan at Gradle (see this thread), but they are not working for my case, for some reason that is as yet beyond me. Any help would be greatly appreciated.
For what it's worth, I was able to achieve a workaround by adding a dependency to the output of the shadowJar
task rather than the project itself.
Project structure:
project/
producer/
build.gradle
consumer/
build.gradle
build.gradle
producer's build.gradle
:
apply plugin: "com.github.johnrengelman.shadow"
shadowJar {
relocate 'old.package', 'new.package'
}
consumer's build.gradle
:
dependencies {
compile files(tasks.getByPath(':producer:shadowJar').archiveFile)
}
IDEA will not run the shadowJar
task automatically when Gradle dependencies are refreshed. However, I was able to rectify this by specifying that the shadowJar task should be run before syncing the project in IntelliJ:
-
View > Tool Windows > Gradle
- Drill down to the producer project's
shadowJar
task - Right-click the
shadowJar
task and selectExecute Before Sync
.
This can also be configured without needing to set it manually in IDEA, with the help of the idea-ext
plugin:
In the project's root build.gradle
(won't work in a subproject's build.gradle
):
plugins {
id "org.jetbrains.gradle.plugin.idea-ext" version "1.0"
}
// Since the following references a subproject's task,
// it will need to be run after the subproject has been evaluated.
// You will likely need to put the following block toward the end
// of your project's build.gradle for it to work.
apply plugin: 'org.jetbrains.gradle.plugin.idea-ext'
idea.project.settings {
taskTriggers {
beforeSync tasks.getByPath(':producer:shadowJar')
}
}
After playing around a bit, I've found that uploading the shadow jar to one's local Maven repository and referencing that instead is probably the easiest solution.
Project structure
project/
producer/
build.gradle
consumer/
build.gradle
build.gradle
producer's build.gradle:
apply plugin: "com.github.johnrengelman.shadow"
shadowJar {
relocate 'old.package', 'new.package'
}
consumer's build.gradle:
repositories {
mavenLocal()
}
// Ensure the shadow jar is published to local repo before this class is compiled.
compileJava.dependsOn(tasks.getByPath(':producer:publishToMavenLocal'))
dependencies {
compile(group: project.group, name: "producer", version: project.version, classifier: "shadow")
}
This works well with IDEA, as IntelliJ will resolve the shadow jar from the local Maven repo.
Hi @autonomousapps , I tried to go to your existing thread with Cedric and folks but is gone (thanks Slack free tier).
do you recall what things you tried? I saw that in your repo you produce a jar for antlr
module and then add it to libs
.
publishing a jar and import it on intellij is far from ideal, same as creating dependencies between project tasks and cross the boundaries.
I don't even think using feature/variants help much here. What are your thoughts?
I gave up and never tried again.
On August 13, 2021, GitHub @.***> wrote:
Hi @autonomousapps https://github.com/autonomousapps , I tried to go to your existing thread with Cedric and folks but is gone (thanks Slack free tier).
do you recall what things you tried? or did you ever overcome this issue?
publishing a jar and import it on intellij is far from ideal, same as creating dependencies between project tasks and cross the boundaries.
I don't even think using feature/variants help much here. What are your thoughts?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <https://github.com/johnrengelman/shadow/issues/264#issuecomment- 898754446>, or unsubscribe <https://github.com/notifications/unsubscribe- auth/ABJG5PLTE7DTKLX7MUP63ZLT4WNJRANCNFSM4CX7TYIQ>. Triage notifications on the go with GitHub Mobile for iOS <https://apps.apple.com/app/apple-store/id1477376905?ct=notification- email&mt=8&pt=524675> or Android <https://play.google.com/store/apps/details?id=com.github.android&utm_campaign=notification- email>.
I have a similar issue, but with dependencies that are part of the shadow
configurations. When I try to run code from intellij, I'm getting NoClassDefFoundError
for those.
I've tried the suggested workaround with idea-ext
plugin, but that didn't solve anything in my case.
I have a project to reproduce this, with the following steps:
- clone https://github.com/serpro69/kotlin-faker
- open the project in intellij and go to e.g.
Faker
class from thecore
module - add a main function with code that uses a "shadow" dependency
fun main() {
val s = FakerService(Faker())
with(s) {
println("(a|b|c){3,5}".generexify())
}
}
- run it with intellij
- get
Exception in thread "main" java.lang.NoClassDefFoundError: com/mifmif/common/regex/Generex
So the generex
dependency is part of shadow
configuration: https://github.com/serpro69/kotlin-faker/blob/97ff39ea7e2d991f41901d460c5ee8c3b7328f28/core/build.gradle.kts#L13
And it seems that intellij can't resolve that.
If I add something like this to the build file: runtimeOnly(libs.generex)
, then the dependency is picked up and I can run things from intellij. But obviously this isn't a good workaround.
Am I doing something wrong with my build configuration? Is this actual behavior of shadow
configurations? Or are there any better workarounds I could try? E.g. with aforementioned idea-ext
plugin?