This message was deleted.
# community-support
s
This message was deleted.
t
Have you tried reading the code of the wrapper?
org.gradle.wrapper.GradleUserHomeLookup#gradleUserHome
might be the answer. This must be documented somewhere too, but couldn't find it with a quick search. Tip: right click the gradle-wrapper.jar and add as library, then you can expand and browse the classes. Alternatively: https://github.com/gradle/gradle/blob/master/platforms/core-runtime/wrapper-shared/src/main/java/org/gradle/wrapper/GradleUserHomeLookup.java
Gradle User Home is well-documented though: https://docs.gradle.org/current/userguide/directory_layout.html
r
This is Gradle user home, not the Gradle installation directory
I'm asking about the latter
t
Do you mean the folder within the
dists
folder?
r
I mean
GRADLE_HOME
in
$GRADLE_HOME/bin/gradle
I've been chasing down an issue involving custom Gradle distributions and TestKit
In other words, I have multiple installations of Gradle 8.5 that are materially different, because they have different
init.d/
directory contents, and I need much better visibility than I currently have into how Gradle distinguishes different Gradle installations
t
I still think it's the same as wrapper dists, because if you look in there, there are many "Gradle installations", but not for the same version.
r
Yeah, there's a few related concepts here
t
how do you tell it to use a specific installation?
r
There's daemon compatibility, there's the
distributionSha256Sum
that seems to appear in the wrapper dists' paths, there's the
APP_HOME
environment variable that the
bin/gradle
script seems very concerned with figuring out
how do you tell it to use a specific installation?
You run the
bin/gradle
script from that installation. That's the only place where I've been able to find code that is clearly concerned with locating the Gradle installation directory (for the current distribution)
t
so that's it then, I think all that script is doing is essentially GRADLE_HOME=
bin/..
but in a really roundabout way 🙂
r
And I had an issue where TestKit was launching vanilla Gradles to test a plugin, instead of launching the same custom distribution. That turned out to be an issue with how the custom distribution was packaged, and how
bin/gradle
resolves symlinks
What's frustrating is that there's zero logging around any of this
t
APP_HOME is only used for
CLASSPATH=$APP_HOME/lib/gradle-launcher-8.5.jar
and wrapper is doing something similar
r
And I still haven't been able to locate a smoking gun, in the form of an environment variable, Gradle property, or system property that gets relayed from a client to a daemon. It has to be somewhere!
I noticed that if you
java -jar .../gradle-launcher-8.5.jar
it locates the Gradle installation where that jar file lives, no matter which working directory you run
java
in. Which suggests that this information is effectively baked into the classpath
That, in turn, raises questions about
distributionSha256Sum
-- you can't distinguish a Gradle installation by the SHA256 of its classpath, because the same jar files could live in different locations
t
The wrapper uses
Copy code
GradleWrapperMain.class.getProtectionDomain().getCodeSource().getLocation()
to locate itself.
r
Simplicity itself!!!!!!
t
this is then used to read wrapper propes, and gradle.properties
r
Is this code path specific to the generated `./gradlew`/`gradlew.bat`?
I don't understand
bin/gradle
to be a "gradle wrapper" technically speaking
t
yeah, that looks different
gradlew bat is a launcher for gradle-wrapper.jar, which downloads gradle to
dists
and then launches it, so I think yes.
Here are all the classes that contain
getProtectionDomain
(you can probably find the same in the gradle repo too)
strangely this list doesn't contain launcher jar
r
See, I'm growing concerned that this is actually undefined behavior, particularly if you don't go through a wrapper
t
If I were you I would do
GRADLE_OPTS=<... the usual debugger attach params for Java> some/bin/gradle
and then attach a debugger with a breakpoint at
org.gradle.launcher.GradleMain
.
with a debugger you can see
System.getProperties()
and
getenv()
and follow through. I have a feeling it would quickly reach a point where it knows where it is.
r
I'm more worried about the Gradle instances launched by TestKit
I know there's a
GradleRunner
option that lets you provide a Gradle distribution to run. I suppose that if you don't set it, the default behavior is to use the "current" distribution
Does TestKit have its own pool of Gradle daemons, or can it reuse the common ones from the rest of the system?
t
ugh, that last one is hard 😄 Might worth it's own thread. There was a time when I went deep into debugging how testkit launches, but don't remember the particulars 😞
r
Copy code
File testKitDir = createTestKitDir(testKitDirProvider);

        GradleProvider effectiveDistribution = gradleProvider == null ? findGradleInstallFromGradleRunner() : gradleProvider;
🤔
Copy code
private static GradleProvider findGradleInstallFromGradleRunner() {
        GradleInstallation gradleInstallation = CurrentGradleInstallation.get();
Right there. That method is where debug logging should go
Copy code
/**
 * This marker is used to locate the "source" Gradle distribution at runtime.
 * See {@code CurrentGradleInstallationLocator}.
 */
@SuppressWarnings("unused")
public interface InstallationBeacon {
}
Copy code
abstract class CurrentGradleInstallationLocator {

    private static final String BEACON_CLASS_NAME = "org.gradle.internal.installation.beacon.InstallationBeacon";
😮
t
well
classpathutil
was the third in my list above
r
Ah, I see what you mean
I'm still not sure how this is modeled within Gradle, but I buy that it is
t
tip, you can set up a random project where you are able to compile classes against Gradle APIs. Then copy the source of the class you want to modify, compile it, and re-package the jar. This way you can add a single line of code to any class. (I did something similar here in the Workaround in OP: https://youtrack.jetbrains.com/issue/KTIJ-24936)
gtg, have fun!