Commit ee47652
authored
[build] Add support for JDK 21 (#1287)
Context: 5bb0d24
Context: 4273e5c
Context: 0355acf
Context: dotnet/android#9651
Does dotnet/android build with JDK-21? We don't know! But in order
to answer that question, dotnet/java-interop needs to be able to
build under JDK-21; a'la 5bb0d24:
1. [Install JDK-21][0]
2. Run `dotnet build -t:Prepare`, overriding `$(JdksRoot)` to refer
to the JDK-21 installation directory:
dotnet build -t:Prepare Java.Interop.sln -p:JdksRoot=/Library/Java/JavaVirtualMachines/microsoft-21.jdk/Contents/Home
3. Build: `dotnet build`
Unfortunately, this *fails* for three reasons:
1. `class-parse` crashes when processing JDK-21's `java.base.jmod`.
2. `src/Java.Base` needs updates to bind JDK-21's `java.base.jmod`.
3. On Linux and Windows, Gradle 8.1 and JDK-21 don't mix.
~~ class-parse ~~
This only impacts Debug builds of dotnet/java-interop, but:
% dotnet "bin/Debug-net8.0/class-parse.dll" \
"$HOME/android-toolchain/jdk-21/jmods/java.base.jmod" \
"-o=obj/Debug-net8.0//mcw/api.xml"
…
Process terminated. Assertion failed.
Unexpected number of method parameters in `Ljdk/internal/org/objectweb/asm/commons/JSRInlinerAdapter$Instantiation;.get(Ljava/lang/Object;)Ljava/lang/Object;`: expected 1, got 0
at Xamarin.Android.Tools.Bytecode.MethodInfo.UpdateParametersFromMethodParametersAttribute(ParameterInfo[] parameters) in …/src/Xamarin.Android.Tools.Bytecode/Methods.cs:line 308
…
The assertion?
var pinfo = methodParams.ParameterInfo;
int startIndex = 0;
while (startIndex < pinfo.Count &&
pinfo [startIndex].AccessFlags.HasFlag (.Synthetic))
startIndex++;
Debug.Assert (parameters.Length == pinfo.Count - startIndex, …);
This is part of 4273e5c and 0355acf, attempting to "skip over" the
constructor parameters which non-static inner classes have which
contain the outer class instance:
// Java
class Outer {
/* non-static */ class Inner {
public Inner () { … }
}
}
At the ABI boundary, the `Outer.Inner` constructor is actually:
// "Equivalent" Java for JNI purposes
/* partial */ class Outer {
/* partial */ class Inner {
public Inner (Outer outer) { … } // note added constructor parameter
}
}
and we need to skip over the first parameter.
Which brings us to
`jdk.internal.org.objectweb.asm.commons.JSRInlinerAdapter.Instantiation.get()`:
% mkdir _x
% unzip $HOME/android-toolchain/jdk-21/jmods/java.base.jmod -d _x
% dotnet bin/Debug-net8.0/class-parse.dll --dump \
_x/classes/jdk/internal/org/objectweb/asm/commons/JSRInlinerAdapter\$Instantiation.class
…
8: get (Ljava/lang/Object;)Ljava/lang/Object; Public, Bridge, Synthetic
Code(6, Unknown[LineNumberTable](6), LocalVariableTableAttribute(LocalVariableTableEntry(Name='this', Descriptor='Ljdk/internal/org/objectweb/asm/commons/JSRInlinerAdapter$Instantiation;', StartPC=0, Index=0)))
MethodParametersAttribute(MethodParameterInfo(Name='', AccessFlags=Final, Synthetic))
The parameter for `JSRInlinerAdapter.Instantiation.get(Object)` is
`Synthetic`, causing us to skip over it, which is why we have a
parameter mismatch. The thing is, this parameter *shouldn't* be
skipped; the skipping is intended for *constructor* parameters!
Update the code so that the loop only occurs for constructors.
This allows `class-parse` to *not assert*, allowing `src/Java.Base`
to build.
~~ Gradle ~~
Via dotnet/android#9651, `gradle` fails when building
`tools/java-source-utils`, but only on Linux and Windows:
"/mnt/vss/_work/1/s/xamarin-android/external/Java.Interop/build-tools/gradle/gradlew" -d --stacktrace --no-daemon -PjavaSourceVer=11 -PjavaTargetVer=11 jar
…
[org.gradle.internal.buildevents.BuildExceptionReporter]
[org.gradle.internal.buildevents.BuildExceptionReporter] FAILURE: Build failed with an exception.
[org.gradle.internal.buildevents.BuildExceptionReporter]
[org.gradle.internal.buildevents.BuildExceptionReporter] * What went wrong:
[org.gradle.internal.buildevents.BuildExceptionReporter] Could not open settings generic class cache for settings file '/mnt/vss/_work/1/s/xamarin-android/external/Java.Interop/tools/java-source-utils/settings.gradle' (/home/cloudtest/.gradle/caches/8.1.1/scripts/aiw0k2bokig45bv5yvkog3o3j).
[org.gradle.internal.buildevents.BuildExceptionReporter] > BUG! exception in phase 'semantic analysis' in source unit '_BuildScript_' Unsupported class file major version 65
[org.gradle.internal.buildevents.BuildExceptionReporter]
[org.gradle.internal.buildevents.BuildExceptionReporter] * Try:
[org.gradle.internal.buildevents.BuildExceptionReporter] > Run with --scan to get full insights.
[org.gradle.internal.buildevents.BuildExceptionReporter]
[org.gradle.internal.buildevents.BuildExceptionReporter] * Exception is:
[org.gradle.internal.buildevents.BuildExceptionReporter] org.gradle.cache.CacheOpenException: Could not open settings generic class cache for settings file '/mnt/vss/_work/1/s/xamarin-android/external/Java.Interop/tools/java-source-utils/settings.gradle' (/home/cloudtest/.gradle/caches/8.1.1/scripts/aiw0k2bokig45bv5yvkog3o3j).
[org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.cache.internal.DefaultPersistentDirectoryStore.open(DefaultPersistentDirectoryStore.java:91)
[org.gradle.internal.buildevents.BuildExceptionReporter] …
[org.gradle.internal.buildevents.BuildExceptionReporter] Caused by: BUG! exception in phase 'semantic analysis' in source unit '_BuildScript_' Unsupported class file major version 65
[org.gradle.internal.buildevents.BuildExceptionReporter] at org.gradle.groovy.scripts.internal.DefaultScriptCompilationHandler.compileScript(DefaultScriptCompilationHandler.java:147)
[org.gradle.internal.buildevents.BuildExceptionReporter] …
[org.gradle.internal.buildevents.BuildExceptionReporter] Caused by: java.lang.IllegalArgumentException: Unsupported class file major version 65
[org.gradle.internal.buildevents.BuildExceptionReporter] at groovyjarjarasm.asm.ClassReader.<init>(ClassReader.java:199)
🤔
As per the [Gradle Compatibility Matrix][1], Java 21 requires
Gradle 8.5 or later. (No idea why this works on macOS…)
Bump to Gradle 8.12, which is the current latest stable version.
~~ TODO ~~
While dotnet/java-interop now *builds* with JDK-21, unit tests don't
fully pass. In particular,
`tests/Xamarin.Android.Tools.Bytecode-Tests` will need to be updated
because `javac` output has changed. (Again.)
[0]: https://learn.microsoft.com/en-us/java/openjdk/download#openjdk-21
[1]: https://docs.gradle.org/8.12/userguide/compatibility.html1 parent fe00cef commit ee47652
File tree
5 files changed
+57
-5
lines changed- build-tools/gradle/gradle/wrapper
- src
- Java.Base/Java.Lang
- Xamarin.Android.Tools.Bytecode
5 files changed
+57
-5
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
7 | 17 | | |
8 | 18 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
7 | 17 | | |
8 | 18 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
300 | 300 | | |
301 | 301 | | |
302 | 302 | | |
303 | | - | |
304 | | - | |
305 | | - | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
306 | 307 | | |
307 | 308 | | |
308 | 309 | | |
309 | 310 | | |
310 | | - | |
| 311 | + | |
| 312 | + | |
311 | 313 | | |
312 | 314 | | |
313 | 315 | | |
| |||
0 commit comments