Slackbot
01/25/2024, 3:47 PMFuyang Liu
01/25/2024, 3:52 PMCould not determine the dependencies of task ':b:compileJava'.
> Could not resolve all task dependencies for configuration ':b:compileClasspath'.
> Could not resolve project :a.
Required by:
project :b
> No matching variant of project :a was found. The consumer was configured to find a library for use during compile-time, compatible with Java 8, preferably in the form of class files, preferably optimized for standard JVMs, and its dependencies declared externally but:
- Variant 'apiElements' capability com.x:a:1.0.0 declares a library for use during compile-time, packaged as a jar, and its dependencies declared externally:
- Incompatible because this component declares a component, compatible with Java 11 and the consumer needed a component, compatible with Java 8
- Other compatible attribute:
- Doesn't say anything about its target Java environment (preferred optimized for standard JVMs)Vampire
01/25/2024, 4:34 PMFuyang Liu
01/26/2024, 12:11 AMVampire
01/26/2024, 1:13 AMFuyang Liu
01/26/2024, 8:23 AMtasks.withType<JavaCompile> {
sourceCompatibility = "8"
targetCompatibility = "11"
}
Thanks, I tried to just set it as this on B, but seems not working.
Compliance level '1.8' is incompatible with target level '11'. A compliance level '11' or better is requiredVampire
01/26/2024, 9:44 AMVampire
01/26/2024, 9:51 AMFuyang Liu
01/26/2024, 10:14 AMFuyang Liu
01/26/2024, 10:24 AMFuyang Liu
01/26/2024, 10:31 AMtargetCompatibility = "11"
options.compilerArgs = listOf("-source", "1.8")
If I just set like this, I got this error:
duplicate source compliance setting specification: 1.8
So apparently those config is given to the compiler...Vampire
01/26/2024, 11:38 AMFuyang Liu
01/26/2024, 11:47 AMVampire
01/26/2024, 12:19 PMcompileClasspath on B to request Java 11 compatible stuff instead of Java 8 compatible stuff.Vampire
01/26/2024, 12:20 PMrelease instead as it then also ensures the right API is used to compile against.Fuyang Liu
01/26/2024, 3:06 PMplugins {
java
id("io.github.themrmilchmann.ecj") // for using eclipse compiler - <https://stackoverflow.com/questions/3061654/what-is-the-difference-between-javac-and-the-eclipse-compiler>
}
java {
toolchain.languageVersion.set(JavaLanguageVersion.of(11))
toolchain.vendor.set(JvmVendorSpec.ADOPTIUM)
}
ecj {
compilerGroupId.set("org.eclipse.jdt")
compilerArtifactId.set("ecj")
compilerVersion.set("3.36.0")
}
Then those apply both to A and B, but in B I am adding some extra such as:
b:
plugins {
id("p-java-library") // local convention plugin
}
dependencies {
implementation(project(":A"))
}
tasks.withType<JavaCompile> {
sourceCompatibility = "8"
targetCompatibility = "8"
}
Then I got the error on the top of the project.Vampire
01/26/2024, 3:28 PMconfigurations.compileClasspath {
attributes.attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 11)
}
on BFuyang Liu
01/26/2024, 3:42 PMList.of() in a file in B. But, the Intellij somehow fetch correct info and can show me the List.of() is Java9 api and gives me an error.
I guess this will serve as a solution for me.Fuyang Liu
01/26/2024, 3:45 PMjava -jar ecj-4.30.jar A.java -source 1.8 -target 11
Compliance level '1.8' is incompatible with target level '11'. A compliance level '11' or better is requiredFuyang Liu
01/26/2024, 3:50 PMFuyang Liu
01/26/2024, 4:01 PMcompileOnly(project(":A")) in B, otherwise, for example using "implementation", it still cannot work :)Vampire
01/26/2024, 4:04 PMWoo... It's a bit difficult to understand for now but somehow it does make it compilesA has that attribute set to 11 B requests this attribute to be at most 8 thus it fails Now you tell B "request it to be at most 11" and the resolution error disappears And as you are actually using a Java 11 compiler, the compiler can read the Java 11 classes of A
However, the interesting fact seems to be, the compile will NOT fail in this case if I writeThat's why I said you should usein a file in B.List.of()
release if you need source and target to be the same, because with release you additionally tell the compiler to compile against the according API and prevent using newer API or breakingly changed API.
If you for example just set source compatibility to 8 with the normal compiler, you get a warning that you did not also set the bootstrap classpath from a Java 8 JDK which would also serve the same purpose.Vampire
01/26/2024, 4:05 PMOh by the way, looks like I need to setWell, if you for something use thein B, otherwise, for example using "implementation", it still cannot work πcompileOnly(project(":A"))
runtimeClasspath, you again have the same problem and could use the same work-around.Vampire
01/26/2024, 4:06 PMVampire
01/26/2024, 4:06 PMVampire
01/26/2024, 4:07 PMFuyang Liu
01/26/2024, 4:08 PMrelease and learned it is different from setting both -source and -target. Good input.
options.release = 8 works perfect.Fuyang Liu
01/26/2024, 4:22 PMFuyang Liu
01/26/2024, 4:50 PMFuyang Liu
01/26/2024, 4:51 PMVampire
01/26/2024, 4:53 PMWhat if I have some main method in a class on B that people use locally to generate some stuff, and it does depend on AIf it needs to run on Java 8, you are lost as A requires Java 11 to run.
Fuyang Liu
01/27/2024, 9:44 AMVampire
01/27/2024, 12:13 PMcompileOnly that basically is what some call provided. It means if you need it at runtime, you have to supply it manuallyFuyang Liu
01/28/2024, 4:59 PM