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!)