builrd/resources broken for gradle projects ?

At some change in some 13.x version (and EAP 14), the classpath when running an application in a gradle project no longer includes src/main/resources (through "build/resources/main" or any other folder called "resources") for any of the modules, which means my program is no longer able to load classpath resources, since they are not included in the classpath.

If I go into "Project Settings | Modules" I will see src/main/resources correctly tagged as "resources". Any idea of what might be causing this ?

(If its interesting I can probably bisect to the specif idea version where this broke...)

Kristian

15 comments
Comment actions Permalink

13.0.4 seems to be the last version this works in.

0
Comment actions Permalink

I guess, it happens after you invoke some gradle tasks like *gradle clean build*, which clean build dir and then put compiled classes into 'build/classes/main' folder.
The 'build/classes/main' folder used by IDEA now by default for compiler output (it's planned to add an IDEA build-system agnostic setting for output directories choice, see http://youtrack.jetbrains.com/issue/IDEA-91952).
Next, IDEA are not aware of these changes in output folder and do not copy resources again due to incremental compilation optimization

try to add

allprojects {
    apply plugin: 'idea'
    idea {
        module {
            inheritOutputDirs = true
        }
    }
}


You can also see comments at http://youtrack.jetbrains.com/issue/IDEA-126986 for details.

UPDATE: there is open issue for processing of gradle resources (with support of filtering/inclusion/exclusion of files), it will help to avoid this particular issue - http://youtrack.jetbrains.com/issue/IDEA-127046

0
Comment actions Permalink

I am not sure this is the same problem, neither with your update


In idea 14 or 13.1.4 I can do

    <Invalidate caches in idea>
    <close project>
    rm -rf .idea # in project home directory
    import from gradle wrapper (v1.12)

Run a single class with a "main" method in a muiltimodule project and *not* get classpath resources, the java class with the main method is in the same module as the resource. This works in 13.0.4

Kristian

0
Comment actions Permalink

Did you try idea.module.inheritOutputDirs = true option of the idea plugin (note, after the change in *.gradle script, you have to reimport the project)?

0
Comment actions Permalink

Splitting output directories for idea/gradle works, but has other issues with it. The gradle integration in idea is where the maven integration used to be about 5 years ago; quite buggy and to a user it's fairly arbitrary if/when it works. Most of my colleagues cross fingers and say silent prayers every time we have to reimport. Right now interllij is not able to *build* my gradle project because IDEA does not get the classpath right. So I have to rely on "gradle build" from the CLI to actually make the whole project compile. So splitting the compiler output is not good, and by historcial precedent it will be like that for at least another year. So it should probably be possible to disable those post 13.0.4 optimizations :)  Make it work, make it pretty, make it fast; the gradle integration is still at step 1.


Looking a bit further at my problem, it seems like my issue is that there *cannot* be any kind of "build" folder when I run import; I suppose that's just a permutation of the issues you're already seeing.

The moment I added a "gradle clean" before I did rm -rf .idea, it all seems to be solved.

Kristian

0
Comment actions Permalink

afaik, there was no post 13.0.4 optimizations in the make of gradle projects. And the only difference(related to the problem) I know, is the change of the default value of compiler output folder during import from Gradle.
Previously, it used IDEA specific output folder, now it uses the same output folder like gradle.
The problem is that IDEA itself does not support different output folders for compiled classes and resources but gradle does (e.g. build/classes/main and build/resources/main).
You can go to File => Project Structure => Modules => Compile output => Output path, there is only two paths: one for for test classes/test resources and other for production classes/resources.
That's why IDEA put resoures into 'build/classes/main' output folder.

This was changed for IDEA Gradle integration within http://youtrack.jetbrains.com/issue/IDEA-127046 issue.
Please, try next IDEA 14 eap build, it will be available ~ at 6th of August and will include the feature.

0
Comment actions Permalink

Thanks for a great explanation, I'll try the next EAP :)

0
Comment actions Permalink

Has this issue crept back in?  Our team is experience this issue in the latest version of Intellij 2017.2.6.  The idea.module.inheritOutputDirs = true makes things worse.

3
Comment actions Permalink

Oh, good. I'm not crazy. I've been having problems with this too in v2017.2.6. Gradle's `SourceSet.runtimeClasspath` includes the "build/main/resources" dir, but IDEA's runtime classpath does not. I cannot for the life of me figure out why.

1
Comment actions Permalink

FYI, this workaround solves the problem for me:

https://youtrack.jetbrains.com/issue/IDEA-176738#comment=27-2518612

It looks like you can tell IDEA to use gradle's build process and classpath instead of its own for running the code.

0
Comment actions Permalink

This is such a frustrating issue. Seemingly randomly it can no longer find my log configuration... using the workaround Cuchaz posted works, but you then have to rebuild whenever you make even the slightest change.

Really, really don't want to switch my entire project over to Maven just to sidestep an IDE issue ._.

0
Comment actions Permalink

Hi. per our developers, hot swap support for gradle delegated builds is planned for 2018.2. After that, most probably, "delegate build to gradle" would be on by default for all gradle projects.

0
Comment actions Permalink

Delegating to gradle is not a viable end all solution. Saying you /have/ to use this optional setting is just...yeah.  A lot of people I know, our company included, want to use gradle for CI and to populate IDE settings but stick with IDE for actions that require rapid iteration.

Real world example would be the work I did for a multi-module multiplatform kotlin build.  It consisted of a library with multiple multiplatform modules, and requirements to be able to provide out of the box support (as much as possible without extra tooling) for people building an app with that library.

Iteration by delegating through gradle (with parallel, build cache, deferred configuration, and incremental compilation for JS and JVM turned on) was so slow (comparatively) that the system was not adopted.  People would rather ditch having common modules and all that brings, revert back to the faked common modules through interfaces, than do this.  They would be happy if they could just lean back on intellij for rapid iteration activities.

As a note to those that are curious (as this obviously needs to be reported to someone, somewhere that's not here), taking all of the other gradle tasks and portions out of the equation, the really slow part was when gradle would get to the incremental compilation task.  This took way longer than any equivalent incremental compile provided by intellij or build scripts that use the compiler directly.  It also wasn't consistent.

0

Please sign in to leave a comment.