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

Rename JavaVM.GetObject() to JavaVM.GetValue(). #2

Closed
jonpryor opened this issue Apr 7, 2015 · 0 comments
Closed

Rename JavaVM.GetObject() to JavaVM.GetValue(). #2

jonpryor opened this issue Apr 7, 2015 · 0 comments

Comments

@jonpryor
Copy link
Member

jonpryor commented Apr 7, 2015

Rename JavaVM.GetObject() to JavaVM.GetValue().

Rationale: I want to remove the IJavaObject constraint so that we can do e.g. vm.GetValue<int>(javaLangIntegerHandle) to read a java.lang.Integer into an int (ditto arrays, etc.), and "Object" no longer makes sense when a copy of the value will be created.

jonpryor added a commit that referenced this issue Dec 4, 2015
Context: #2
Context: #8

From Issue #8:

> I don't like JniMarshalInfo; it's too convoluted, makes the
> simple cases hard.

What do we mean by "hard"?  We mean that it's use is error prone,
because what you need to do depends on the values of the
JniMarshalInfo members, which is best characterized by what
JniArgumentMarshalInfo had to do to create a JNI Local refererence:

	JniObjectReference lref;

	var marshaler = JniRuntime.CurrentRuntime.ValueManager.GetJniMarshalInfoForType (type);
	if (info.CreateMarshalCollection != null) {
		var obj = info.CreateMarshalCollection (value);
		lref    = obj.PeerReference;
	} else if (info.CreateLocalRef != null) {
		lref    = info.CreateLocalRef (value);
	} else
		throw new NotSupportedException ("Don't know how to get a JNI Local Reference!");

	// can now use `lref`...

Need to pass as a method argument? Similar-yet-different.  Then
there's the cleanup code!

The eventual intention is for tools/jnimarshalmethod-gen to
post-process assemblies and generate Java > Managed marshal methods
for all resolvable methods, and do this "dynamically" based on the
actual types involved.  This will allow "fixing" binding assemblies
when involved types change, because binding assemblies won't be as
"static" as they are in Xamarin.Android.  (Which is why Issue #8
mentions using Expressions for the marshaling.)

However, before we can get there we first need a rational marshaling
abstrasction, something that is "pluggable" and readily extensible, so
taht we can e.g. have a custom attribute to control which marshaler to
use on types, parameters, and method return types.  JniMarshalInfo
wasn't that abstraction, and couldn't *be* that abstraction.

To replace JniMarshalInfo, introduce JniValueMarshaler and
JniValueMarshler<T>:

	public abstract partial class JniValueMarshaler {
		public  abstract    object                  CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType = null);
		public  virtual     JniValueMarshalerState  CreateArgumentState (object value, ParameterAttributes synchronize = 0);
		public  abstract    JniValueMarshalerState  CreateObjectReferenceArgumentState (object value, ParameterAttributes synchronize = 0);
		public  abstract    void                    DestroyArgumentState (object value, ref JniValueMarshalerState state, ParameterAttributes synchronize = 0);
	}

	public abstract partial class JniValueMarshaler<T> : JniValueMarshaler {
		public  abstract    T                       CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType = null);
		public  virtual     JniValueMarshalerState  CreateGenericArgumentState (T value, ParameterAttributes synchronize = 0);
		public  abstract    JniValueMarshalerState  CreateGenericObjectReferenceArgumentState (T value, ParameterAttributes synchronize = 0);
		public  abstract    void                    DestroyGenericArgumentState (T value, ref JniValueMarshalerState state, ParameterAttributes synchronize = 0);

		public override object                  CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType = null);
		public override JniValueMarshalerState  CreateArgumentState (object value, ParameterAttributes synchronize = 0);
		public override JniValueMarshalerState  CreateObjectReferenceArgumentState (object value, ParameterAttributes synchronize = 0);
		public override void                    DestroyArgumentState (object value, ref JniValueMarshalerState state, ParameterAttributes synchronize = 0);
	}

