-
Notifications
You must be signed in to change notification settings - Fork 528
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[build] Cursory JDK 9 support #1214
Conversation
@@ -0,0 +1,36 @@ | |||
<?xml version="1.0" encoding="utf-8"?> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any way we can merge these Xamarin.Android.BindingResolveImportLib*.targets
files into one? For the most part the BuildJar
and CleanJar
targets are identical.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. There is now a new build-tools/scripts/Jar.targets
file which contains a BuildTestJarFile
target. This takes the @(TestJarEntry)
item group -- which is assumed to contain Java source code -- compiles it with javac
, and then jar
s it into %(TestJarEntry.OutputFile)
. Through the joy of Target batching, this allows a project to fairly easily generate any number of output .jar
files without too much difficulty.
We have a VSTS+macOS build machine which has JDK 9 as the default JDK, thus causing *all* xamarin-android builds to fail, as `gradlew` and JDK 9 don't *directly* mix: Executing: ./gradlew assembleDebug --stacktrace ... org.gradle.api.ProjectConfigurationException: A problem occurred configuring project ':library'. ... Caused by: org.gradle.internal.event.ListenerNotificationException: Failed to notify project evaluation listener. ... Caused by: java.lang.NoClassDefFoundError: javax/xml/bind/annotation/XmlSchema ... Caused by: java.lang.ClassNotFoundException: javax.xml.bind.annotation.XmlSchema When using JDK 9, `gradlew` fails because *something* within it attempts to use the deprecated type `javax.xml.bind.annotation.XmlSchema`, and JDK 9 doesn't provide deprecated modules in the default `$CLASSPATH`. Knowing that the VSTS machine *also* has JDK 8 installed, we've tried to "filter out" JDK 9 so that it wouldn't be used; see e.g. a3c4358. Unfortunately that doesn't work, because on macOS the default JDK used is [always the JDK with the highest version number][macOS-jdk], and this can't be easily changed system-wide because changing this behavior requires "removing" a `Info.plist` file to prevent the JDK from being "seen" by `/usr/bin/java`: [macOS-jdk]: https://stackoverflow.com/a/44169445 # Don't use JDK 9 by default on macOS: $ cd /Library/Java/JavaVirtualMachines/jdk-9.0.4.jdk/Contents $ mv Info.plist Info.plist.disabled (Renaming `Info.plist.disabled` to `Info.plist` will restore JDK 9 as the default JDK on the machine.) A "proper" fix would presumably involve using and exporting `$JAVA_HOME` *everywhere*, which isn't currently the case. [This is something that *should* be explored.][xa-1213] [xa-1213]: dotnet#1213 In the meantime, a question: *Can* we build with JDK 9? *Is it even possible in the first place*? Turns out, *yes*, it *is* possible. The above `gradlew` error can be fixed by providing the (new-in-JDK9) `--add-modules` option, so that the `java.xml.bind` module is accessible: $ ANDROID_HOME=... JAVA_OPTS="--add-modules java.xml.bind" ./gradlew assembleDebug --stacktrace --no-daemon # ...works! Unfortunately, *other* parts xamarin-android get in the way, e.g. the `<ResolveSdks/>` task doesn't correctly parse the version number out of `java -version`, and JDK 9 `javac` requires `-source` and `-target` when `-bootclasspath` is used. Update the build system and tests so that things *can* be built under JDK 9. Additionally, cleanup the internal build system a bit: instead of having `javac` and `jar` calls strewn throughout *7* different projects -- all of which would need to be updated to provide usable `javac -source` and `javac -target` values (JDK 9 doesn't support `-target 1.6` anymore!), introduce `build-tools\scripts\Jar.targets` and the new `BuildTestJarFile` target. This takes all `@(TestJarEntry)` files, compiles them with `javac`, and `jar`s the compiled files into `%(TestJarEntry.OutputFile)`. **Note**: This does ***NOT*** mean that building and/or using JDK 9 will be commercially supported in *any* way. (It might not even work!)
We have a VSTS+macOS build machine which has JDK 9 as the default JDK, thus causing *all* xamarin-android builds to fail, as `gradlew` and JDK 9 don't *directly* mix: Executing: ./gradlew assembleDebug --stacktrace ... org.gradle.api.ProjectConfigurationException: A problem occurred configuring project ':library'. ... Caused by: org.gradle.internal.event.ListenerNotificationException: Failed to notify project evaluation listener. ... Caused by: java.lang.NoClassDefFoundError: javax/xml/bind/annotation/XmlSchema ... Caused by: java.lang.ClassNotFoundException: javax.xml.bind.annotation.XmlSchema When using JDK 9, `gradlew` fails because *something* within it attempts to use the deprecated type `javax.xml.bind.annotation.XmlSchema`, and JDK 9 doesn't provide deprecated modules in the default `$CLASSPATH`. Knowing that the VSTS machine *also* has JDK 8 installed, we've tried to "filter out" JDK 9 so that it wouldn't be used; see e.g. a3c4358. Unfortunately that doesn't work, because on macOS the default JDK used is [always the JDK with the highest version number][macOS-jdk], and this can't be easily changed system-wide because changing this behavior requires "removing" a `Info.plist` file to prevent the JDK from being "seen" by `/usr/bin/java`: [macOS-jdk]: https://stackoverflow.com/a/44169445 # Don't use JDK 9 by default on macOS: $ cd /Library/Java/JavaVirtualMachines/jdk-9.0.4.jdk/Contents $ mv Info.plist Info.plist.disabled (Renaming `Info.plist.disabled` to `Info.plist` will restore JDK 9 as the default JDK on the machine.) A "proper" fix would presumably involve using and exporting `$JAVA_HOME` *everywhere*, which isn't currently the case. [This is something that *should* be explored.][xa-1213] [xa-1213]: #1213 In the meantime, a question: *Can* we build with JDK 9? *Is it even possible in the first place*? Turns out, *yes*, it *is* possible. The above `gradlew` error can be fixed by providing the (new-in-JDK9) `--add-modules` option, so that the `java.xml.bind` module is accessible: $ ANDROID_HOME=... JAVA_OPTS="--add-modules java.xml.bind" ./gradlew assembleDebug --stacktrace --no-daemon # ...works! Unfortunately, *other* parts xamarin-android get in the way, e.g. the `<ResolveSdks/>` task doesn't correctly parse the version number out of `java -version`, and JDK 9 `javac` requires `-source` and `-target` when `-bootclasspath` is used. Update the build system and tests so that things *can* be built under JDK 9. Additionally, cleanup the internal build system a bit: instead of having `javac` and `jar` calls strewn throughout *7* different projects -- all of which would need to be updated to provide usable `javac -source` and `javac -target` values (JDK 9 doesn't support `-target 1.6` anymore!), introduce `build-tools\scripts\Jar.targets` and the new `BuildTestJarFile` target. This takes all `@(TestJarEntry)` files, compiles them with `javac`, and `jar`s the compiled files into `%(TestJarEntry.OutputFile)`. **Note**: This does ***NOT*** mean that building and/or using JDK 9 will be commercially supported in *any* way. (It might not even work!)
…Tasks (#6116) Context: https://discord.com/channels/732297728826277939/732297837953679412/865316625950572554 Context: https://discord.com/channels/732297728826277939/732297837953679412/869307441601470484 Changes: https://github.com/xamarin/monodroid/compare/b359d3b43774ff031add3d7a4949483052957db3...fb0d502139bc222d4e9ad82f912b1c6f1d4ca34e * xamarin/monodroid@fb0d50213: StrongName Xamarin.Android.Build.Debugging.Tasks (#1214) * xamarin/monodroid@71ac9a81b: Bump to xamarin/xamarin-android/main@4ea37883 (#1220) Occasionally when: 1. Building on Windows within Visual Studio, with 2. "Legacy" Xamarin.Android installed, and 3. A preview .NET for Android (net6.0 + Android) workload installed the build may fail: C:\Program Files\dotnet\packs\Microsoft.Android.Sdk.Windows\30.0.100-preview.6.62\tools\Xamarin.Android.Common.targets(512,7): error MSB4064: The "ManifestPlaceholders" parameter is not supported by the "GetAndroidPackageName" task loaded from assembly: Xamarin.Android.Build.Tasks, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null from the path: D:\Program Files\Microsoft Visual Studio\2022\Preview\MSBuild\Xamarin\Android\Xamarin.Android.Build.Tasks.dll. Verify that the parameter exists on the task, the <UsingTask> points to the correct assembly, and it is a settable public instance property. C:\Program Files\dotnet\packs\Microsoft.Android.Sdk.Windows\30.0.100-preview.6.62\tools\Xamarin.Android.Common.targets(509,3): error MSB4063: The "GetAndroidPackageName" task could not be initialized with its input parameters. The root cause of the problem is that *both* "Legacy" Xamarin.Android and .NET SDK for Android contain a non-strong-named `Xamarin.Android.Build.Tasks.dll`, and if a Project Solution `.sln` contains Projects `.csproj` which reference both SDKs, then `Xamarin.Android.Build.Tasks.dll` will only be loaded *once*, which will be incompatible with the other. In the above error message, the legacy `Xamarin.Android.Build.Tasks.dll` was loaded first, causing the build to fail when trying to build the .NET SDK for Android project. There are three ways to solve this: 1. Maintain API compatibility between Legacy & .NET 6+ 2. Use different assembly names between "Legacy" and .NET 6+, or 3. [Strong-name][0] all MSBuild-related assemblies. (1) is a non-starter; new or different functionality is introduced as part of .NET SDK for Android. The assemblies can't be API compatible. We could solve via (2) by renaming the .NET SDK for Android assembly to e.g. `Microsoft.Android.Build.Tasks.dll`, but this only delays the problem; come .NET 7, we'll still have the same assembly name for two different installation locations (.NET 6, .NET 7), and they won't be compatible with each other. Which leaves (3): we strong-name our MSBuild assemblies. Strong-naming allows us to have different versions installed "side by side" (Legacy and .net 6) in separate directories. Strong-naming is the best solution to this issue. A few notes though. 1. `pdb2mdb.exe` is now ILRepacked into `Xamarin.Android.Build.Tasks` via [`ILRepack`][1], as it is not Strong-named. See also 610ade7. 2. The `Xamarin.Android.Build.Tasks.csproj` project itself is *NOT* StrongNamed. This is because `pdb2mdb.exe` is not either. We handle the StrongNaming via the `ILRepacker` target later in the build. The end result is a Strong-named `Xamarin.Android.Build.Tasks.dll`. Co-authored-by: Jonathan Peppers <[email protected]> [0]: https://docs.microsoft.com/en-us/dotnet/standard/assembly/strong-named [1]: https://www.nuget.org/packages/ILRepack/
We have a VSTS+macOS build machine which has JDK 9 as the default JDK,
thus causing all xamarin-android builds to fail, as
gradlew
andJDK 9 don't directly mix:
When using JDK 9,
gradlew
fails because something within itattempts to use the deprecated type
javax.xml.bind.annotation.XmlSchema
, and JDK 9 doesn't providedeprecated modules in the default
$CLASSPATH
.Knowing that the VSTS machine also has JDK 8 installed, we've tried
to "filter out" JDK 9 so that it wouldn't be used; see e.g. a3c4358.
Unfortunately that doesn't work, because on macOS the default JDK used
is always the JDK with the highest version number, and
this can't be easily changed system-wide because changing this
behavior requires "removing" a
Info.plist
file to prevent the JDKfrom being "seen" by
/usr/bin/java
:(Renaming
Info.plist.disabled
toInfo.plist
will restore JDK 9 asthe default JDK on the machine.)
A "proper" fix would presumably involve using and exporting
$JAVA_HOME
everywhere, which isn't currently the case.This is something that should be explored.
In the meantime, a question: Can we build with JDK 9?
Is it even possible in the first place?
Turns out, yes, it is possible. The above
gradlew
error can befixed by providing the (new-in-JDK9)
--add-modules
option, so thatthe
java.xml.bind
module is accessible:Unfortunately, other parts xamarin-android get in the way, e.g. the
<ResolveSdks/>
task doesn't correctly parse the version number outof
java -version
, and JDK 9javac
requires-source
and-target
when
-bootclasspath
is used.Update the build system and tests so that things can be built under
JDK 9.
Note: This does NOT mean that building and/or using JDK 9
will be commercially supported in any way. (It might not even work!)