Achieve result of IntelliJ "Choose Sources" Dialog in Gradle
I am building extensions for a Java project (Ghidra) with a fairly complicated system of Gradle files. IntelliJ picks up the dependency jars properly, but every time a `.class` file is opened (e.g. during debugging) IntelliJ presents the banner at the top stating:
`Decompiled .class file, bytecode version: 55.0 (Java 11) Choose Sources... `
`Choose Sources` opens the dialog to select the sources, and the `*-src.zip` that is always right next to the `*.jar` file can be selected to add the sources. This can also be done via the project settings.
When adding the `*-src.zip` via the Project Settings there is an explicit warning: `A Library is imported from Gradle. Any changes made in its configuration might be lost after reimporting.`. This behavior is still the case when using `Choose Sources`, there is just no warning.
### Core question
How do I add the sources to Gradle configuration in a way that IntelliJ (or any other IDE) recognizes automatically? I.e. what is the Gradle directive that achieves what the `Choose Sources` dialog in IntelliJ IDEA does and is applied every time the Gradle project is reloaded?
The way the dependencies are declared in a Gradle file, that is included in the actual `build.gradle`, in this way:
dependencies {
api fileTree(dir: ghidraDir + '/Framework', include: "**/*.jar")
}
### Attempts
My first attempt was to change this to
api fileTree(dir: ghidraDir + '/Framework', includes: ["**/*.jar", "**/*-src.zip"])
But this adds the zip as a separate archive file in IntelliJ, and not as the sources for a dependency jar.
### Gradle code for Eclipse
The Gradle code that seems to achieve the same result for Eclipse looks like the following, specifically the `entry.setSourcePath`
eclipse {
classpath {
downloadJavadoc = true
downloadSources = true
file {
whenMerged {
File javaDoc = new File(ghidraInstallDir+"/docs/GhidraAPI_javadoc.zip");
for (entry in entries) {
if (entry.path.contains('jar')) {
File folder = new File(entry.getPath()).getParentFile();
for (File file : folder.listFiles()) {
if (file.getName().endsWith(".zip")) {
if (file.getName().contains("-src")) {
entry.setSourcePath(it.fileReference(file));
}
entry.setJavadocPath(it.fileReference(javaDoc));
}
}
}
}
entries.add(
new org.gradle.plugins.ide.eclipse.model.Library(
it.fileReference(new File(projectDir, '/bin'))
)
)
}
}
}
}
Please sign in to leave a comment.
Sounds like IDEA-231254 Gradle import does not resolve sources and javadoc when using a project lib directory
Please try if adding it as a directory works:
Also try
The underlying project/framework I am writing plugins for doesn't have a flat dir with all the jars, they are spread over a many directories/modules, so the first suggestion isn't really applicable in a way that is obvious to me.
adding `downloadSources = True` doesn't seem to do anything either. What behavior is activated by that? The sources are not downloadable anywhere, but they are already in the zip files right next to each .jar. Would it be possible to port the same logic as in the eclipse specific logic to IntelliJ? I can work with having to add that snippet to each `build.gradle` that uses the underlying framework
>adding `downloadSources = True` doesn't seem to do anything either. What behavior is activated by that?
It ensures that if there are sources packaged with the artifact, it will be attached to IDE. But, actually, Gradle by default loads the sources already.
It looks like the issue here is that the sources do not have standard format for the repository packaging. Please feel free to file a request about it.
To clarifiy: What do you mean by "the sources do not have standard format"? If I open the archive via the `Choose Sources` dialog it works, so am I understanding you correctly that the naming scheme is the issue? I.e. renaming the sources for a `foobar.jar` from `foobar-src.zip` to `foobar-sources.zip` should work?
Yes, maybe it worths trying naming like <file-name>.jar and <file-name>-sources.jar.