The intention is that a custom marshaler can be introduced by
inheriting from JniValueMarshaler<T> and overriding three methods.
This also provides a reasonable abstraction, e.g. to create a
JNI Local Reference:

	var state = marshaler.CreateGenericObjectReferenceArgumentState (value);
	// state.ReferenceValue contains a JNI Object Reference
	// use, then cleanup:
	marshaler.DestroyGenericArgumentState (value, ref state);

The methods are as follows:

  * CreateValue, CreateGenericValue:
    Java > Managed marshaler.
    Given a JniObjectReference, marshal the value to a type compatible
    with specified targetType, which should be either null or a class
    assignment compatible to T.

The other methods use a JniValueMarshalerState type:

	public partial struct JniValueMarshalerState {
		public JniArgumentValue         JniArgumentValue {get;}
		public JniObjectReference       ReferenceValue   {get;}
		public IJavaPeerable            PeerableValue    {get;}
	}

The remaining methods of import are:

  * CreateArgumentState(), CreateGenericArgumentState():
    Managed > Java marshaler.
    Used when the intention is to use
    JniValueMarshalerState.JniArgumentValue, which in turn is for use
    with JniEnvironment.*Methods.Call*Method().

  * CreateObjectReferenceArgumentState(),
    CreateGenericObjectReferenceArgumentState():
    Managed > Java marshaler.
    Used when the intention is to use
    JniValueMarshalerState.ReferenceValue.

  * DestroyArgumentState(), DestroyGenericArgumentState(): Generic
    resource cleanup mechanism for use with Create*ArgumentState().

The primary difference between Create*ArgumentState() and
Create*ObjectReferenceArgumentState() is with builtin value types,
e.g. `int`. Create*ArgumentState() will *only* provide a
JniArgumentValue, while JniValueMarshalerState.ReferenceValue will be
null. Create*ObjectReferenceArgumentState(), meanwhile, will "box" the
value type, providing a valid JniValueMarshalerState.ReferenceValue.
For all other types, these methods are identical.

JniValueMarshaler and JniValueMarshalerState together combine to
replace JniMarshalInfo and JniArgumentMarshalInfo, the latter of which
(1) wasn't public, and (2) was "duplicated" between the generic
marshalers and Java.Interop.Dynamic.  JniValueMarshaler thus allows
cleaning up this duplication.

Along with the new JniValueMarshaler abstraction, we provide
implementations for all builtin types, Nullable<T> for builtin types
(which always box), arrays of the builtin types, JavaObjectArray<T>,
IJavaPeerable, and `object`.

The `object` marshaler supersedes the previous
JniMarshal.GetValue<T>() semantics, using JavaProxyObject as needed.

One thing to note is the ParameterAttributes parameters.  This value
is intended to correspond with
System.Reflection.ParameterInfo.Attributes.  jnimarshalmethod-gen can
thus use the actual MethodInfo + ParameterInfo to encode parameter
marshaling direction.  For most types this won't be useful; this is
largely intended for *arrays*, e.g. we could have an `[In] int[]`
parameter which thus avoids the "copy out" behavior Xamarin.Android
currently performs, thus avoiding an extra JNI transition.  Or
vice-versa, have an `[Out] int[]` parameter, which avoids a JNI
transition to copy the managed `int[]` to the Java `int[]`, replacing
it with the copy-out transition.

Partially addressing Issue #2, this also introduces
JniRuntime.JniValueManager.GetValue() and GetValue<T>() methods.
GetObject() is not yet replaced, but will be in a future commit.
Actual implementation will be done alongside introduction of
CreateValue<T>() and cleaning up JniValueMarshaler.Create*Value()
methods to always create values when able, simplifying the logic if
JniValueMarshaler implementations.
jonpryor added a commit to jonpryor/java.interop that referenced this issue Aug 17, 2016
When `JniRuntime.CreationOptions.DestroyRuntimeOnDispose` is true,
`JavaVM::DestroyJavaVM()` will be invoked when the `JniRuntime`
instance is disposed *or* finalized.

