This is an automated email from the ASF dual-hosted git repository.

ipavlukhin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 4fe0371  IGNITE-11907 Fail Continuous Query registration and do not 
fail node if remote filter class is missing - Fixes #6645.
4fe0371 is described below

commit 4fe0371c00a3204030b4e1fbe6db3d2d54412b48
Author: ipavlukhin <vololo...@gmail.com>
AuthorDate: Wed Jul 10 12:48:48 2019 +0300

    IGNITE-11907 Fail Continuous Query registration and do not fail node if 
remote filter class is missing - Fixes #6645.
    
    Signed-off-by: ipavlukhin <vololo...@gmail.com>
---
 .../IncompleteDeserializationException.java        |  53 ++++++++
 .../continuous/GridContinuousProcessor.java        |  62 ++++++---
 .../continuous/StartRoutineDiscoveryMessage.java   |  40 +++++-
 .../messages/TcpDiscoveryCustomEventMessage.java   |  14 +-
 .../IncompleteDeserializationExceptionTest.java    | 132 ++++++++++++++++++
 ...ueryRemoteFilterMissingInClassPathSelfTest.java | 148 +++++++++++++++------
 .../ignite/testsuites/IgniteBasicTestSuite.java    |  19 +--
 .../ignite/internal/managers/discovery/Wrapper.ser | Bin 0 -> 260 bytes
 8 files changed, 394 insertions(+), 74 deletions(-)

diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/IncompleteDeserializationException.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/IncompleteDeserializationException.java
new file mode 100644
index 0000000..5a440ce
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/IncompleteDeserializationException.java
@@ -0,0 +1,53 @@
+/*
+ * 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.internal.managers.discovery;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Exception which can be used to access a message which failed to be 
deserialized completely using Java serialization.
+ * Throwed from deserialization methods it can be caught by a caller.
+ * <p>
+ * Should be {@link RuntimeException} because of limitations of Java 
serialization mechanisms.
+ * <p>
+ * Catching {@link ClassNotFoundException} inside deserialization methods 
cannot do the same trick because
+ * Java deserialization remembers such exception internally and will rethrow 
it anyway upon returing to a user.
+ */
+public class IncompleteDeserializationException extends RuntimeException {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** */
+    private final DiscoveryCustomMessage m;
+
+    /**
+     * @param m Message.
+     */
+    public IncompleteDeserializationException(@NotNull DiscoveryCustomMessage 
m) {
+        super(null, null, false, false);
+
+        this.m = m;
+    }
+
+    /**
+     * @return Message.
+     */
+    @NotNull public DiscoveryCustomMessage message() {
+        return m;
+    }
+}
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousProcessor.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousProcessor.java
index f6bd571..eeb7303 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousProcessor.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/GridContinuousProcessor.java
@@ -1071,37 +1071,37 @@ public class GridContinuousProcessor extends 
GridProcessorAdapter {
                     doStop = true;
             }
 
