public static void CheckListenerMethodsFromJavaWorld()
        {
            var javaListener   = new ListenerImplementor();
            var csharpListener = new ListenerCSharpImplemntor();
            var javaInvoker    = new ListenerInvoker();

            // This should work fine
            WrapCall(
                javaInvoker,
                javaListener,
                nameof(javaInvoker.InvokeListenerImplementorMethod),
                () => javaInvoker.InvokeListenerImplementorMethod(javaListener));

            // This should work fine
            WrapCall(
                javaInvoker,
                javaListener,
                nameof(javaInvoker.InvokeListenerImplementorMethod),
                () => javaInvoker.InvokeListenerMethod(javaListener));

            // This throws AbstractMethodError when it shouldn't
            WrapCall(
                javaInvoker,
                csharpListener,
                nameof(javaInvoker.InvokeListenerImplementorMethod),
                () => javaInvoker.InvokeListenerMethod(csharpListener));
        }
示例#2
0
        /// <summary>
        /// A method that guarantess that every delegate contained in the
        /// give <see cref="MulticastDelegate"/> delegate will be executed.
        /// </summary>
        /// <param name="multi_cast_delegate">
        /// A <see cref="MulticastDelegate"/> containing the delegates to be
        /// invoked.
        /// </param>
        /// <param name="invoker">
        /// A <see cref="ListenerInvoker{T}"/> that is invoked for each delegate
        /// contained in the <see cref="MulticastDelegate"/>.
        /// </param>
        /// <remarks>
        /// In many cases, a notification source can simply call "delegate()" to
        /// execute all the target handler methods associated with a
        /// <see lang="MulticastDelegate"/> delegate object. However, the
        /// <see lang="MulticastDelegate"/> error handling makes awereness of the
        /// sequential notification critical. If one subscriber throws an exception
        /// then later subscribers in the chain is not executed.
        /// <para>
        /// To avoid this problem, so that all subscribers execute
        /// regardless of the behavior of the earlier subscribers, you must
        /// manually enumerate through the list of subscribers and call them
        /// individually. This method may be used to avoid doing it manually.
        /// </para>
        /// <para>
        /// We just log the exceptions that are throwed by the subscribers. The
        /// <see cref="MustLogger"/> is used to log the exceptions, by default this
        /// logger logs to nothing, clients should configure the logger that they
        /// want to use.
        /// </para>
        /// </remarks>
        public static void SafeInvoke <T>(MulticastDelegate multi_cast_delegate, ListenerInvoker <T> invoker) where T : class
        {
            if (multi_cast_delegate == null)
            {
                return;
            }

            Delegate[] delegates = multi_cast_delegate.GetInvocationList();

            for (int i = 0, j = delegates.Length; i < j; i++)
            {
                Delegate delegate_i = delegates[i];
                try {
                    invoker(delegate_i as T);
                } catch (Exception e) {
                    // Log it nad keep going. Don't punish the other delegates if we're
                    // given a bad one.
                    ILogger logger = MustLogger.ForCurrentProcess;
                    if (logger.IsErrorEnabled)
                    {
                        logger.Error("Exception while executing delegate "
                                     + delegate_i.ToString(), e);
                    }
                }
            }
        }