`JreRuntime.CreateJreVM()` would *always* set
`DestroyRuntimeOnDispose` to true, because it called
`JNI_CreateJavaVM()`, so *of course* you'd want to destroy the
Java VM, right?

Which brings us to unit tests. I don't know of any "before all test
fixtures run" and "after all test fixtures run" extension points,
which means:

1. The JVM needs to be created implicitly, "on demand."
2. There's no good way to destroy the JVM created in (1) after all
    tests have finished executing.

Which *really* means that the `JreRuntime` instance is *finalized*,
which sets us up for the unholy trifecta of AppDomain unloads,
finalizers, and JVM shutdown:

For unknown reasons, ~randomly, when running the unit tests (e.g.
`make run-tests`), the test runner will *hang*, indefinitely.

Attaching `lldb` and triggering a backtrace shows the unholy trifecta:

Finalization:

	thread dotnet#4: tid = 0x403831, 0x00007fff9656bdb6 libsystem_kernel.dylib`__psynch_cvwait + 10, name = 'tid_1403'
	  ...
	  frame dotnet#10: 0x00000001001ccb4a mono64`mono_gc_run_finalize(obj=<unavailable>, data=<unavailable>) + 938 at gc.c:256 [opt]
	  frame dotnet#11: 0x00000001001cdd4a mono64`finalizer_thread [inlined] finalize_domain_objects + 51 at gc.c:681 [opt]
	  frame dotnet#12: 0x00000001001cdd17 mono64`finalizer_thread(unused=<unavailable>) + 295 at gc.c:730 [opt]

JVM destruction:

	thread dotnet#4: tid = 0x403831, 0x00007fff9656bdb6 libsystem_kernel.dylib`__psynch_cvwait + 10, name = 'tid_1403'
	  frame #0: 0x00007fff9656bdb6 libsystem_kernel.dylib`__psynch_cvwait + 10
	  frame dotnet#1: 0x00007fffa04d4728 libsystem_pthread.dylib`_pthread_cond_wait + 767
	  frame dotnet#2: 0x000000010ba5bc76 libjvm.dylib`os::PlatformEvent::park() + 192
	  frame dotnet#3: 0x000000010ba38e32 libjvm.dylib`ParkCommon(ParkEvent*, long) + 42
	  frame dotnet#4: 0x000000010ba39708 libjvm.dylib`Monitor::IWait(Thread*, long) + 168
	  frame dotnet#5: 0x000000010ba398f0 libjvm.dylib`Monitor::wait(bool, long, bool) + 246
	  frame dotnet#6: 0x000000010bb3dca2 libjvm.dylib`Threads::destroy_vm() + 80
	  frame dotnet#7: 0x000000010b8fd665 libjvm.dylib`jni_DestroyJavaVM + 254

