Skip to content

Conversation

@atsushieno
Copy link
Contributor

The logging stopped working during xamarin-android migration because
AndroidLogger simply ignored logging calls. It only resulted in
insufficient failure logs that later prevented diagnosing issues.

So from now on, setting event handlers is mandatory before logging
anything with AndroidLogger.

ReadResolvedSdksCache and ResolveSdksTask were the ones which used
the class in problematic way.

The logging stopped working during xamarin-android migration because
AndroidLogger simply ignored logging calls. It only resulted in
insufficient failure logs that later prevented diagnosing issues.

So from now on, setting event handlers is mandatory before logging
anything with AndroidLogger.

ReadResolvedSdksCache and ResolveSdksTask were the ones which used
the class in problematic way.
@dellis1972 dellis1972 merged commit 95c71bb into dotnet:master May 26, 2016
radical pushed a commit that referenced this pull request May 8, 2018
A unit test failure is being reported, which unfortunately doesn't
contain enough useful context:

	1) generatortests.NormalMethods.GeneratedOK :   error : .../Java.Interop/bin/TestDebug/SupportFiles/JavaObject.cs(78,17): (Location of the symbol related to previous warning)
	Expected: 0
	But was:  1

It's a very odd "error", in that there's no error reported, just a
mention of a "previous warning", which isn't shown.

The *cause* of this useless output is that `Compiler` "trims out" all
the "non-error" output from the compilation. This *seems* good, except
in this case it's the "useless output" that we need to make sense of
anything at all!

Revise `Compiler.Compile()` so that instead of extracting "errors" it
instead provides *all* compiler output and an indicator of whether or
not errors occurred. (This still depends on `CompilerResults.Errors`
having correct output -- and I'm starting to wonder if I'm actually
dealing with a CodeDom bug here -- but at least with more output I can
better rationalize about what's going on.)
dellis1972 referenced this pull request in dellis1972/xamarin-android Mar 26, 2019
In commit 75023bd we noticed an issue the
value of `MonoPackageManager_Resouces.ApiPackageName` was
`""` even after it was replaced at built time with a new
`.class` file which contained an actual value.

The fix in that PR was to make the temp file in java-runtime
have a value of `null` rather than `""`. This made thing work
but we didn't know WHY.

After some more investigation it turns out that the value
was being inlined by the java compiler.

	public static java.lang.String getApiPackageName();
	    descriptor: ()Ljava/lang/String;
	    Code:
	       0: ldc           #48                 // String
	       2: areturn

The code above is pointing to a string in the Constants table.
What we were expecting was that the statick method would be
called in the file generated by the build system. Making
the temp file have a `null` rather than `""` resulted in the
following code

	public static java.lang.String getApiPackageName();
	    descriptor: ()Ljava/lang/String;
	    Code:
	       0: getstatic     #47                 // Field mono/MonoPackageManager_Resources.ApiPackageName:Ljava/lang/String;
	       3: areturn

This is why changing to `null` worked. It prevented the compiler
from inlining the value.

This commit removes the `final` keyword from the `MonoPackageManager_Resources`
class fields to make sure that they never get inlined.
jonpryor pushed a commit that referenced this pull request Mar 26, 2019
In commit 75023bd we noticed that the value of
`MonoPackageManager_Resouces.ApiPackageName` was `""` even after it
was replaced at build time with a new `.class` file which contained
an actual value:

> We don't yet fully understand this failure scenario, but setting
> `ApiPackageName` to null allows things to work.

The fix in 75023bd was to make the default value within
`MonoPackageManager_Resources.java` have a value of `null` rather
than `""`.  This allowed things to work but we didn't know WHY.

After some more investigation it turns out that when
`MonoPackageManager_Resouces.ApiPackageName` was `""`, the empty
string value was being *inlined* by `javac` when generating
`MonoPackageManager.getApiPackageName()`:

	public static java.lang.String getApiPackageName();
	    descriptor: ()Ljava/lang/String;
	    Code:
	       0: ldc           #48                 // String
	       2: areturn

`ldc` loads a constant from the Constants table, in this case `""`.

When `null` was used, `javac` instead emitted a field access:

	public static java.lang.String getApiPackageName();
	    descriptor: ()Ljava/lang/String;
	    Code:
	       0: getstatic     #47                 // Field mono/MonoPackageManager_Resources.ApiPackageName:Ljava/lang/String;
	       3: areturn

(Why `javac` didn't inline `null` is beyond @jonpryor.)

This is why changing to `null` worked: it prevented the compiler from
inlining the value.

However, while that "worked," it is not at all obvious, and short of
reading the Java Language Spec to determine if `null` is even a value
which *can* be inlined, the current approach of using a `final` value
seems potentially *dangerous*, as behavior may be subject to the
compiler used and subject to change.

To fix this, remove the `final` keyword from the
`MonoPackageManager_Resources` fields prevent inlining.
@github-actions github-actions bot locked and limited conversation to collaborators Feb 2, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants