You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by pt...@apache.org on 2017/02/15 13:08:47 UTC

ignite git commit: IGNITE-4693 Add possibility to wrap Java plugin exceptions to .NET plugin exceptions

Repository: ignite
Updated Branches:
  refs/heads/ignite-2.0 bd988b71d -> 4a783410e


IGNITE-4693 Add possibility to wrap Java plugin exceptions to .NET plugin exceptions

This closes #1530


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/4a783410
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/4a783410
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/4a783410

Branch: refs/heads/ignite-2.0
Commit: 4a783410e2555584bc69b752f955d7e0d9066ebd
Parents: bd988b7
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Wed Feb 15 16:08:35 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Wed Feb 15 16:08:35 2017 +0300

----------------------------------------------------------------------
 .../plugin/PlatformTestPluginException.java     | 34 ++++++++
 .../plugin/PlatformTestPluginTarget.java        |  3 +
 .../Apache.Ignite.Core.Tests.csproj             |  1 +
 .../Plugin/PluginTest.cs                        | 13 +++
 .../Plugin/TestIgnitePluginException.cs         | 64 ++++++++++++++
 .../Plugin/TestIgnitePluginProvider.cs          |  4 +
 .../Apache.Ignite.Core.csproj                   |  1 +
 .../Common/ExceptionFactory.cs                  | 31 +++++++
 .../Apache.Ignite.Core/Impl/ExceptionUtils.cs   | 92 +++++++++++---------
 .../Impl/Plugin/PluginContext.cs                | 11 +++
 .../Impl/Plugin/PluginProcessor.cs              | 28 ++++++
 .../Apache.Ignite.Core/Plugin/IPluginContext.cs |  9 ++
 12 files changed, 251 insertions(+), 40 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/4a783410/modules/core/src/test/java/org/apache/ignite/platform/plugin/PlatformTestPluginException.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/platform/plugin/PlatformTestPluginException.java b/modules/core/src/test/java/org/apache/ignite/platform/plugin/PlatformTestPluginException.java