AppDomain unload:

	thread dotnet#37: tid = 0x4038fb, 0x00007fff9656bdb6 libsystem_kernel.dylib`__psynch_cvwait + 10
	  frame #0: 0x00007fff9656bdb6 libsystem_kernel.dylib`__psynch_cvwait + 10
	  frame dotnet#1: 0x00007fffa04d4728 libsystem_pthread.dylib`_pthread_cond_wait + 767
	  frame dotnet#2: 0x0000000100234a7f mono64`mono_os_cond_timedwait [inlined] mono_os_cond_wait(cond=0x0000000102016e50, mutex=0x0000000102016e10) + 11 at mono-os-mutex.h:105 [opt]
	  frame dotnet#3: 0x0000000100234a74 mono64`mono_os_cond_timedwait(cond=0x0000000102016e50, mutex=0x0000000102016e10, timeout_ms=<unavailable>) + 164 at mono-os-mutex.h:120 [opt]
	  frame dotnet#4: 0x0000000100234828 mono64`_wapi_handle_timedwait_signal_handle(handle=0x0000000000000440, timeout=4294967295, alertable=1, poll=<unavailable>, alerted=0x0000700000a286f4) + 536 at handles.c:1554 [opt]
	  frame dotnet#5: 0x0000000100246370 mono64`wapi_WaitForSingleObjectEx(handle=<unavailable>, timeout=<unavailable>, alertable=<unavailable>) + 592 at wait.c:189 [opt]
	  frame dotnet#6: 0x00000001001c832e mono64`mono_domain_try_unload [inlined] guarded_wait(timeout=4294967295, alertable=1) + 30 at appdomain.c:2390 [opt]
	  frame dotnet#7: 0x00000001001c8310 mono64`mono_domain_try_unload(domain=0x000000010127ccb0, exc=0x0000700000a287a0) + 416 at appdomain.c:2482 [opt]
	  frame dotnet#8: 0x00000001001c7db2 mono64`ves_icall_System_AppDomain_InternalUnload [inlined] mono_domain_unload(domain=<unavailable>) + 20 at appdomain.c:2379 [opt]
	  frame dotnet#9: 0x00000001001c7d9e mono64`ves_icall_System_AppDomain_InternalUnload(domain_id=<unavailable>) + 46 at appdomain.c:2039 [opt]

This randomly results in deadlock, and hung Jenkins bots.

Fix this behavior by altering `JreRuntime.CreateJreVM()` to *not*
override the value of
`JniRuntime.CreationOptions.DestroyRuntimeOnDispose`. This allows the
constructor of the `JreRuntime` instance to decide whether or not the
JVM is destroyed.

In the case of TestJVM, we *don't* want to destroy the JVM.

This prevents the JVM from being destroyed, which in turn prevents the
hang during process shutdown.
jonpryor added a commit that referenced this issue Aug 17, 2016
When `JniRuntime.CreationOptions.DestroyRuntimeOnDispose` is true,
`JavaVM::DestroyJavaVM()` will be invoked when the `JniRuntime`
instance is disposed *or* finalized.

`JreRuntime.CreateJreVM()` would *always* set
`DestroyRuntimeOnDispose` to true, because it called
`JNI_CreateJavaVM()`, so *of course* you'd want to destroy the
Java VM, right?

Which brings us to unit tests. I don't know of any "before all test
fixtures run" and "after all test fixtures run" extension points,
which means:

1. The JVM needs to be created implicitly, "on demand."
2. There's no good way to destroy the JVM created in (1) after all
    tests have finished executing.

Which *really* means that the `JreRuntime` instance is *finalized*,
which sets us up for the unholy trifecta of AppDomain unloads,
finalizers, and JVM shutdown:

For unknown reasons, ~randomly, when running the unit tests (e.g.
`make run-tests`), the test runner will *hang*, indefinitely.

Attaching `lldb` and triggering a backtrace shows the unholy trifecta:

Finalization:

	thread #4: tid = 0x403831, 0x00007fff9656bdb6 libsystem_kernel.dylib`__psynch_cvwait + 10, name = 'tid_1403'
	  ...
	  frame #10: 0x00000001001ccb4a mono64`mono_gc_run_finalize(obj=<unavailable>, data=<unavailable>) + 938 at gc.c:256 [opt]
	  frame #11: 0x00000001001cdd4a mono64`finalizer_thread [inlined] finalize_domain_objects + 51 at gc.c:681 [opt]
	  frame #12: 0x00000001001cdd17 mono64`finalizer_thread(unused=<unavailable>) + 295 at gc.c:730 [opt]

