This is an automated email from the ASF dual-hosted git repository. ilyak 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 c8a3b90 IGNITE-13103 Fix SerializedLambda deployment by not registering capturingClass with marshaller - Fixes #7880. c8a3b90 is described below commit c8a3b905ad6585c36d2bbb3e030162d09c72922c Author: Ilya Kasnacheev <ilya.kasnach...@gmail.com> AuthorDate: Mon Jun 8 10:51:20 2020 +0300 IGNITE-13103 Fix SerializedLambda deployment by not registering capturingClass with marshaller - Fixes #7880. Signed-off-by: Ilya Kasnacheev <ilya.kasnach...@gmail.com> --- .../ignite/internal/binary/BinaryWriterExImpl.java | 2 +- .../apache/ignite/p2p/SharedDeploymentTest.java | 54 ++++++++++++++++++++++ .../ignite/tests/p2p/compute/ExternalLambda.java | 40 ++++++++++++++++ .../ignite/tests/p2p/compute/ExternalLambda.java | 40 ++++++++++++++++ 4 files changed, 135 insertions(+), 1 deletion(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java index 7a91f77..db7833e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java @@ -911,7 +911,7 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje if (val == null) out.writeByte(GridBinaryMarshaller.NULL); else { - BinaryClassDescriptor desc = ctx.registerClass(val, true, failIfUnregistered); + BinaryClassDescriptor desc = ctx.registerClass(val, false, failIfUnregistered); out.unsafeEnsure(1 + 4); diff --git a/modules/core/src/test/java/org/apache/ignite/p2p/SharedDeploymentTest.java b/modules/core/src/test/java/org/apache/ignite/p2p/SharedDeploymentTest.java index 21dbdac..7dbda9d 100644 --- a/modules/core/src/test/java/org/apache/ignite/p2p/SharedDeploymentTest.java +++ b/modules/core/src/test/java/org/apache/ignite/p2p/SharedDeploymentTest.java @@ -17,6 +17,7 @@ package org.apache.ignite.p2p; +import java.lang.reflect.Method; import org.apache.ignite.Ignite; import org.apache.ignite.configuration.DeploymentMode; import org.apache.ignite.configuration.IgniteConfiguration; @@ -41,6 +42,9 @@ public class SharedDeploymentTest extends GridCommonAbstractTest { /** */ private static final String RUN_CLS2 = "org.apache.ignite.tests.p2p.compute.ExternalCallable2"; + /** */ + private static final String RUN_LAMBDA = "org.apache.ignite.tests.p2p.compute.ExternalLambda"; + /** {@inheritDoc} */ @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { return super.getConfiguration(igniteInstanceName) @@ -93,6 +97,47 @@ public class SharedDeploymentTest extends GridCommonAbstractTest { } /** + * Start a cluster of 3 server nodes. + * Broadcast a lambda callable deployed on node 3 from first classpath. Check correct return values. + * Restart node 3 + * Broadcast a lambda callable deployed on node 3 from second classpath, declared in binary incompatible class + * (type of field changed). Check corresponding return values. + * + * Expected behavior: no errors. + * Problematic behavior: marshalling exception due to lambda capturing class binary incompatibility. + * + * @throws Exception if failed. + */ + @Test + public void testLambdaDeploymentFromSecondAndThird() throws Exception { + try { + startGrid(1); + startGrid(2); + + Ignite ignite3 = startGrid(3); + + Collection<Object> res = runLambda(new GridTestExternalClassLoader(new URL[] { + new URL(GridTestProperties.getProperty("p2p.uri.cls"))}), ignite3, 10_000); + + for (Object o: res) + assertEquals(o, 42); + + ignite3.close(); + + ignite3 = startGrid(3); + + res = runLambda(new GridTestExternalClassLoader(new URL[] { + new URL(GridTestProperties.getProperty("p2p.uri.cls.second"))}), ignite3, 10_000); + + for (Object o: res) + assertEquals(o, 43); + } + finally { + stopAllGrids(); + } + } + + /** * @param ignite Ignite instance. * @param timeout Timeout. * @param param Parameter. @@ -127,4 +172,13 @@ public class SharedDeploymentTest extends GridCommonAbstractTest { return ignite.compute().withTimeout(timeout).broadcast((IgniteCallable<Object>)ctor.newInstance(param)); } + + /** + * @throws Exception If failed. + */ + private Collection<Object> runLambda(ClassLoader testClassLoader, Ignite ignite, long timeout) throws Exception { + Method m = testClassLoader.loadClass(RUN_LAMBDA).getMethod("lambda", new Class[0]); + + return ignite.compute().withTimeout(timeout).broadcast((IgniteCallable<Object>)m.invoke(null, new Object[0])); + } } diff --git a/modules/extdata/p2p/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalLambda.java b/modules/extdata/p2p/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalLambda.java new file mode 100644 index 0000000..5dfc67b --- /dev/null +++ b/modules/extdata/p2p/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalLambda.java @@ -0,0 +1,40 @@ +/* + * 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.tests.p2p.compute; + +import org.apache.ignite.lang.IgniteCallable; + +/** + */ +public class ExternalLambda { + /** */ + private String param; + + /** */ + private ExternalLambda() { + // No-op. + } + + /** */ + public static IgniteCallable<Integer> lambda() { + return () -> { + System.err.println("!!!!! I am a lambda!"); + return 42; + }; + } +} diff --git a/modules/extdata/uri/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalLambda.java b/modules/extdata/uri/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalLambda.java new file mode 100644 index 0000000..c6ddc49 --- /dev/null +++ b/modules/extdata/uri/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalLambda.java @@ -0,0 +1,40 @@ +/* + * 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.tests.p2p.compute; + +import org.apache.ignite.lang.IgniteCallable; + +/** + */ +public class ExternalLambda { + /** */ + private int param; + + /** */ + private ExternalLambda() { + // No-op. + } + + /** */ + public static IgniteCallable<Integer> lambda() { + return () -> { + System.err.println("!!!!! I am a modified lambda!"); + return 43; + }; + } +}