-        if (doStop) {
-            boolean stop = false;
+            if (doStop) {
+                boolean stop = false;
 
-            // Unregister routine locally.
-            LocalRoutineInfo routine = locInfos.remove(routineId);
+                // Unregister routine locally.
+                LocalRoutineInfo routine = locInfos.remove(routineId);
 
-            if (routine != null) {
-                stop = true;
+                if (routine != null) {
+                    stop = true;
 
-                // Unregister handler locally.
-                unregisterHandler(routineId, routine.hnd, true);
-            }
+                    // Unregister handler locally.
+                    unregisterHandler(routineId, routine.hnd, true);
+                }
 
-            if (!stop && discoProtoVer == 2)
-                stop = routinesInfo.routineExists(routineId);
+                if (!stop && discoProtoVer == 2)
+                    stop = routinesInfo.routineExists(routineId);
 
-            // Finish if routine is not found (wrong ID is provided).
-            if (!stop) {
-                stopFuts.remove(routineId);
+                // Finish if routine is not found (wrong ID is provided).
+                if (!stop) {
+                    stopFuts.remove(routineId);
 
                     fut.onDone();
 
                     return fut;
                 }
 
-            try {
-                ctx.discovery().sendCustomEvent(new 
StopRoutineDiscoveryMessage(routineId));
-            }
-            catch (IgniteCheckedException e) {
-                fut.onDone(e);
-            }
+                try {
+                    ctx.discovery().sendCustomEvent(new 
StopRoutineDiscoveryMessage(routineId));
+                }
+                catch (IgniteCheckedException e) {
+                    fut.onDone(e);
+                }
 
                 if (ctx.isStopping())
                     fut.onDone();
@@ -1360,10 +1360,21 @@ public class GridContinuousProcessor extends 
GridProcessorAdapter {
      * @param req Start request.
      */
     private void processStartRequest(ClusterNode node, 
StartRoutineDiscoveryMessage req) {
-        UUID routineId = req.routineId();
         if (node.id().equals(ctx.localNodeId()))
             return;
 
+        UUID routineId = req.routineId();
+
+        if (req.deserializationException() != null && checkNodeFilter(req)) {
+            IgniteCheckedException err = new 
IgniteCheckedException(req.deserializationException());
+
+            req.addError(node.id(), err);
+
+            U.error(log, "Failed to register handler [nodeId=" + node.id() + 
", routineId=" + routineId + ']', err);
+
+            return;
+        }
+
         StartRequestData data = req.startRequestData();
 
         GridContinuousHandler hnd = data.handler();
@@ -1459,6 +1470,15 @@ public class GridContinuousProcessor extends 
GridProcessorAdapter {
             req.addError(ctx.localNodeId(), err);
     }
 
+    /** */
+    private boolean checkNodeFilter(StartRoutineDiscoveryMessage req) {
+        StartRequestData reqData = req.startRequestData();
+        IgnitePredicate<ClusterNode> prjPred;
+
+        return reqData == null || (prjPred = reqData.projectionPredicate()) == 
null
+            || prjPred.apply(ctx.discovery().localNode());
+    }
+
     /**
      * @param sndId Sender node ID.
      * @param msg Message.
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/StartRoutineDiscoveryMessage.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/StartRoutineDiscoveryMessage.java
index 82996d4..af55624 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/StartRoutineDiscoveryMessage.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/continuous/StartRoutineDiscoveryMessage.java
@@ -17,16 +17,21 @@
 
 package org.apache.ignite.internal.processors.continuous;
 
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage;
+import 
org.apache.ignite.internal.managers.discovery.IncompleteDeserializationException;
 import org.apache.ignite.internal.util.typedef.T2;
 import org.apache.ignite.internal.util.typedef.internal.S;
+import org.jetbrains.annotations.Nullable;
 
 /**
- *
+ * Discovery message used for Continuous Query registration.
  */
 public class StartRoutineDiscoveryMessage extends AbstractContinuousMessage {
     /** */
@@ -36,7 +41,7 @@ public class StartRoutineDiscoveryMessage extends 
AbstractContinuousMessage {
     private final StartRequestData startReqData;
 
     /** */
-    private final Map<UUID, IgniteCheckedException> errs = new HashMap<>();
+    private Map<UUID, IgniteCheckedException> errs;
 
     /** */
     private Map<Integer, T2<Long, Long>> updateCntrs;
@@ -47,6 +52,9 @@ public class StartRoutineDiscoveryMessage extends 
AbstractContinuousMessage {
     /** Keep binary flag. */
     private boolean keepBinary;
 
+    /** */
+    private transient ClassNotFoundException deserEx;
+
     /**
      * @param routineId Routine id.
      * @param startReqData Start request data.
@@ -70,6 +78,9 @@ public class StartRoutineDiscoveryMessage extends 
AbstractContinuousMessage {
      * @param e Exception.
      */
     public void addError(UUID nodeId, IgniteCheckedException e) {
+        if (errs == null)
+            errs = new HashMap<>();
+
         errs.put(nodeId, e);
     }
 
@@ -108,7 +119,7 @@ public class StartRoutineDiscoveryMessage extends 
AbstractContinuousMessage {
      * @return Errs.
      */
     public Map<UUID, IgniteCheckedException> errs() {
-        return errs;
+        return errs != null ? errs : Collections.emptyMap();
     }
 
     /**
@@ -125,7 +136,28 @@ public class StartRoutineDiscoveryMessage extends 
AbstractContinuousMessage {
 
     /** {@inheritDoc} */
     @Override public DiscoveryCustomMessage ackMessage() {
-        return new StartRoutineAckDiscoveryMessage(routineId, errs, 
updateCntrs, updateCntrsPerNode);
+        return new StartRoutineAckDiscoveryMessage(routineId, errs(), 
updateCntrs, updateCntrsPerNode);
+    }
+
+    /** */
+    private void readObject(ObjectInputStream in) throws IOException {
+        // Override default serialization in order to tolerate missing classes 
exceptions (e.g. remote filter class).
+        // We need this means because CQ registration process assumes that an 
"ack message" will be sent.
+        try {
+            in.defaultReadObject();
+        }
+        catch (ClassNotFoundException e) {
+            deserEx = e;
+
+            throw new IncompleteDeserializationException(this);
+        }
+    }
+
+    /**
+     * @return Exception occurred during deserialization.
+     */
+    @Nullable public ClassNotFoundException deserializationException() {
+        return deserEx;
     }
 
     /** {@inheritDoc} */
diff --git 
a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCustomEventMessage.java
 
b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCustomEventMessage.java
index bbbcdd7..bc7de6a 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCustomEventMessage.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryCustomEventMessage.java
@@ -18,6 +18,9 @@
 package org.apache.ignite.spi.discovery.tcp.messages;
 
 import java.util.UUID;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.managers.discovery.CustomMessageWrapper;
+import 
org.apache.ignite.internal.managers.discovery.IncompleteDeserializationException;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
@@ -96,7 +99,16 @@ public class TcpDiscoveryCustomEventMessage extends 
TcpDiscoveryAbstractMessage
      */
     @Nullable public DiscoverySpiCustomMessage message(@NotNull Marshaller 
marsh, ClassLoader ldr) throws Throwable {
         if (msg == null) {
-            msg = U.unmarshal(marsh, msgBytes, ldr);
+            try {
+                msg = U.unmarshal(marsh, msgBytes, ldr);
+            }
+            catch (IgniteCheckedException e) {
+                // Try to resurrect a message in a case of deserialization 
failure
+                if (e.getCause() instanceof IncompleteDeserializationException)
+                    return new 
CustomMessageWrapper(((IncompleteDeserializationException)e.getCause()).message());
+
+                throw e;
+            }
 
             assert msg != null;
         }
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/managers/discovery/IncompleteDeserializationExceptionTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/managers/discovery/IncompleteDeserializationExceptionTest.java
new file mode 100644
index 0000000..636c46b
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/managers/discovery/IncompleteDeserializationExceptionTest.java
@@ -0,0 +1,132 @@
+/*
+ * 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.internal.managers.discovery;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.UUID;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.jetbrains.annotations.Nullable;
+import org.junit.Test;
+
+/** */
+public class IncompleteDeserializationExceptionTest extends 
GridCommonAbstractTest {
+    /** */
+    private Path tmpDir;
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        super.beforeTest();
+
+        tmpDir = Files.createTempDirectory(UUID.randomUUID().toString());
+
+        Files.createDirectories(tmpDir);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        Files.delete(tmpDir);
+
+        super.afterTest();
+    }
+
+    /** */
+    @Test
+    public void testMissingClassDeserialization() throws Exception {
+        try (ObjectInputStream in = new 
ObjectInputStream(getClass().getResourceAsStream("Wrapper.ser"))) {
+            in.readObject();
+
+            fail("Exception is expected");
+        }
+        catch (IncompleteDeserializationException e) {
+            Wrapper wrp = (Wrapper)e.message();
+
+            assertNotNull(wrp);
+            assertEquals(42, wrp.i);
+            assertNull(wrp.o);
+        }
+    }
+
+    /** */
+    public static class Wrapper implements DiscoveryCustomMessage {
+        /** */
+        private static final long serialVersionUID = 0;
+
+        /** */
+        private final int i;
+
+        /** */
+        private final Object o;
+
+        /** */
+        private Wrapper(int i, Object o) {
+            this.i = i;
+            this.o = o;
+        }
+
+        /** */
+        private void readObject(ObjectInputStream in) throws IOException {
+            try {
+                in.defaultReadObject();
+            }
+            catch (ClassNotFoundException e) {
+                throw new IncompleteDeserializationException(this);
+            }
+        }
+
+        /** {@inheritDoc} */
+        @Override public IgniteUuid id() {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public @Nullable DiscoveryCustomMessage ackMessage() {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean isMutable() {
+            return false;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean stopProcess() {
+            return false;
+        }
+
+        /** {@inheritDoc} */
+        @Override public DiscoCache createDiscoCache(GridDiscoveryManager mgr, 
AffinityTopologyVersion topVer,
+            DiscoCache discoCache) {
+            return null;
+        }
+    }
+
+    // Commented lines were used to prepare serialized object
+//    public static void main(String[] args) throws IOException {
+//        try (ObjectOutputStream out = new ObjectOutputStream(new 
FileOutputStream("Wrapper.ser"))) {
+//            out.writeObject(new Wrapper(42, new ForeignClass()));
+//        }
+//    }
+//
+//    public static class ForeignClass implements Serializable {
+//    }
+}
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/ContinuousQueryRemoteFilterMissingInClassPathSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/ContinuousQueryRemoteFilterMissingInClassPathSelfTest.java
index 657f4e4..6d8ddfd 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/ContinuousQueryRemoteFilterMissingInClassPathSelfTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/ContinuousQueryRemoteFilterMissingInClassPathSelfTest.java
@@ -17,6 +17,14 @@
 
 package org.apache.ignite.internal.processors.cache.query.continuous;
 
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import javax.cache.configuration.Factory;
+import javax.cache.event.CacheEntryEvent;
+import javax.cache.event.CacheEntryEventFilter;
+import javax.cache.event.CacheEntryListenerException;
+import javax.cache.event.CacheEntryUpdatedListener;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.IgniteCheckedException;
@@ -26,21 +34,14 @@ import org.apache.ignite.cache.CacheMode;
 import org.apache.ignite.cache.query.ContinuousQuery;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.util.typedef.X;
+import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.testframework.GridStringLogger;
 import org.apache.ignite.testframework.GridTestUtils;
 import org.apache.ignite.testframework.ListeningTestLogger;
 import org.apache.ignite.testframework.LogListener;
 import org.apache.ignite.testframework.config.GridTestProperties;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-
-import javax.cache.configuration.Factory;
-import javax.cache.event.CacheEntryEvent;
-import javax.cache.event.CacheEntryEventFilter;
-import javax.cache.event.CacheEntryListenerException;
-import javax.cache.event.CacheEntryUpdatedListener;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
 import org.junit.Test;
 
 /**
@@ -50,6 +51,9 @@ public class 
ContinuousQueryRemoteFilterMissingInClassPathSelfTest extends GridC
     /** URL of classes. */
     private static final URL[] URLS;
 
+    /** */
+    public static final String EXT_FILTER_CLASS = 
"org.apache.ignite.tests.p2p.CacheDeploymentCacheEntryEventSerializableFilter";
+
     static {
         try {
             URLS = new URL[] {new 
URL(GridTestProperties.getProperty("p2p.uri.cls"))};
@@ -69,7 +73,10 @@ public class 
ContinuousQueryRemoteFilterMissingInClassPathSelfTest extends GridC
     private boolean setExternalLoader;
 
     /** */
-    private ClassLoader ldr;
+    private final ClassLoader extLdr = new URLClassLoader(URLS, 
getClass().getClassLoader());
+
+    /** */
+    private boolean setFilterAttr;
 
     /** {@inheritDoc} */
     @Override protected void afterTest() throws Exception {
@@ -84,19 +91,23 @@ public class 
ContinuousQueryRemoteFilterMissingInClassPathSelfTest extends GridC
 
         cfg.setClientMode(clientMode);
 
-        CacheConfiguration cacheCfg = new 
CacheConfiguration(DEFAULT_CACHE_NAME);
-
-        cacheCfg.setName("simple");
+        CacheConfiguration<Object, Object> cacheCfg = new 
CacheConfiguration<>(DEFAULT_CACHE_NAME);
 
         cacheCfg.setCacheMode(CacheMode.PARTITIONED);
 
+        cacheCfg.setNodeFilter(node -> node.attribute("filter") == null);
+
         cfg.setCacheConfiguration(cacheCfg);
 
         if (setExternalLoader)
-            cfg.setClassLoader(ldr);
-        else
+            cfg.setClassLoader(extLdr);
+
+        if (log != null)
             cfg.setGridLogger(log);
 
+        if (setFilterAttr)
+            cfg.setUserAttributes(U.map("filter", 1));
+
         return cfg;
     }
 
@@ -104,14 +115,12 @@ public class 
ContinuousQueryRemoteFilterMissingInClassPathSelfTest extends GridC
      * @throws Exception If fail.
      */
     @Test
-    public void testWarningMessageOnClientNode() throws Exception {
-        ldr = new URLClassLoader(URLS, getClass().getClassLoader());
-
+    public void testClientJoinsMissingClassWarning() throws Exception {
         clientMode = false;
         setExternalLoader = true;
-        final Ignite ignite0 = startGrid(1);
+        Ignite ignite0 = startGrid(1);
 
-        executeContinuousQuery(ignite0.cache("simple"));
+        executeContinuousQuery(ignite0.cache(DEFAULT_CACHE_NAME));
 
         log = new GridStringLogger();
         clientMode = true;
@@ -129,15 +138,13 @@ public class 
ContinuousQueryRemoteFilterMissingInClassPathSelfTest extends GridC
      * @throws Exception If fail.
      */
     @Test
-    public void testNoWarningMessageOnClientNode() throws Exception {
-        ldr = new URLClassLoader(URLS, getClass().getClassLoader());
-
+    public void testClientJoinsExtClassLoaderNoWarning() throws Exception {
         setExternalLoader = true;
 
         clientMode = false;
-        final Ignite ignite0 = startGrid(1);
+        Ignite ignite0 = startGrid(1);
 
-        executeContinuousQuery(ignite0.cache("simple"));
+        executeContinuousQuery(ignite0.cache(DEFAULT_CACHE_NAME));
 
         log = new GridStringLogger();
         clientMode = true;
@@ -152,15 +159,13 @@ public class 
ContinuousQueryRemoteFilterMissingInClassPathSelfTest extends GridC
      * @throws Exception If fail.
      */
     @Test
-    public void testExceptionOnServerNode() throws Exception {
-        ldr = new URLClassLoader(URLS, getClass().getClassLoader());
-
+    public void testServerJoinsMissingClassException() throws Exception {
         clientMode = false;
 
         setExternalLoader = true;
-        final Ignite ignite0 = startGrid(1);
+        Ignite ignite0 = startGrid(1);
 
-        executeContinuousQuery(ignite0.cache("simple"));
+        executeContinuousQuery(ignite0.cache(DEFAULT_CACHE_NAME));
 
         ListeningTestLogger listeningLogger = new ListeningTestLogger();
 
@@ -185,15 +190,13 @@ public class 
ContinuousQueryRemoteFilterMissingInClassPathSelfTest extends GridC
      * @throws Exception If fail.
      */
     @Test
-    public void testNoExceptionOnServerNode() throws Exception {
-        ldr = new URLClassLoader(URLS, getClass().getClassLoader());
-
+    public void testServerJoinsExtClassLoaderNoException() throws Exception {
         clientMode = false;
 
         setExternalLoader = true;
-        final Ignite ignite0 = startGrid(1);
+        Ignite ignite0 = startGrid(1);
 
-        executeContinuousQuery(ignite0.cache("simple"));
+        executeContinuousQuery(ignite0.cache(DEFAULT_CACHE_NAME));
 
         log = new GridStringLogger();
 
@@ -204,10 +207,75 @@ public class 
ContinuousQueryRemoteFilterMissingInClassPathSelfTest extends GridC
     }
 
     /**
+     * @throws Exception If fail.
+     */
+    @Test
+    public void testServerMissingClassFailsRegistration() throws Exception {
+        clientMode = false;
+
+        setExternalLoader = true;
+
+        Ignite ign1 = startGrid(1);
+
+        setExternalLoader = false;
+
+        startGrid(2);
+
+        try {
+            executeContinuousQuery(ign1.cache(DEFAULT_CACHE_NAME));
+
+            fail("Exception is expected");
+        }
+        catch (Exception e) {
+            assertTrue(X.hasCause(e, EXT_FILTER_CLASS, 
ClassNotFoundException.class));
+        }
+    }
+
+    /**
+     * @throws Exception If fail.
+     */
+    @Test
+    public void testClientMissingClassDoesNotFailRegistration() throws 
Exception {
+        clientMode = false;
+
+        setExternalLoader = true;
+
+        Ignite ign1 = startGrid(1);
+
+        setExternalLoader = false;
+
+        clientMode = true;
+
+        startGrid(2);
+
+        executeContinuousQuery(ign1.cache(DEFAULT_CACHE_NAME));
+    }
+
+    /**
+     * @throws Exception If fail.
+     */
+    @Test
+    public void testNodeFilterServerMissingClassDoesNotFailRegistration() 
throws Exception {
+        clientMode = false;
+
+        setExternalLoader = true;
+
+        Ignite ign1 = startGrid(1);
+
+        setExternalLoader = false;
+
+        setFilterAttr = true;
+
+        startGrid(2);
+
+        executeContinuousQuery(ign1.cache(DEFAULT_CACHE_NAME));
+    }
+
+    /**
      * @param cache Ignite cache.
      * @throws Exception If fail.
      */
-    private void executeContinuousQuery(IgniteCache cache) throws Exception {
+    private void executeContinuousQuery(IgniteCache<Object, Object> cache) 
throws Exception {
         ContinuousQuery<Integer, String> qry = new ContinuousQuery<>();
 
         qry.setLocalListener(
@@ -220,10 +288,10 @@ public class 
ContinuousQueryRemoteFilterMissingInClassPathSelfTest extends GridC
             }
         );
 
-        final Class<CacheEntryEventSerializableFilter> remoteFilterClass = 
(Class<CacheEntryEventSerializableFilter>)
-            
ldr.loadClass("org.apache.ignite.tests.p2p.CacheDeploymentCacheEntryEventSerializableFilter");
+        Class<CacheEntryEventSerializableFilter> remoteFilterCls = 
(Class<CacheEntryEventSerializableFilter>)
+            extLdr.loadClass(EXT_FILTER_CLASS);
 
-        qry.setRemoteFilterFactory(new ClassFilterFactory(remoteFilterClass));
+        qry.setRemoteFilterFactory(new ClassFilterFactory(remoteFilterCls));
 
         cache.query(qry);
 
@@ -248,7 +316,7 @@ public class 
ContinuousQueryRemoteFilterMissingInClassPathSelfTest extends GridC
         /** {@inheritDoc} */
         @Override public CacheEntryEventSerializableFilter<Integer, String> 
create() {
             try {
-                return cls.newInstance();
+                return (CacheEntryEventSerializableFilter<Integer, 
String>)cls.newInstance();
             }
             catch (Exception e) {
                 throw new RuntimeException(e);
diff --git 
a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java
 
b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java
index e4097a5..beeea1a 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java
@@ -44,6 +44,7 @@ import 
org.apache.ignite.internal.MarshallerContextLockingSelfTest;
 import org.apache.ignite.internal.TransactionsMXBeanImplTest;
 import 
org.apache.ignite.internal.managers.IgniteDiagnosticMessagesMultipleConnectionsTest;
 import org.apache.ignite.internal.managers.IgniteDiagnosticMessagesTest;
+import 
org.apache.ignite.internal.managers.discovery.IncompleteDeserializationExceptionTest;
 import org.apache.ignite.internal.processors.DeadLockOnNodeLeftExchangeTest;
 import 
org.apache.ignite.internal.processors.affinity.GridAffinityAssignmentV2Test;
 import 
org.apache.ignite.internal.processors.affinity.GridAffinityAssignmentV2TestNoOptimizations;
@@ -97,8 +98,8 @@ import org.apache.ignite.plugin.PluginNodeValidationTest;
 import org.apache.ignite.plugin.security.SecurityPermissionSetBuilderTest;
 import org.apache.ignite.spi.GridSpiLocalHostInjectionTest;
 import org.apache.ignite.startup.properties.NotStringSystemPropertyTest;
-import org.apache.ignite.testframework.test.ConfigVariationsExecutionTest;
 import org.apache.ignite.testframework.MessageOrderLogListenerTest;
+import org.apache.ignite.testframework.test.ConfigVariationsExecutionTest;
 import 
org.apache.ignite.testframework.test.ConfigVariationsTestSuiteBuilderTest;
 import org.apache.ignite.testframework.test.ListeningTestLoggerTest;
 import org.apache.ignite.testframework.test.ParametersTest;
@@ -233,16 +234,18 @@ import org.junit.runners.Suite;
 
     ConsistentIdImplicitlyExplicitlyTest.class,
 
-        // Tests against configuration variations framework.
-        ParametersTest.class,
-        VariationsIteratorTest.class,
-        NotStringSystemPropertyTest.class,
-        ConfigVariationsExecutionTest.class,
-        ConfigVariationsTestSuiteBuilderTest.class,
+    // Tests against configuration variations framework.
+    ParametersTest.class,
+    VariationsIteratorTest.class,
+    NotStringSystemPropertyTest.class,
+    ConfigVariationsExecutionTest.class,
+    ConfigVariationsTestSuiteBuilderTest.class,
 
     DeadLockOnNodeLeftExchangeTest.class,
 
-    ClassPathContentLoggingTest.class
+    ClassPathContentLoggingTest.class,
+
+    IncompleteDeserializationExceptionTest.class
 })
 public class IgniteBasicTestSuite {
 }
diff --git 
a/modules/core/src/test/resources/org/apache/ignite/internal/managers/discovery/Wrapper.ser
 
b/modules/core/src/test/resources/org/apache/ignite/internal/managers/discovery/Wrapper.ser
new file mode 100644
index 0000000..cbf16a8
Binary files /dev/null and 
b/modules/core/src/test/resources/org/apache/ignite/internal/managers/discovery/Wrapper.ser
 differ

Reply via email to