new file mode 100644
index 0000000..3d71dda
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/platform/plugin/PlatformTestPluginException.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.platform.plugin;
+
+import org.apache.ignite.IgniteCheckedException;
+
+/**
+ * Custom plugin exception
+ */
+public class PlatformTestPluginException extends IgniteCheckedException {
+    /**
+     * Ctor.
+     *
+     * @param msg Message.
+     */
+    public PlatformTestPluginException(String msg) {
+        super(msg);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4a783410/modules/core/src/test/java/org/apache/ignite/platform/plugin/PlatformTestPluginTarget.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/platform/plugin/PlatformTestPluginTarget.java b/modules/core/src/test/java/org/apache/ignite/platform/plugin/PlatformTestPluginTarget.java
index b893395..94a21a3 100644
--- a/modules/core/src/test/java/org/apache/ignite/platform/plugin/PlatformTestPluginTarget.java
+++ b/modules/core/src/test/java/org/apache/ignite/platform/plugin/PlatformTestPluginTarget.java
@@ -56,6 +56,9 @@ class PlatformTestPluginTarget extends PlatformAbstractTarget {
 
     /** {@inheritDoc} */
     @Override public long processInLongOutLong(int type, long val) throws IgniteCheckedException {
+        if (type == -1)
+            throw new PlatformTestPluginException("Baz");
+
         return val + 1;
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/4a783410/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
index 3e0641b..71b0593 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
@@ -94,6 +94,7 @@
     <Compile Include="Plugin\PluginTest.cs" />
     <Compile Include="Plugin\TestIgnitePlugin.cs" />
     <Compile Include="Plugin\TestIgnitePluginConfiguration.cs" />
+    <Compile Include="Plugin\TestIgnitePluginException.cs" />
     <Compile Include="Plugin\TestIgnitePluginProvider.cs" />
     <Compile Include="Plugin\Cache\CachePlugin.cs" />
     <Compile Include="Plugin\Cache\CachePluginConfiguration.cs" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/4a783410/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/PluginTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/PluginTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/PluginTest.cs
index 6fca03a..0af7b10 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/PluginTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/PluginTest.cs
@@ -114,6 +114,19 @@ namespace Apache.Ignite.Core.Tests.Plugin
             // Returns a copy with same name.
             var resCopy = res.Item2.OutObject(1);
             Assert.AreEqual("name1_abc", resCopy.OutStream(1, r => r.ReadString()));
+
+            // Throws custom mapped exception.
+            var ex = Assert.Throws<TestIgnitePluginException>(() => target.InLongOutLong(-1, 0));
+            Assert.AreEqual("Baz", ex.Message);
+            Assert.AreEqual(Ignition.GetIgnite(null), ex.Ignite);
+            Assert.AreEqual("org.apache.ignite.platform.plugin.PlatformTestPluginException", ex.ClassName);
+
+            var javaEx = ex.InnerException as JavaException;
+            Assert.IsNotNull(javaEx);
+            Assert.AreEqual("Baz", javaEx.JavaMessage);
+            Assert.AreEqual("org.apache.ignite.platform.plugin.PlatformTestPluginException", javaEx.JavaClassName);
+            Assert.IsTrue(javaEx.Message.Contains(
+                "at org.apache.ignite.platform.plugin.PlatformTestPluginTarget.processInLongOutLong"));
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/4a783410/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/TestIgnitePluginException.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/TestIgnitePluginException.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/TestIgnitePluginException.cs
new file mode 100644
index 0000000..c0805d1
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/TestIgnitePluginException.cs
@@ -0,0 +1,64 @@
+\ufeff/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Tests.Plugin
+{
+    using System;
+    using Apache.Ignite.Core.Common;
+
+    /// <summary>
+    /// Test custom-mapped plugin exception.
+    /// </summary>
+    public class TestIgnitePluginException : IgniteException
+    {
+        /** */
+        private readonly string _className;
+
+        /** */
+        private readonly IIgnite _ignite;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="TestIgnitePluginException" /> class.
+        /// </summary>
+        /// <param name="className">Name of the class.</param>
+        /// <param name="message">Message.</param>
+        /// <param name="ignite">Ignite.</param>
+        /// <param name="cause">Cause.</param>
+        public TestIgnitePluginException(string className, string message, IIgnite ignite, Exception cause) 
+            : base(message, cause)
+        {
+            _className = className;
+            _ignite = ignite;
+        }
+
+        /// <summary>
+        /// Gets the name of the class.
+        /// </summary>
+        public string ClassName
+        {
+            get { return _className; }
+        }
+
+        /// <summary>
+        /// Gets the ignite.
+        /// </summary>
+        public IIgnite Ignite
+        {
+            get { return _ignite; }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4a783410/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/TestIgnitePluginProvider.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/TestIgnitePluginProvider.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/TestIgnitePluginProvider.cs
index bc21540..d86750f 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/TestIgnitePluginProvider.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Plugin/TestIgnitePluginProvider.cs
@@ -65,6 +65,10 @@ namespace Apache.Ignite.Core.Tests.Plugin
         /** <inheritdoc /> */
         public void Start(IPluginContext<TestIgnitePluginConfiguration> context)
         {
+            context.RegisterExceptionMapping("org.apache.ignite.platform.plugin.PlatformTestPluginException",
+                (className, message, inner, ignite) =>
+                    new TestIgnitePluginException(className, message, ignite, inner));
+
             Context = context;
 
             EnsureIgniteWorks();

http://git-wip-us.apache.org/repos/asf/ignite/blob/4a783410/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
index 1499104..7c86429 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
@@ -92,6 +92,7 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Binary\BinaryArrayEqualityComparer.cs" />
+    <Compile Include="Common\ExceptionFactory.cs" />
     <Compile Include="Impl\Binary\BinaryFieldEqualityComparer.cs" />
     <Compile Include="Binary\BinaryReflectiveSerializer.cs" />
     <Compile Include="Common\JavaException.cs" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/4a783410/modules/platforms/dotnet/Apache.Ignite.Core/Common/ExceptionFactory.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Common/ExceptionFactory.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Common/ExceptionFactory.cs
new file mode 100644
index 0000000..e93ee78
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Common/ExceptionFactory.cs
@@ -0,0 +1,31 @@
+\ufeff/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Common
+{
+    using System;
+
+    /// <summary>
+    /// Exception factory delegate.
+    /// </summary>
+    /// <param name="className">Exception class name.</param>
+    /// <param name="message">Exception message.</param>
+    /// <param name="inner">Inner exception.</param>
+    /// <param name="ignite">Ignite instance.</param>
+    /// <returns>Exception.</returns>
+    public delegate Exception ExceptionFactory(string className, string message, Exception inner, IIgnite ignite);
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4a783410/modules/platforms/dotnet/Apache.Ignite.Core/Impl/ExceptionUtils.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/ExceptionUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/ExceptionUtils.cs
index 4534e91..e2d61d7 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/ExceptionUtils.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/ExceptionUtils.cs
@@ -48,10 +48,7 @@ namespace Apache.Ignite.Core.Impl
         private const string ClsCachePartialUpdateErr = "org.apache.ignite.internal.processors.platform.cache.PlatformCachePartialUpdateException";
 
         /** Map with predefined exceptions. */
-        private static readonly IDictionary<string, ExceptionFactoryDelegate> Exs = new Dictionary<string, ExceptionFactoryDelegate>();
-
-        /** Exception factory delegate. */
-        private delegate Exception ExceptionFactoryDelegate(IIgnite ignite, string msg, Exception innerEx);
+        private static readonly IDictionary<string, ExceptionFactory> Exs = new Dictionary<string, ExceptionFactory>();
 
         /** Inner class regex. */
         private static readonly Regex InnerClassRegex = new Regex(@"class ([^\s]+): (.*)", RegexOptions.Compiled);
@@ -64,50 +61,50 @@ namespace Apache.Ignite.Core.Impl
         static ExceptionUtils()
         {
             // Common Java exceptions mapped to common .NET exceptions.
-            Exs["java.lang.IllegalArgumentException"] = (i, m, e) => new ArgumentException(m, e);
-            Exs["java.lang.IllegalStateException"] = (i, m, e) => new InvalidOperationException(m, e);
-            Exs["java.lang.UnsupportedOperationException"] = (i, m, e) => new NotSupportedException(m, e);
-            Exs["java.lang.InterruptedException"] = (i, m, e) => new ThreadInterruptedException(m, e);
+            Exs["java.lang.IllegalArgumentException"] = (c, m, e, i) => new ArgumentException(m, e);
+            Exs["java.lang.IllegalStateException"] = (c, m, e, i) => new InvalidOperationException(m, e);
+            Exs["java.lang.UnsupportedOperationException"] = (c, m, e, i) => new NotSupportedException(m, e);
+            Exs["java.lang.InterruptedException"] = (c, m, e, i) => new ThreadInterruptedException(m, e);
 
             // Generic Ignite exceptions.
-            Exs["org.apache.ignite.IgniteException"] = (i, m, e) => new IgniteException(m, e);
-            Exs["org.apache.ignite.IgniteCheckedException"] = (i, m, e) => new IgniteException(m, e);
-            Exs["org.apache.ignite.IgniteClientDisconnectedException"] = (i, m, e) => new ClientDisconnectedException(m, e, i.GetCluster().ClientReconnectTask);
-            Exs["org.apache.ignite.internal.IgniteClientDisconnectedCheckedException"] = (i, m, e) => new ClientDisconnectedException(m, e, i.GetCluster().ClientReconnectTask);
-            Exs["org.apache.ignite.binary.BinaryObjectException"] = (i, m, e) => new BinaryObjectException(m, e);
+            Exs["org.apache.ignite.IgniteException"] = (c, m, e, i) => new IgniteException(m, e);
+            Exs["org.apache.ignite.IgniteCheckedException"] = (c, m, e, i) => new IgniteException(m, e);
+            Exs["org.apache.ignite.IgniteClientDisconnectedException"] = (c, m, e, i) => new ClientDisconnectedException(m, e, i.GetCluster().ClientReconnectTask);
+            Exs["org.apache.ignite.internal.IgniteClientDisconnectedCheckedException"] = (c, m, e, i) => new ClientDisconnectedException(m, e, i.GetCluster().ClientReconnectTask);
+            Exs["org.apache.ignite.binary.BinaryObjectException"] = (c, m, e, i) => new BinaryObjectException(m, e);
 
             // Cluster exceptions.
-            Exs["org.apache.ignite.cluster.ClusterGroupEmptyException"] = (i, m, e) => new ClusterGroupEmptyException(m, e);
-            Exs["org.apache.ignite.cluster.ClusterTopologyException"] = (i, m, e) => new ClusterTopologyException(m, e);
+            Exs["org.apache.ignite.cluster.ClusterGroupEmptyException"] = (c, m, e, i) => new ClusterGroupEmptyException(m, e);
+            Exs["org.apache.ignite.cluster.ClusterTopologyException"] = (c, m, e, i) => new ClusterTopologyException(m, e);
 
             // Compute exceptions.
-            Exs["org.apache.ignite.compute.ComputeExecutionRejectedException"] = (i, m, e) => new ComputeExecutionRejectedException(m, e);
-            Exs["org.apache.ignite.compute.ComputeJobFailoverException"] = (i, m, e) => new ComputeJobFailoverException(m, e);
-            Exs["org.apache.ignite.compute.ComputeTaskCancelledException"] = (i, m, e) => new ComputeTaskCancelledException(m, e);
-            Exs["org.apache.ignite.compute.ComputeTaskTimeoutException"] = (i, m, e) => new ComputeTaskTimeoutException(m, e);
-            Exs["org.apache.ignite.compute.ComputeUserUndeclaredException"] = (i, m, e) => new ComputeUserUndeclaredException(m, e);
+            Exs["org.apache.ignite.compute.ComputeExecutionRejectedException"] = (c, m, e, i) => new ComputeExecutionRejectedException(m, e);
+            Exs["org.apache.ignite.compute.ComputeJobFailoverException"] = (c, m, e, i) => new ComputeJobFailoverException(m, e);
+            Exs["org.apache.ignite.compute.ComputeTaskCancelledException"] = (c, m, e, i) => new ComputeTaskCancelledException(m, e);
+            Exs["org.apache.ignite.compute.ComputeTaskTimeoutException"] = (c, m, e, i) => new ComputeTaskTimeoutException(m, e);
+            Exs["org.apache.ignite.compute.ComputeUserUndeclaredException"] = (c, m, e, i) => new ComputeUserUndeclaredException(m, e);
 
             // Cache exceptions.
-            Exs["javax.cache.CacheException"] = (i, m, e) => new CacheException(m, e);
-            Exs["javax.cache.integration.CacheLoaderException"] = (i, m, e) => new CacheStoreException(m, e);
-            Exs["javax.cache.integration.CacheWriterException"] = (i, m, e) => new CacheStoreException(m, e);
-            Exs["javax.cache.processor.EntryProcessorException"] = (i, m, e) => new CacheEntryProcessorException(m, e);
-            Exs["org.apache.ignite.cache.CacheAtomicUpdateTimeoutException"] = (i, m, e) => new CacheAtomicUpdateTimeoutException(m, e);
+            Exs["javax.cache.CacheException"] = (c, m, e, i) => new CacheException(m, e);
+            Exs["javax.cache.integration.CacheLoaderException"] = (c, m, e, i) => new CacheStoreException(m, e);
+            Exs["javax.cache.integration.CacheWriterException"] = (c, m, e, i) => new CacheStoreException(m, e);
+            Exs["javax.cache.processor.EntryProcessorException"] = (c, m, e, i) => new CacheEntryProcessorException(m, e);
+            Exs["org.apache.ignite.cache.CacheAtomicUpdateTimeoutException"] = (c, m, e, i) => new CacheAtomicUpdateTimeoutException(m, e);
 
             // Transaction exceptions.
-            Exs["org.apache.ignite.transactions.TransactionOptimisticException"] = (i, m, e) => new TransactionOptimisticException(m, e);
-            Exs["org.apache.ignite.transactions.TransactionTimeoutException"] = (i, m, e) => new TransactionTimeoutException(m, e);
-            Exs["org.apache.ignite.transactions.TransactionRollbackException"] = (i, m, e) => new TransactionRollbackException(m, e);
-            Exs["org.apache.ignite.transactions.TransactionHeuristicException"] = (i, m, e) => new TransactionHeuristicException(m, e);
-            Exs["org.apache.ignite.transactions.TransactionDeadlockException"] = (i, m, e) => new TransactionDeadlockException(m, e);
+            Exs["org.apache.ignite.transactions.TransactionOptimisticException"] = (c, m, e, i) => new TransactionOptimisticException(m, e);
+            Exs["org.apache.ignite.transactions.TransactionTimeoutException"] = (c, m, e, i) => new TransactionTimeoutException(m, e);
+            Exs["org.apache.ignite.transactions.TransactionRollbackException"] = (c, m, e, i) => new TransactionRollbackException(m, e);
+            Exs["org.apache.ignite.transactions.TransactionHeuristicException"] = (c, m, e, i) => new TransactionHeuristicException(m, e);
+            Exs["org.apache.ignite.transactions.TransactionDeadlockException"] = (c, m, e, i) => new TransactionDeadlockException(m, e);
 
             // Security exceptions.
-            Exs["org.apache.ignite.IgniteAuthenticationException"] = (i, m, e) => new SecurityException(m, e);
-            Exs["org.apache.ignite.plugin.security.GridSecurityException"] = (i, m, e) => new SecurityException(m, e);
+            Exs["org.apache.ignite.IgniteAuthenticationException"] = (c, m, e, i) => new SecurityException(m, e);
+            Exs["org.apache.ignite.plugin.security.GridSecurityException"] = (c, m, e, i) => new SecurityException(m, e);
 
             // Future exceptions
-            Exs["org.apache.ignite.lang.IgniteFutureCancelledException"] = (i, m, e) => new IgniteFutureCancelledException(m, e);
-            Exs["org.apache.ignite.internal.IgniteFutureCancelledCheckedException"] = (i, m, e) => new IgniteFutureCancelledException(m, e);
+            Exs["org.apache.ignite.lang.IgniteFutureCancelledException"] = (c, m, e, i) => new IgniteFutureCancelledException(m, e);
+            Exs["org.apache.ignite.internal.IgniteFutureCancelledCheckedException"] = (c, m, e, i) => new IgniteFutureCancelledException(m, e);
         }
 
         /// <summary>
@@ -120,25 +117,28 @@ namespace Apache.Ignite.Core.Impl
         /// <param name="reader">Error data reader.</param>
         /// <param name="innerException">Inner exception.</param>
         /// <returns>Exception.</returns>
-        public static Exception GetException(IIgnite ignite, string clsName, string msg, string stackTrace,
+        public static Exception GetException(Ignite ignite, string clsName, string msg, string stackTrace,
             BinaryReader reader = null, Exception innerException = null)
         {
             // Set JavaException as inner only if there is no InnerException.
             if (innerException == null)
                 innerException = new JavaException(clsName, msg, stackTrace);
 
-            ExceptionFactoryDelegate ctor;
+            ExceptionFactory ctor;
 
             if (Exs.TryGetValue(clsName, out ctor))
             {
                 var match = InnerClassRegex.Match(msg ?? string.Empty);
 
-                ExceptionFactoryDelegate innerCtor;
+                ExceptionFactory innerCtor;
 
                 if (match.Success && Exs.TryGetValue(match.Groups[1].Value, out innerCtor))
-                    return ctor(ignite, msg, innerCtor(ignite, match.Groups[2].Value, innerException));
+                {
+                    return ctor(clsName, msg,
+                        innerCtor(match.Groups[1].Value, match.Groups[2].Value, innerException, ignite), ignite);
+                }
 
-                return ctor(ignite, msg, innerException);
+                return ctor(clsName, msg, innerException, ignite);
             }
 
             if (ClsNoClsDefFoundErr.Equals(clsName, StringComparison.OrdinalIgnoreCase))
@@ -152,6 +152,18 @@ namespace Apache.Ignite.Core.Impl
             if (ClsCachePartialUpdateErr.Equals(clsName, StringComparison.OrdinalIgnoreCase))
                 return ProcessCachePartialUpdateException(ignite, msg, stackTrace, reader);
 
+            // Predefined mapping not found - check plugins.
+            if (ignite != null)
+            {
+                ctor = ignite.PluginProcessor.GetExceptionMapping(clsName);
+
+                if (ctor != null)
+                {
+                    return ctor(clsName, msg, innerException, ignite);
+                }
+            }
+
+            // Return default exception.
             return new IgniteException(string.Format("Java exception occurred [class={0}, message={1}]", clsName, msg),
                 innerException);
         }
@@ -165,7 +177,7 @@ namespace Apache.Ignite.Core.Impl
         /// <param name="reader">Reader.</param>
         /// <returns>CachePartialUpdateException.</returns>
         [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
-        private static Exception ProcessCachePartialUpdateException(IIgnite ignite, string msg, string stackTrace,
+        private static Exception ProcessCachePartialUpdateException(Ignite ignite, string msg, string stackTrace,
             BinaryReader reader)
         {
             if (reader == null)

http://git-wip-us.apache.org/repos/asf/ignite/blob/4a783410/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Plugin/PluginContext.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Plugin/PluginContext.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Plugin/PluginContext.cs
index 1aa4fab..0e01244 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Plugin/PluginContext.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Plugin/PluginContext.cs
@@ -17,6 +17,8 @@
 
 namespace Apache.Ignite.Core.Impl.Plugin
 {
+    using Apache.Ignite.Core.Common;
+    using Apache.Ignite.Core.Impl.Common;
     using Apache.Ignite.Core.Impl.Unmanaged;
     using Apache.Ignite.Core.Interop;
     using Apache.Ignite.Core.Plugin;
@@ -68,5 +70,14 @@ namespace Apache.Ignite.Core.Impl.Plugin
 
             return new PlatformTarget(ext, ignite.Marshaller);
         }
+
+        /** <inheritdoc /> */
+        public void RegisterExceptionMapping(string className, ExceptionFactory factory)
+        {
+            IgniteArgumentCheck.NotNull(className, "className");
+            IgniteArgumentCheck.NotNull(factory, "factory");
+
+            _pluginProcessor.RegisterExceptionMapping(className, factory);
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/4a783410/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Plugin/PluginProcessor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Plugin/PluginProcessor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Plugin/PluginProcessor.cs
index 78b750b..7cafcc0 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Plugin/PluginProcessor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Plugin/PluginProcessor.cs
@@ -22,6 +22,7 @@ namespace Apache.Ignite.Core.Impl.Plugin
     using System.Diagnostics;
     using System.Linq;
     using Apache.Ignite.Core.Common;
+    using Apache.Ignite.Core.Impl.Common;
     using Apache.Ignite.Core.Log;
     using Apache.Ignite.Core.Plugin;
 
@@ -37,6 +38,10 @@ namespace Apache.Ignite.Core.Impl.Plugin
         private readonly Dictionary<string, IPluginProviderProxy> _pluginProvidersByName
             = new Dictionary<string, IPluginProviderProxy>();
 
+        /** Plugin exception mappings. */
+        private readonly CopyOnWriteConcurrentDictionary<string, ExceptionFactory> _exceptionMappings
+            = new CopyOnWriteConcurrentDictionary<string, ExceptionFactory>();
+
         /** */
         private readonly Ignite _ignite;
 
@@ -116,6 +121,29 @@ namespace Apache.Ignite.Core.Impl.Plugin
         }
 
         /// <summary>
+        /// Gets the exception factory.
+        /// </summary>
+        public ExceptionFactory GetExceptionMapping(string className)
+        {
+            Debug.Assert(className != null);
+
+            ExceptionFactory res;
+
+            return _exceptionMappings.TryGetValue(className, out res) ? res : null;
+        }
+
+        /// <summary>
+        /// Registers the exception mapping.
+        /// </summary>
+        public void RegisterExceptionMapping(string className, ExceptionFactory factory)
+        {
+            Debug.Assert(className != null);
+            Debug.Assert(factory != null);
+
+            _exceptionMappings.GetOrAdd(className, _ => factory);
+        }
+
+        /// <summary>
         /// Loads the plugins.
         /// </summary>
         private void LoadPlugins()

http://git-wip-us.apache.org/repos/asf/ignite/blob/4a783410/modules/platforms/dotnet/Apache.Ignite.Core/Plugin/IPluginContext.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Plugin/IPluginContext.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Plugin/IPluginContext.cs
index edaa7c3..97b566c 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Plugin/IPluginContext.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Plugin/IPluginContext.cs
@@ -17,6 +17,7 @@
 
 namespace Apache.Ignite.Core.Plugin
 {
+    using Apache.Ignite.Core.Common;
     using Apache.Ignite.Core.Interop;
 
     /// <summary>
@@ -48,5 +49,13 @@ namespace Apache.Ignite.Core.Plugin
         /// <param name="id">Extension id. Equal to PlatformExtension.id().</param>
         /// <returns>Reference to a plugin extension on Java side.</returns>
         IPlatformTarget GetExtension(int id);
+
+        /// <summary>
+        /// Registers custom exception mapping: when Java exception of specified class occurs, it will be mapped
+        /// using provided factory delegate.
+        /// </summary>
+        /// <param name="className">Name of the Java exception class to be mapped.</param>
+        /// <param name="factory">Exception factory delegate.</param>
+        void RegisterExceptionMapping(string className, ExceptionFactory factory);
     }
 }
\ No newline at end of file