JVM destruction:

	thread #4: tid = 0x403831, 0x00007fff9656bdb6 libsystem_kernel.dylib`__psynch_cvwait + 10, name = 'tid_1403'
	  frame #0: 0x00007fff9656bdb6 libsystem_kernel.dylib`__psynch_cvwait + 10
	  frame #1: 0x00007fffa04d4728 libsystem_pthread.dylib`_pthread_cond_wait + 767
	  frame #2: 0x000000010ba5bc76 libjvm.dylib`os::PlatformEvent::park() + 192
	  frame #3: 0x000000010ba38e32 libjvm.dylib`ParkCommon(ParkEvent*, long) + 42
	  frame #4: 0x000000010ba39708 libjvm.dylib`Monitor::IWait(Thread*, long) + 168
	  frame #5: 0x000000010ba398f0 libjvm.dylib`Monitor::wait(bool, long, bool) + 246
	  frame #6: 0x000000010bb3dca2 libjvm.dylib`Threads::destroy_vm() + 80
	  frame #7: 0x000000010b8fd665 libjvm.dylib`jni_DestroyJavaVM + 254

AppDomain unload:

	thread #37: tid = 0x4038fb, 0x00007fff9656bdb6 libsystem_kernel.dylib`__psynch_cvwait + 10
	  frame #0: 0x00007fff9656bdb6 libsystem_kernel.dylib`__psynch_cvwait + 10
	  frame #1: 0x00007fffa04d4728 libsystem_pthread.dylib`_pthread_cond_wait + 767
	  frame #2: 0x0000000100234a7f mono64`mono_os_cond_timedwait [inlined] mono_os_cond_wait(cond=0x0000000102016e50, mutex=0x0000000102016e10) + 11 at mono-os-mutex.h:105 [opt]
	  frame #3: 0x0000000100234a74 mono64`mono_os_cond_timedwait(cond=0x0000000102016e50, mutex=0x0000000102016e10, timeout_ms=<unavailable>) + 164 at mono-os-mutex.h:120 [opt]
	  frame #4: 0x0000000100234828 mono64`_wapi_handle_timedwait_signal_handle(handle=0x0000000000000440, timeout=4294967295, alertable=1, poll=<unavailable>, alerted=0x0000700000a286f4) + 536 at handles.c:1554 [opt]
	  frame #5: 0x0000000100246370 mono64`wapi_WaitForSingleObjectEx(handle=<unavailable>, timeout=<unavailable>, alertable=<unavailable>) + 592 at wait.c:189 [opt]
	  frame #6: 0x00000001001c832e mono64`mono_domain_try_unload [inlined] guarded_wait(timeout=4294967295, alertable=1) + 30 at appdomain.c:2390 [opt]
	  frame #7: 0x00000001001c8310 mono64`mono_domain_try_unload(domain=0x000000010127ccb0, exc=0x0000700000a287a0) + 416 at appdomain.c:2482 [opt]
	  frame #8: 0x00000001001c7db2 mono64`ves_icall_System_AppDomain_InternalUnload [inlined] mono_domain_unload(domain=<unavailable>) + 20 at appdomain.c:2379 [opt]
	  frame #9: 0x00000001001c7d9e mono64`ves_icall_System_AppDomain_InternalUnload(domain_id=<unavailable>) + 46 at appdomain.c:2039 [opt]

This randomly results in deadlock, and hung Jenkins bots.

Fix this behavior by altering `JreRuntime.CreateJreVM()` to *not*
override the value of
`JniRuntime.CreationOptions.DestroyRuntimeOnDispose`. This allows the
constructor of the `JreRuntime` instance to decide whether or not the
JVM is destroyed.

In the case of TestJVM, we *don't* want to destroy the JVM.

This prevents the JVM from being destroyed, which in turn prevents the
hang during process shutdown.
jonpryor added a commit to jonpryor/java.interop that referenced this issue Oct 19, 2020
Context: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1230070

