krakowski / gradle-jextract

Gradle plugin for integrating Project Panama's jextract tool
https://plugins.gradle.org/plugin/io.github.krakowski.jextract
GNU General Public License v3.0
53 stars 10 forks source link

IntelliJ Project Import Issue #17

Closed Brownshome closed 8 months ago

Brownshome commented 1 year ago

Environment

How does this bug occur?

When using jextract in source-mode in a Java module project that is openned as an IntelliJ project.

What happens when the bug occurs?

A dependency is added on the output directory, which contains the sources. This causes issues in IDEA IntelliJ as it sees these files as in the unnamed module, causing import and module access issues.

Would you like to submit a PR fixing this bug?

[x] YES [ ] NO

Brownshome commented 1 year ago

I've attached a minimal example, the project imports incorrectly into IntelliJ (even after running gradle jextract). Once the commented lines in the build file are uncommented it imports correctly (these lines remove the dependency on the jextract source folder, which is not recognised as a module). Delete the build folder, refresh the gradle project and rerun gradle jextract to see this.

minimal example.zip

Errored import: image

After removing the dependency: image

Brownshome commented 1 year ago

I'm using the same fix as the example zip on my end:

plugins.withType(JextractPlugin).configureEach {
    configurations {
        implementation {
            dependencies.removeIf {
                it instanceof FileCollectionDependency
            }
        }
    }
}

This won't be viable as a long-term fix (as it breaks class output support), some options that I'll look into are:

I'm not sure class output will ever work in a Java module project without patching or something similar as I was under the understanding that modules had to be compiled as one unit, but I'm not 100% on that.

krakowski commented 1 year ago

Hi @Brownshome,

thanks for bringing this to my attention! I've never used Java modules inside a project before, so I wasn't aware of this. The bug you experience does also happen when using Gradle standalone via the console (without IntelliJ). I don't really know if this is a bug with Gradle. Adding the generated sources folder as a dependency shouldn't hide the module, in my opinion.

Ideally, I would like to enable/disable the inclusion of the dependency based on the sourceMode parameter here. The Task configuration is being read once the task gets executed, so (at the moment) I don't see a way of getting the sourceMode value at the referenced line.

The easiest fix would be to remove the class-mode feature from this plugin, which would allow to remove the dependency on the generated sources folder. There once was a discussion on the panama-dev mailing list about problems with jextract and class-mode : https://mail.openjdk.org/pipermail/panama-dev/2021-February/012096.html

I'm not sure class output will ever work in a Java module project without patching or something similar as I was under the understanding that modules had to be compiled as one unit, but I'm not 100% on that.

I also couldn't find any documentation on this. This is the only documentation I found on dependencies without support for modules: https://docs.gradle.org/current/userguide/java_library_plugin.html#using_libraries_that_are_not_modules

A third case are traditional libraries that provide no module information at all — for example commons-cli:commons-cli:1.4. Gradle puts such libraries on the classpath instead of the module path. The classpath is then treated as one module (the so called unnamed module) by Java.

Adding a manifest could fix this, but I don't really know if this works outside of JARs.

Others, like org.apache.commons:commons-lang3:3.10, may not offer a full module descriptor but will at least contain an Automatic-Module-Name entry in their manifest file to define the module’s name (org.apache.commons.lang3 in the example). Such modules, that only have a name as module description, are called automatic module that export all their packages and can read all modules on the module path.

Brownshome commented 1 year ago

I'd be happy to explore some of these options in a PR! (might be a week or so till I get some solid time to look at this again though).

Brownshome commented 10 months ago

Heh, took longer than a few weeks to get around to this, but better late than never!

See #19 for a PR