Skip to content
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

Allow/use JAVA_HOME #1213

Closed
jonpryor opened this issue Jan 19, 2018 · 3 comments
Closed

Allow/use JAVA_HOME #1213

jonpryor opened this issue Jan 19, 2018 · 3 comments
Labels
Area: xamarin-android Build Issues building the xamarin-android repo *itself*.

Comments

@jonpryor
Copy link
Member

The default xamarin-android build uses whatever java is in $PATH, that the manner to override this choice is ill-defined. Additionally, the default xamarin-android build artifacts (xabuild) will likewise use whatever java is in $PATH.

Unfortunately, on macOS it is rather "weird" to control the the default JDK which is used when more than one is installed, making the "use whatever java is in $PATH" behavior sub-optimal.

There is already a way to specify the JDK to use for app builds: $HOME/.config/xbuild/monodroid-config.xml contains a /monodroid/java-sdk/@path attribute which is the path to the JDK to use.

However, defaults matter, and the default is $PATH.

We should do something smarter here, so that when we encounter a machine with both JDK 1.8 and JDK 9 installed, we prefer JDK 8.

@jonpryor jonpryor added the Area: xamarin-android Build Issues building the xamarin-android repo *itself*. label Jan 19, 2018
jonpryor added a commit to jonpryor/xamarin-android that referenced this issue Jan 20, 2018
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.

**Note**: This does ***NOT*** mean that building and/or using JDK 9
will be commercially supported in *any* way. (It might not even work!)
jonpryor added a commit to jonpryor/xamarin-android that referenced this issue Jan 20, 2018
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.

**Note**: This does ***NOT*** mean that building and/or using JDK 9
will be commercially supported in *any* way. (It might not even work!)
jonpryor added a commit to jonpryor/xamarin-android that referenced this issue Jan 23, 2018
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!)
jonpryor added a commit to jonpryor/xamarin-android that referenced this issue Jan 23, 2018
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!)
dellis1972 pushed a commit that referenced this issue Jan 23, 2018
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!)
dellis1972 pushed a commit that referenced this issue Jan 30, 2018
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!)
@directhex
Copy link
Contributor

directhex commented May 4, 2018

Dumb question: why not try a few built-in paths after JAVA_HOME, before $PATH?

Like

Why not call the fully-qualified path from a common location?

/Library/Java/JavaVirtualMachines/jdk1.8.0*/Contents/Home/bin/
/usr/lib/jvm/java-8-openjdk*/bin/
/usr/lib/jvm/java-1.8.0*/jdk/bin/
C:\Program Files\Java\jdk1.8.0\bin\
C:\Program Files (x86)\Java\jdk1.8.0\bin\

That way you don't need to care about the user's default.

@jonpryor
Copy link
Member Author

jonpryor commented Jun 5, 2018

This should be fixed as of dotnet/java-interop@4bd9297 and dotnet/java-interop@bed2958 and 9bc51ae.

@jonpryor jonpryor closed this as completed Jun 5, 2018
@awattar
Copy link

awattar commented Feb 8, 2019

@jonpryor Are there any plans to support other standard Java/Android variables for SKD and NDK?

jonpryor added a commit to jonpryor/xamarin-android that referenced this issue Jul 27, 2021
Fixes: dotnet#6113

Changes: xamarin/monodroid@33e542f...ab6c39e

  * xamarin/monodroid@ab6c39ee5: [tools/fastdev] use strtoull to parse 64 bit argument. (dotnet#1217)
  * xamarin/monodroid@aa75b5b89: [tools/msbuild] Cache the ToolsAbi value for the device. (dotnet#1216)
  * xamarin/monodroid@d4a8977cb: [tools/msbuild] add missing RuntimeConfigBinFilePath value (dotnet#1213)
jonpryor added a commit that referenced this issue Jul 28, 2021
Fixes: #6113

Changes: xamarin/monodroid@33e542f...ab6c39e

  * xamarin/monodroid@ab6c39ee5: [tools/fastdev] use strtoull to parse 64 bit argument. (#1217)
  * xamarin/monodroid@aa75b5b89: [tools/msbuild] Cache the ToolsAbi value for the device. (#1216)
  * xamarin/monodroid@d4a8977cb: [tools/msbuild] add missing RuntimeConfigBinFilePath value (#1213)
jonpryor added a commit that referenced this issue Jul 28, 2021
Fixes: #6113

Changes: xamarin/monodroid@33e542f...ab6c39e

  * xamarin/monodroid@ab6c39ee5: [tools/fastdev] use strtoull to parse 64 bit argument. (#1217)
  * xamarin/monodroid@aa75b5b89: [tools/msbuild] Cache the ToolsAbi value for the device. (#1216)
  * xamarin/monodroid@d4a8977cb: [tools/msbuild] add missing RuntimeConfigBinFilePath value (#1213)
@ghost ghost locked as resolved and limited conversation to collaborators Jun 9, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Area: xamarin-android Build Issues building the xamarin-android repo *itself*.
Projects
None yet
Development

No branches or pull requests

3 participants