Changes: mono/LineEditor@5a7e3e2...3fa0c2e

  * mono/LineEditor@3fa0c2e: Fix NuGet publishing errors (dotnet#9)
  * mono/LineEditor@06a4ddf: Bump `$(PackageVersion)` to 5.4.1.
  * mono/LineEditor@bce1b7f: Enable .pdb files for Release config & add AzDO build script (dotnet#8)
  * mono/LineEditor@4831e1a: Merge pull request dotnet#6 from terrajobst/code-of-conduct
  * mono/LineEditor@5b4a4aa: Link Code of Conduct
  * mono/LineEditor@410ca3d: Merge pull request dotnet#2 from VEIT-Electronics/master
  * mono/LineEditor@3d802e7: Merge pull request dotnet#1 from VEIT-Electronics/bugfix/ENG-232-line-editor-completions
  * mono/LineEditor@0d43552: fix: text overriding was only platform specific (check platform)

The most important piece is mono/LineEditor@bce1b7f, which will allow
us to redistribute `LineEditor.pdb` in the Xamarin.Android installers.
jonpryor added a commit to jonpryor/java.interop that referenced this issue Oct 19, 2020
Context: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1230070

Changes: mono/LineEditor@5a7e3e2...3fa0c2e

  * mono/LineEditor@3fa0c2e: Fix NuGet publishing errors (dotnet#9)
  * mono/LineEditor@06a4ddf: Bump `$(PackageVersion)` to 5.4.1.
  * mono/LineEditor@bce1b7f: Enable .pdb files for Release config & add AzDO build script (dotnet#8)
  * mono/LineEditor@4831e1a: Merge pull request dotnet#6 from terrajobst/code-of-conduct
  * mono/LineEditor@5b4a4aa: Link Code of Conduct
  * mono/LineEditor@410ca3d: Merge pull request dotnet#2 from VEIT-Electronics/master
  * mono/LineEditor@3d802e7: Merge pull request dotnet#1 from VEIT-Electronics/bugfix/ENG-232-line-editor-completions
  * mono/LineEditor@0d43552: fix: text overriding was only platform specific (check platform)

The most important piece is mono/LineEditor@bce1b7f, which will allow
us to redistribute `LineEditor.pdb` in the Xamarin.Android installers.
jonpryor added a commit to jonpryor/java.interop that referenced this issue Oct 20, 2020
Context: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1230070

Changes: mono/LineEditor@5a7e3e2...3fa0c2e

  * mono/LineEditor@3fa0c2e: Fix NuGet publishing errors (dotnet#9)
  * mono/LineEditor@06a4ddf: Bump `$(PackageVersion)` to 5.4.1.
  * mono/LineEditor@bce1b7f: Enable .pdb files for Release config & add AzDO build script (dotnet#8)
  * mono/LineEditor@4831e1a: Merge pull request dotnet#6 from terrajobst/code-of-conduct
  * mono/LineEditor@5b4a4aa: Link Code of Conduct
  * mono/LineEditor@410ca3d: Merge pull request dotnet#2 from VEIT-Electronics/master
  * mono/LineEditor@3d802e7: Merge pull request dotnet#1 from VEIT-Electronics/bugfix/ENG-232-line-editor-completions
  * mono/LineEditor@0d43552: fix: text overriding was only platform specific (check platform)

The most important piece is mono/LineEditor@bce1b7f, which will allow
us to redistribute `LineEditor.pdb` in the Xamarin.Android installers.

Use `LineEditor.pdb` by adding a post-`Build` target to
`logcat-parse/Directory.Build.targets` which copies `LineEditor.pdb`
into `$(OutputPath)`.  This will allow the Xamarin.Android installer
to include `LineEditor.pdb` into the installer packages.
jonpryor added a commit to jonpryor/java.interop that referenced this issue Oct 20, 2020
Context: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1230070

Changes: mono/LineEditor@5a7e3e2...3fa0c2e

  * mono/LineEditor@3fa0c2e: Fix NuGet publishing errors (dotnet#9)
  * mono/LineEditor@06a4ddf: Bump `$(PackageVersion)` to 5.4.1.
  * mono/LineEditor@bce1b7f: Enable .pdb files for Release config & add AzDO build script (dotnet#8)
  * mono/LineEditor@4831e1a: Merge pull request dotnet#6 from terrajobst/code-of-conduct
  * mono/LineEditor@5b4a4aa: Link Code of Conduct
  * mono/LineEditor@410ca3d: Merge pull request dotnet#2 from VEIT-Electronics/master
  * mono/LineEditor@3d802e7: Merge pull request dotnet#1 from VEIT-Electronics/bugfix/ENG-232-line-editor-completions
  * mono/LineEditor@0d43552: fix: text overriding was only platform specific (check platform)

The most important piece is mono/LineEditor@bce1b7f, which will allow
us to redistribute `LineEditor.pdb` in the Xamarin.Android installers.

Add a post-`Build` target to `logcat-parse/Directory.Build.targets`
which copies `LineEditor.pdb` into `$(OutputPath)`.  This will allow
the Xamarin.Android installer to include `LineEditor.pdb` into the
installer packages.
jonpryor added a commit that referenced this issue Oct 20, 2020
Context: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1230070

Changes: mono/LineEditor@5a7e3e2...3fa0c2e

  * mono/LineEditor@3fa0c2e: Fix NuGet publishing errors (#9)
  * mono/LineEditor@06a4ddf: Bump `$(PackageVersion)` to 5.4.1.
  * mono/LineEditor@bce1b7f: Enable .pdb files for Release config & add AzDO build script (#8)
  * mono/LineEditor@4831e1a: Merge pull request #6 from terrajobst/code-of-conduct
  * mono/LineEditor@5b4a4aa: Link Code of Conduct
  * mono/LineEditor@410ca3d: Merge pull request #2 from VEIT-Electronics/master
  * mono/LineEditor@3d802e7: Merge pull request #1 from VEIT-Electronics/bugfix/ENG-232-line-editor-completions
  * mono/LineEditor@0d43552: fix: text overriding was only platform specific (check platform)

The most important piece is mono/LineEditor@bce1b7f, which will allow
us to redistribute `LineEditor.pdb` in the Xamarin.Android installers.

Add a post-`Build` target to `logcat-parse/Directory.Build.targets`
which copies `LineEditor.pdb` into `$(OutputPath)`.  This will allow
the Xamarin.Android installer to include `LineEditor.pdb` into the
installer packages.
pjcollins pushed a commit to pjcollins/java.interop that referenced this issue Dec 17, 2020
Context: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1230070

Changes: mono/LineEditor@5a7e3e2...3fa0c2e

  * mono/LineEditor@3fa0c2e: Fix NuGet publishing errors (dotnet#9)
  * mono/LineEditor@06a4ddf: Bump `$(PackageVersion)` to 5.4.1.
  * mono/LineEditor@bce1b7f: Enable .pdb files for Release config & add AzDO build script (dotnet#8)
  * mono/LineEditor@4831e1a: Merge pull request dotnet#6 from terrajobst/code-of-conduct
  * mono/LineEditor@5b4a4aa: Link Code of Conduct
  * mono/LineEditor@410ca3d: Merge pull request dotnet#2 from VEIT-Electronics/master
  * mono/LineEditor@3d802e7: Merge pull request dotnet#1 from VEIT-Electronics/bugfix/ENG-232-line-editor-completions
  * mono/LineEditor@0d43552: fix: text overriding was only platform specific (check platform)

The most important piece is mono/LineEditor@bce1b7f, which will allow
us to redistribute `LineEditor.pdb` in the Xamarin.Android installers.

Add a post-`Build` target to `logcat-parse/Directory.Build.targets`
which copies `LineEditor.pdb` into `$(OutputPath)`.  This will allow
the Xamarin.Android installer to include `LineEditor.pdb` into the
installer packages.
@github-actions github-actions bot locked and limited conversation to collaborators Apr 15, 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

No branches or pull requests

1 participant