Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IntelliJ IDEA unable to resolve classes of project dependency shadow jar #264

Open
Favorlock opened this issue Nov 30, 2016 · 18 comments
Open

Comments

@Favorlock
Copy link

Favorlock commented Nov 30, 2016

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...

@Favorlock
Copy link
Author

Any ideas as to why I would experience this issue @johnrengelman ?

@Kraeutergarten
Copy link

Kraeutergarten commented Dec 12, 2016

Same Issue here.
Using Intellij 2016.3 and gradle 2.14.1

@Favorlock
Copy link
Author

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.

@johnrengelman
Copy link
Collaborator

Does someone have a simple project on github that exhibits the problem?

@Favorlock
Copy link
Author

Favorlock commented Dec 13, 2016

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.

@janschaefer
Copy link
Contributor

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.

@janschaefer
Copy link
Contributor

There is also an open defect for IntelliJ regarding this issue: https://youtrack.jetbrains.com/issue/IDEA-163411

@RobLewis
Copy link

RobLewis commented Oct 3, 2019

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.

@hafarooki
Copy link

Is there any workaround for this?

@hafarooki
Copy link

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

@benjvoigt
Copy link

@MicleBrick Can you post some example configuration please? I don't know how to apply your mentioned workaround.

@hafarooki
Copy link

hafarooki commented Jul 28, 2020

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.

@autonomousapps
Copy link

@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.

@ericfields
Copy link

ericfields commented Apr 6, 2021

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 select Execute 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')
    }
}

@ericfields
Copy link

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.

@rpalcolea
Copy link
Contributor

rpalcolea commented Aug 13, 2021

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?

@autonomousapps
Copy link

autonomousapps commented Aug 14, 2021 via email

@serpro69
Copy link

serpro69 commented May 12, 2024

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:

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests