Closed jpenilla closed 9 months ago
Sadly I can not reproduce this with an up to date MDK. With our without that plugin.
I am still able to reproduce with a fresh clone of the MDK and adding the plugin:
┌─jason@jason-pc ~/temp
└─➤ git clone git@github.com:neoforged/MDK.git
Cloning into 'MDK'...
remote: Enumerating objects: 674, done.
remote: Counting objects: 100% (674/674), done.
remote: Compressing objects: 100% (306/306), done.
remote: Total 674 (delta 208), reused 627 (delta 175), pack-reused 0
Receiving objects: 100% (674/674), 181.32 KiB | 937.00 KiB/s, done.
Resolving deltas: 100% (208/208), done.
┌─jason@jason-pc ~/temp
└─➤ cd MDK
┌─jason@jason-pc ~/temp/MDK ‹main›
└─➤ ./gradlew build
To honour the JVM settings for this build a single-use Daemon process will be forked. See https://docs.gradle.org/8.1.1/userguide/gradle_daemon.html#sec:disabling_the_daemon.
Daemon will be stopped at the end of the build
> Task :neoFormApplyForgesAccessTransformer
[10:07:24] [main/INFO]: Access Transformer processor running version 8.0.7+8.0.7+master.43473d43
[10:07:24] [main/INFO]: Command line arguments [--inJar, /home/jason/temp/MDK/build/neoForm/neoFormJoined1.20.2-20231019.002635/steps/rename/output.jar, --outJar, /home/jason/temp/MDK/build/neoForm/neoFormJoined1.20.2-20231019.002635/steps/applyForgesAccessTransformer/output.jar, --atFile, /home/jason/temp/MDK/build/neoForm/neoFormJoined1.20.2-20231019.002635/accesstransformers/Forges/_script_neoforge.cfg, --atFile, /home/jason/temp/MDK/build/neoForm/neoFormJoined1.20.2-20231019.002635/accesstransformers/Forges/accesstransformer.cfg]
[10:07:24] [main/INFO]: Reading from /home/jason/temp/MDK/build/neoForm/neoFormJoined1.20.2-20231019.002635/steps/rename/output.jar
[10:07:24] [main/INFO]: Writing to /home/jason/temp/MDK/build/neoForm/neoFormJoined1.20.2-20231019.002635/steps/applyForgesAccessTransformer/output.jar
[10:07:24] [main/INFO]: Transformer file /home/jason/temp/MDK/build/neoForm/neoFormJoined1.20.2-20231019.002635/accesstransformers/Forges/_script_neoforge.cfg
[10:07:24] [main/INFO]: Transformer file /home/jason/temp/MDK/build/neoForm/neoFormJoined1.20.2-20231019.002635/accesstransformers/Forges/accesstransformer.cfg
[10:07:24] [main/WARN]: Found existing output jar /home/jason/temp/MDK/build/neoForm/neoFormJoined1.20.2-20231019.002635/steps/applyForgesAccessTransformer/output.jar, overwriting
[10:07:26] [main/INFO]: JAR transformation complete /home/jason/temp/MDK/build/neoForm/neoFormJoined1.20.2-20231019.002635/steps/applyForgesAccessTransformer/output.jar
> Task :neoFormRecompile
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use or override a deprecated API that is marked for removal.
Note: Recompile with -Xlint:removal for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
BUILD SUCCESSFUL in 1m 53s
35 actionable tasks: 35 executed
┌─jason@jason-pc ~/temp/MDK ‹main›
└─➤ vim build.gradle
┌─jason@jason-pc ~/temp/MDK ‹main*›
└─➤ git diff HEAD | cat && git status
diff --git a/build.gradle b/build.gradle
index 5eec844..1fe341e 100644
--- a/build.gradle
+++ b/build.gradle
@@ -4,6 +4,7 @@ plugins {
id 'idea'
id 'maven-publish'
id 'net.neoforged.gradle.userdev' version '7.0.5'
+ id("org.gradlex.java-ecosystem-capabilities") version "1.3.1"
}
version = mod_version
On branch main
Your branch is up to date with 'origin/main'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: build.gradle
no changes added to commit (use "git add" and/or "git commit -a")
┌─jason@jason-pc ~/temp/MDK ‹main*›
└─➤ ./gradlew build
To honour the JVM settings for this build a single-use Daemon process will be forked. See https://docs.gradle.org/8.1.1/userguide/gradle_daemon.html#sec:disabling_the_daemon.
Daemon will be stopped at the end of the build
> Task :neoFormApplyForgesAccessTransformer
[10:10:05] [main/INFO]: Access Transformer processor running version 8.0.7+8.0.7+master.43473d43
[10:10:05] [main/INFO]: Command line arguments [--inJar, /home/jason/temp/MDK/build/neoForm/neoFormJoined1.20.2-20231019.002635/steps/rename/output.jar, --outJar, /home/jason/temp/MDK/build/neoForm/neoFormJoined1.20.2-20231019.002635/steps/applyForgesAccessTransformer/output.jar, --atFile, /home/jason/temp/MDK/build/neoForm/neoFormJoined1.20.2-20231019.002635/accesstransformers/Forges/_script_neoforge.cfg, --atFile, /home/jason/temp/MDK/build/neoForm/neoFormJoined1.20.2-20231019.002635/accesstransformers/Forges/accesstransformer.cfg]
[10:10:05] [main/INFO]: Reading from /home/jason/temp/MDK/build/neoForm/neoFormJoined1.20.2-20231019.002635/steps/rename/output.jar
[10:10:05] [main/INFO]: Writing to /home/jason/temp/MDK/build/neoForm/neoFormJoined1.20.2-20231019.002635/steps/applyForgesAccessTransformer/output.jar
[10:10:05] [main/INFO]: Transformer file /home/jason/temp/MDK/build/neoForm/neoFormJoined1.20.2-20231019.002635/accesstransformers/Forges/_script_neoforge.cfg
[10:10:05] [main/INFO]: Transformer file /home/jason/temp/MDK/build/neoForm/neoFormJoined1.20.2-20231019.002635/accesstransformers/Forges/accesstransformer.cfg
[10:10:05] [main/WARN]: Found existing output jar /home/jason/temp/MDK/build/neoForm/neoFormJoined1.20.2-20231019.002635/steps/applyForgesAccessTransformer/output.jar, overwriting
[10:10:07] [main/INFO]: JAR transformation complete /home/jason/temp/MDK/build/neoForm/neoFormJoined1.20.2-20231019.002635/steps/applyForgesAccessTransformer/output.jar
> Task :neoFormRecompile FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':neoFormRecompile'.
> Could not resolve all files for configuration ':detachedConfiguration2'.
> Could not resolve com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava.
Required by:
project :
> Module 'com.google.guava:listenablefuture' has been rejected:
Cannot select module with conflict on capability 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava' also provided by [com.google.guava:guava:31.1-jre(runtime)]
> Could not resolve com.google.guava:guava:31.1-jre.
Required by:
project :
> Module 'com.google.guava:guava' has been rejected:
Cannot select module with conflict on capability 'com.google.guava:listenablefuture:1.0' also provided by [com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava(runtime)]
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 1m 11s
30 actionable tasks: 30 executed
┌─jason@jason-pc ~/temp/MDK ‹main*›
└─➤ git remote show origin 1 ↵
* remote origin
Fetch URL: git@github.com:neoforged/MDK.git
Push URL: git@github.com:neoforged/MDK.git
HEAD branch: main
Remote branches:
features/20.2 tracked
main tracked
Local branch configured for 'git pull':
main merges with remote main
Local ref configured for 'git push':
main pushes to main (up to date)
┌─jason@jason-pc ~/temp/MDK ‹main*›
└─➤ git fetch origin && git status
On branch main
Your branch is up to date with 'origin/main'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: build.gradle
no changes added to commit (use "git add" and/or "git commit -a")
┌─jason@jason-pc ~/temp/MDK ‹main*›
└─➤
What is this com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
that is mentioned in your log, @jpenilla?
It's a dummy dependency for a change in guava a while ago, as mentioned in the Guava readme.
This issue can be reproduced by running gradlew resolveConf
with the following simple build script:
plugins {
id 'java'
id 'java-library'
id 'org.gradlex.java-ecosystem-capabilities' version "1.3.1"
}
repositories {
mavenCentral()
maven {
name = "neoforge"
url = "https://maven.neoforged.net/releases"
}
}
tasks.register("resolveConf") {
it.doFirst {
def conf = configurations.detachedConfiguration()
def addDep = { conf.dependencies.add(dependencies.create it) }
addDep "net.neoforged:JarJarMetadata:0.4.0"
addDep "com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava"
conf.resolve().each { file ->
println(file)
}
}
}
I don't think we are to blame for this?
Interestingly, the following works:
dependencies {
implementation "net.neoforged:JarJarMetadata:0.4.0"
implementation "com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava"
}
tasks.register("resolveConf") {
it.doFirst {
configurations.runtimeClasspath.resolve().each { file ->
println(file)
}
}
}
This issue can be reproduced by running
gradlew resolveConf
with the following simple build script:plugins { id 'java' id 'java-library' id 'org.gradlex.java-ecosystem-capabilities' version "1.3.1" } repositories { mavenCentral() maven { name = "neoforge" url = "https://maven.neoforged.net/releases" } } tasks.register("resolveConf") { it.doFirst { def conf = configurations.detachedConfiguration() def addDep = { conf.dependencies.add(dependencies.create it) } addDep "net.neoforged:JarJarMetadata:0.4.0" addDep "com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava" conf.resolve().each { file -> println(file) } } }
I don't think we are to blame for this?
Those two dependencies are added by NeoGradle as they are listed in the userdev config. As mentioned in the original issue I am not sure whether the problem is with NG or NF, but I am quite sure it's something in the neo toolchain, as I don't run into this problem with any other modding platform. For now I can get my project to build by forcing Gradle to ignore the conflicting dependencies:
dependencies {
components.withModule(GuavaListenableFutureRule.MODULES[0]) {
// Ad-hoc rule to revert the effect of 'GuavaListenableFutureRule' (NeoForge has broken dependencies)
allVariants {
withCapabilities {
removeCapability(GuavaListenableFutureRule.CAPABILITY_GROUP, GuavaListenableFutureRule.CAPABILITY_NAME)
}
}
}
}
fwiw, this issue also presents itself when consuming NF with archloom, so if the issue is on the NG side then it would likely be with the userdev config creation.
The two dependencies are seemingly perfectly legal. Just because the issue happens with NG doesn't mean that NG is to blame. Please check the POM of JarJarMetadata and you'll see that it looks normal.
This issue only happens for detached configurations as far as I can tell, which points to an issue with the java ecosystem plugin IMO.
I think this has something to do with the dependency tree getting flattened, see https://github.com/gradlex-org/java-ecosystem-capabilities/blob/main/src/main/java/org/gradlex/javaecosystem/capabilities/rules/GuavaListenableFutureRule.java
The example you gave that "works" actually doesn't, it just doesn't error, see ./gradlew dependencies
:
runtimeClasspath - Runtime classpath of source set 'main'.
+--- net.neoforged:JarJarMetadata:0.4.0
| +--- org.apache.maven:maven-artifact:3.8.1
| | +--- org.codehaus.plexus:plexus-utils:3.2.1
| | \--- org.apache.commons:commons-lang3:3.8.1
| +--- com.google.code.gson:gson:2.8.5
| +--- com.google.guava:guava:31.0.1-jre -> com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
| +--- com.machinezoo.noexception:noexception:1.7.1
| | \--- org.slf4j:slf4j-api:1.7.30
| \--- org.slf4j:slf4j-api:1.7.30
\--- com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
It seems like java-ecosystem-capabilities
(reasonably) doesn't expect users to declare an explicit dependency on com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
. The difference between detached and normal configurations is definitely strange though... it might be an issue with Gradle itself, although probably worth raising an issue at java-ecosystem-capabilities
for discussion.
As far as a solution to this specific issue though, I think simply filtering com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
out of dependency lists written to userdev & other configs is sensible (since changes to not flatten the tree would be non-trivial). Alternatively applying java-ecosystem-capabilities
to NeoForge might also solve this?
Hmmm, what is the problem with that runtimeClasspath
? It looks normal to me but I might be missing something?
The empty workaround jar is being selected over Guava.
The empty workaround jar is being selected over Guava.
Which can have many reasons. Including but not limited to externally declared module metadata over which we have no control
OK. What is happening here is that NG is writing the full resolved contents of its installer
configuration into the userdev jsons (you can check that the userdev jar contains this 9999 guava listenablefuture dependency), and then that gets written to a configuration userdev dependency. This one specifically: https://github.com/neoforged/NeoGradle/blob/ae319cfb8e74eb2894717b1fc41b88df9fdd23d9/userdev/src/main/java/net/neoforged/gradle/userdev/runtime/extension/UserDevRuntimeExtension.java#L84
I don't really see a different way of doing this for us. If we do not flatten the configuration then we risk a version mismatch in the run arguments...
IMO this is a problem with the way the capability is declared for com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
. The simple example that I give should just work out of the box, and the fact that it does not points to an issue in the ecosystem plugin IMO. Possibly also an issue with Gradle because it should error given that the guava capability is missing. But this is not really our problem...
Not sure whether this should be reported here or to NeoForge, but the
org.gradlex.java-ecosystem-capabilities
plugin reveals a problem with the dependency graph of something in the toolchain.The 1.20.2 MDK branch did not build for me locally, I made this change to get it building (not sure what exactly fixed it, but this is not the focus of the issue anyways):
Then when I add the
org.gradlex.java-ecosystem-capabilities
plugin to detect and enforce resolution of capability conflicts:I end up with the following error when invoking
./gradlew build
: