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