You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by se...@apache.org on 2021/05/11 09:03:43 UTC
[ignite] branch master updated: IGNITE-14131 IgniteCompute tasks
with same name,
running from one node and different ClassLoaders can lead to OOM - Fixes
#9020.
This is an automated email from the ASF dual-hosted git repository.
sergeychugunov 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 4928ca5 IGNITE-14131 IgniteCompute tasks with same name, running from one node and different ClassLoaders can lead to OOM - Fixes #9020.
4928ca5 is described below
commit 4928ca57955a4ab9dd3bbcbad8adf29ddaa36cf2
Author: zstan <st...@gmail.com>
AuthorDate: Tue May 11 11:32:46 2021 +0300
IGNITE-14131 IgniteCompute tasks with same name, running from one node and different ClassLoaders can lead to OOM - Fixes #9020.
Signed-off-by: Sergey Chugunov <se...@gmail.com>
---
.../main/java/org/apache/ignite/IgniteCompute.java | 4 +
.../deployment/GridDeploymentLocalStore.java | 174 ++++++++++----------
.../deployment/GridDeploymentPerLoaderStore.java | 2 +-
.../apache/ignite/internal/util/IgniteUtils.java | 14 ++
.../spi/deployment/local/LocalDeploymentSpi.java | 100 +++++++-----
.../GridMultipleVersionsDeploymentSelfTest.java | 2 +-
.../ignite/internal/GridSpiExceptionSelfTest.java | 3 +-
.../IgniteExplicitImplicitDeploymentSelfTest.java | 178 ++++++++++++---------
.../RaceOnDeployClassesWithSameAliases.java | 147 -----------------
.../GridDeploymentManagerStopSelfTest.java | 4 +-
.../GridDifferentLocalDeploymentSelfTest.java | 162 +++++++++++++++++++
.../distributed/IgniteCacheSizeFailoverTest.java | 2 +-
.../apache/ignite/p2p/GridP2PUndeploySelfTest.java | 41 ++++-
.../local/GridLocalDeploymentSpiSelfTest.java | 54 +++++--
.../ignite/testsuites/IgniteP2PSelfTestSuite.java | 6 +-
15 files changed, 523 insertions(+), 370 deletions(-)
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteCompute.java b/modules/core/src/main/java/org/apache/ignite/IgniteCompute.java
index fb2db2f..f686d77 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteCompute.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteCompute.java
@@ -371,6 +371,10 @@ public interface IgniteCompute extends IgniteAsyncSupport {
* <p>
* If task for given name has not been deployed yet, then {@code taskName} will be
* used as task class name to auto-deploy the task (see {@link #localDeployTask(Class, ClassLoader)} method).
+ * <p>
+ * If class with the same name was deployed more than once, the last deployed version is used.
+ * If method is called when other threads are deploying other versions of class with the same name there are no
+ * guarantees which version of the class will be executed.
*
* @param taskName Name of the task to execute.
* @param arg Optional argument of task execution, can be {@code null}.
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentLocalStore.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentLocalStore.java
index 89d7bcf..ecf9bf8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentLocalStore.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentLocalStore.java
@@ -90,7 +90,7 @@ class GridDeploymentLocalStore extends GridDeploymentStoreAdapter {
Map<String, Collection<GridDeployment>> cp;
synchronized (mux) {
- cp = new HashMap<String, Collection<GridDeployment>>(cache);
+ cp = new HashMap<>(cache);
for (Entry<String, Collection<GridDeployment>> entry : cp.entrySet())
entry.setValue(new ArrayList<>(entry.getValue()));
@@ -145,7 +145,7 @@ class GridDeploymentLocalStore extends GridDeploymentStoreAdapter {
// Validate metadata.
assert alias != null : "Meta is invalid: " + meta;
- GridDeployment dep = deployment(alias);
+ GridDeployment dep = deployment(meta);
if (dep != null) {
if (log.isDebugEnabled())
@@ -154,74 +154,66 @@ class GridDeploymentLocalStore extends GridDeploymentStoreAdapter {
return dep;
}
- DeploymentResource rsrc = spi.findResource(alias);
+ if (meta.classLoader() == null) {
+ DeploymentResource rsrc = spi.findResource(alias);
- if (rsrc != null) {
- dep = deploy(ctx.config().getDeploymentMode(), rsrc.getClassLoader(), rsrc.getResourceClass(), alias,
- meta.record());
+ if (rsrc != null) {
+ dep = deploy(ctx.config().getDeploymentMode(), rsrc.getClassLoader(), rsrc.getResourceClass(), alias,
+ meta.record());
- assert dep != null;
+ assert dep != null;
- if (log.isDebugEnabled())
- log.debug("Acquired deployment class from SPI: " + dep);
- }
- // Auto-deploy.
- else {
- ClassLoader ldr = meta.classLoader();
-
- if (ldr == null) {
- ldr = Thread.currentThread().getContextClassLoader();
-
- // Safety.
- if (ldr == null)
- ldr = U.resolveClassLoader(ctx.config());
- }
-
- if (ldr instanceof GridDeploymentClassLoader) {
if (log.isDebugEnabled())
- log.debug("Skipping local auto-deploy (nested execution) [ldr=" + ldr + ", meta=" + meta + ']');
+ log.debug("Acquired deployment class from SPI: " + dep);
- return null;
+ return dep;
}
+ }
- while (true) {
- try {
- // Check that class can be loaded.
- String clsName = meta.className();
+ // Auto-deploy.
+ ClassLoader ldr = meta.classLoader();
- Class<?> cls = U.forName(clsName != null ? clsName : alias, ldr);
+ if (ldr == null) {
+ ldr = Thread.currentThread().getContextClassLoader();
- spi.register(ldr, cls);
+ // Safety.
+ if (ldr == null)
+ ldr = U.resolveClassLoader(ctx.config());
+ }
- rsrc = spi.findResource(cls.getName());
+ if (ldr instanceof GridDeploymentClassLoader) {
+ if (log.isDebugEnabled())
+ log.debug("Skipping local auto-deploy (nested execution) [ldr=" + ldr + ", meta=" + meta + ']');
- if (rsrc != null && rsrc.getResourceClass().equals(cls)) {
- if (log.isDebugEnabled())
- log.debug("Retrieved auto-loaded resource from spi: " + rsrc);
+ return null;
+ }
- dep = deploy(ctx.config().getDeploymentMode(), ldr, cls, meta.alias(), meta.record());
+ try {
+ // Check that class can be loaded.
+ String clsName = meta.className();
- if (dep != null)
- return dep;
- }
- else {
- U.warn(log, "Failed to find resource from deployment SPI even after registering: " + meta);
+ Class<?> cls = U.forName(clsName != null ? clsName : alias, ldr);
- return null;
- }
+ if (spi.register(ldr, cls)) {
+ if (log.isDebugEnabled()) {
+ log.debug("Resource registered automatically: [name=" + U.getResourceName(cls)
+ + ", class=" + cls.getName()
+ + ", ldr=" + ldr + ']');
}
- catch (ClassNotFoundException ignored) {
- if (log.isDebugEnabled())
- log.debug("Failed to load class for local auto-deployment [ldr=" + ldr + ", meta=" + meta + ']');
+ }
- return null;
- }
- catch (IgniteSpiException e) {
- U.error(log, "Failed to deploy local class with meta: " + meta, e);
+ dep = deploy(ctx.config().getDeploymentMode(), ldr, cls, alias, meta.record());
+ }
+ catch (ClassNotFoundException ignored) {
+ if (log.isDebugEnabled())
+ log.debug("Failed to load class for local auto-deployment [ldr=" + ldr + ", meta=" + meta + ']');
- return null;
- }
- }
+ return null;
+ }
+ catch (IgniteSpiException e) {
+ U.error(log, "Failed to deploy local class with meta: " + meta, e);
+
+ return null;
}
if (log.isDebugEnabled())
@@ -232,23 +224,36 @@ class GridDeploymentLocalStore extends GridDeploymentStoreAdapter {
/** {@inheritDoc} */
@Override public GridDeployment searchDeploymentCache(GridDeploymentMetadata meta) {
- return deployment(meta.alias());
+ return deployment(meta);
}
/**
- * @param alias Class alias.
+ * @param meta Deployment meta.
* @return Deployment.
*/
- @Nullable private GridDeployment deployment(String alias) {
- Deque<GridDeployment> deps = cache.get(alias);
+ @Nullable private GridDeployment deployment(final GridDeploymentMetadata meta) {
+ Deque<GridDeployment> deps = cache.get(meta.alias());
if (deps != null) {
- GridDeployment dep = deps.peekFirst();
+ for (GridDeployment dep : deps) {
+ if (dep.undeployed())
+ continue;
- if (dep != null && !dep.undeployed())
- return dep;
+ // local or remote deployment.
+ if (dep.classLoaderId() == meta.classLoaderId() || dep.classLoader() == meta.classLoader()) {
+ if (log.isTraceEnabled())
+ log.trace("Deployment was found for class with specific class loader [alias=" + meta.alias() +
+ ", clsLdrId=" + meta.classLoaderId() + "]");
+
+ return dep;
+ }
+ }
}
+ if (log.isDebugEnabled())
+ log.debug("Deployment was not found for class with specific class loader [alias=" + meta.alias() +
+ ", clsLdrId=" + meta.classLoaderId() + "]");
+
return null;
}
@@ -260,8 +265,13 @@ class GridDeploymentLocalStore extends GridDeploymentStoreAdapter {
* @param recordEvt {@code True} to record event.
* @return Deployment.
*/
- private GridDeployment deploy(DeploymentMode depMode, ClassLoader ldr, Class<?> cls, String alias,
- boolean recordEvt) {
+ private GridDeployment deploy(
+ DeploymentMode depMode,
+ ClassLoader ldr,
+ Class<?> cls,
+ String alias,
+ boolean recordEvt
+ ) {
GridDeployment dep = null;
synchronized (mux) {
@@ -294,9 +304,10 @@ class GridDeploymentLocalStore extends GridDeploymentStoreAdapter {
cache.put(alias, cachedDeps);
- if (!cls.getName().equals(alias))
+ if (!cls.getName().equals(alias)) {
// Cache by class name as well.
cache.put(cls.getName(), cachedDeps);
+ }
return dep;
}
@@ -318,23 +329,13 @@ class GridDeploymentLocalStore extends GridDeploymentStoreAdapter {
ConcurrentLinkedDeque::new
);
- if (!deps.isEmpty()) {
- for (GridDeployment d : deps) {
- if (!d.undeployed()) {
- U.error(log, "Found more than one active deployment for the same resource " +
- "[cls=" + cls + ", depMode=" + depMode + ", dep=" + d + ']');
-
- return null;
- }
- }
- }
-
// Add at the beginning of the list for future fast access.
deps.addFirst(dep);
- if (!cls.getName().equals(alias))
+ if (!cls.getName().equals(alias)) {
// Cache by class name as well.
cache.put(cls.getName(), deps);
+ }
if (log.isDebugEnabled())
log.debug("Created new deployment: " + dep);
@@ -356,20 +357,23 @@ class GridDeploymentLocalStore extends GridDeploymentStoreAdapter {
if (clsLdr.getClass().equals(GridDeploymentClassLoader.class))
clsLdr = clsLdr.getParent();
- GridDeployment dep = null;
+ if (spi.register(clsLdr, cls)) {
+ if (log.isDebugEnabled()) {
+ log.debug("Resource registered automatically: [name=" + U.getResourceName(cls)
+ + ", class=" + cls.getName() + ", ldr=" + clsLdr + ']');
+ }
+ }
- while (dep == null) {
- spi.register(clsLdr, cls);
+ GridDeploymentMetadata meta = new GridDeploymentMetadata();
- dep = deployment(cls.getName());
+ meta.alias(cls.getName());
+ meta.classLoader(clsLdr);
- if (dep == null) {
- DeploymentResource rsrc = spi.findResource(cls.getName());
+ GridDeployment dep = deployment(meta);
- if (rsrc != null && rsrc.getClassLoader() == clsLdr)
- dep = deploy(ctx.config().getDeploymentMode(), rsrc.getClassLoader(),
- rsrc.getResourceClass(), rsrc.getName(), true);
- }
+ if (dep == null) {
+ dep = deploy(ctx.config().getDeploymentMode(), clsLdr,
+ cls, U.getResourceName(cls), true);
}
return dep;
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerLoaderStore.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerLoaderStore.java
index 0477523..ba68e1bc 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerLoaderStore.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerLoaderStore.java
@@ -183,7 +183,7 @@ public class GridDeploymentPerLoaderStore extends GridDeploymentStoreAdapter {
/** {@inheritDoc} */
@Override public Collection<GridDeployment> getDeployments() {
synchronized (mux) {
- return new LinkedList<GridDeployment>(cache.values());
+ return new LinkedList<>(cache.values());
}
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
index de79bf8..37d6505 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
@@ -6024,6 +6024,20 @@ public abstract class IgniteUtils {
}
/**
+ * Gets resource name.
+ * Returns a task name if it is a Compute task or a class name otherwise.
+ *
+ * @param rscCls Class of resource.
+ * @return Name of resource.
+ */
+ public static String getResourceName(Class rscCls) {
+ if (ComputeTask.class.isAssignableFrom(rscCls))
+ return getTaskName(rscCls);
+
+ return rscCls.getName();
+ }
+
+ /**
* Creates SPI attribute name by adding prefix to the attribute name.
* Prefix is an SPI name + '.'.
*
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/deployment/local/LocalDeploymentSpi.java b/modules/core/src/main/java/org/apache/ignite/spi/deployment/local/LocalDeploymentSpi.java
index d726baf..1748506 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/deployment/local/LocalDeploymentSpi.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/deployment/local/LocalDeploymentSpi.java
@@ -22,7 +22,6 @@ import java.util.Collection;
import java.util.LinkedList;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.IgniteSystemProperties;
@@ -82,8 +81,7 @@ public class LocalDeploymentSpi extends IgniteSpiAdapter implements DeploymentSp
private IgniteLogger log;
/** Map of all resources. */
- private ConcurrentLinkedHashMap<ClassLoader, ConcurrentMap<String, String>> ldrRsrcs =
- new ConcurrentLinkedHashMap<>(16, 0.75f, 64);
+ private volatile ConcurrentLinkedHashMap<ClassLoader, ConcurrentMap<String, String>> ldrRsrcs = new ConcurrentLinkedHashMap<>();
/** Deployment SPI listener. */
private volatile DeploymentListener lsnr;
@@ -110,36 +108,55 @@ public class LocalDeploymentSpi extends IgniteSpiAdapter implements DeploymentSp
log.debug(stopInfo());
}
- /** {@inheritDoc} */
+ /**
+ * Finds class loader for the given class.
+ *
+ * @param rsrcName Class name or class alias to find class loader for.
+ * @return Deployed class loader, or {@code null} if not deployed.
+ */
@Nullable @Override public DeploymentResource findResource(String rsrcName) {
- assert rsrcName != null;
-
- // Last updated class loader has highest priority in search.
for (Entry<ClassLoader, ConcurrentMap<String, String>> e : ldrRsrcs.descendingEntrySet()) {
ClassLoader ldr = e.getKey();
ConcurrentMap<String, String> rsrcs = e.getValue();
- String clsName = rsrcs.get(rsrcName);
+ DeploymentResourceAdapter res = findResource0(rsrcs, rsrcName, ldr);
- // Return class if it was found in resources map.
- if (clsName != null) {
- // Recalculate resource name in case if access is performed by
- // class name and not the resource name.
- rsrcName = getResourceName(clsName, rsrcs);
+ if (res != null)
+ return res;
+ }
- assert clsName != null;
+ return null;
+ }
- try {
- Class<?> cls = Class.forName(clsName, true, ldr);
+ /**
+ * Finds appropriate resource.
+ *
+ * @param rsrcs Resources.
+ * @param rsrcName Class name or class alias to find class loader for.
+ * @param clsLdr desired class loader.
+ * @return Deployed class loader, or {@code null} if not deployed.
+ */
+ @Nullable private DeploymentResourceAdapter findResource0(Map<String, String> rsrcs, String rsrcName, ClassLoader clsLdr) {
+ String clsName = rsrcs.get(rsrcName);
- assert cls != null;
+ // Return class if it was found in resources map.
+ if (clsName != null) {
+ // Recalculate resource name in case if access is performed by
+ // class name and not the resource name.
+ rsrcName = getResourceName(clsName, rsrcs);
- // Return resource.
- return new DeploymentResourceAdapter(rsrcName, cls, ldr);
- }
- catch (ClassNotFoundException ignored) {
- // No-op.
- }
+ assert clsName != null;
+
+ try {
+ Class<?> cls = U.forName(clsName, clsLdr);
+
+ assert cls != null;
+
+ // Return resource.
+ return new DeploymentResourceAdapter(rsrcName, cls, clsLdr);
+ }
+ catch (ClassNotFoundException e) {
+ log.warning("Can`t find appropriate class. ", e);
}
}
@@ -175,31 +192,31 @@ public class LocalDeploymentSpi extends IgniteSpiAdapter implements DeploymentSp
if (log.isDebugEnabled())
log.debug("Registering [ldrRsrcs=" + ldrRsrcs + ", ldr=" + ldr + ", rsrc=" + rsrc + ']');
- ConcurrentMap<String, String> clsLdrRsrcs = ldrRsrcs.getSafe(ldr);
-
- if (clsLdrRsrcs == null) {
- ConcurrentMap<String, String> old = ldrRsrcs.putIfAbsent(ldr,
- clsLdrRsrcs = new ConcurrentHashMap<>());
-
- if (old != null)
- clsLdrRsrcs = old;
- }
+ Map<String, String> newRsrcs;
- Map<String, String> newRsrcs = addResource(ldr, clsLdrRsrcs, rsrc);
+ ConcurrentLinkedHashMap<ClassLoader, ConcurrentMap<String, String>> ldrRsrcs0 =
+ new ConcurrentLinkedHashMap<>(ldrRsrcs);
- Collection<ClassLoader> rmvClsLdrs = null;
+ ConcurrentMap<String, String> clsLdrRsrcs = ldrRsrcs0.getSafe(ldr);
- if (!F.isEmpty(newRsrcs)) {
- rmvClsLdrs = new LinkedList<>();
+ // move forward, localDeployTask compatibility issue.
+ if (clsLdrRsrcs != null) {
+ if (ldrRsrcs0.remove(ldr) != null) {
+ ldrRsrcs0.put(ldr, clsLdrRsrcs);
- removeResources(ldr, newRsrcs, rmvClsLdrs);
+ ldrRsrcs = ldrRsrcs0;
+ }
}
+ else {
+ ConcurrentMap<String, String> old = ldrRsrcs.putIfAbsent(ldr,
+ clsLdrRsrcs == null ? clsLdrRsrcs = new ConcurrentLinkedHashMap<>() : clsLdrRsrcs);
- if (rmvClsLdrs != null) {
- for (ClassLoader cldLdr : rmvClsLdrs)
- onClassLoaderReleased(cldLdr);
+ if (old != null)
+ clsLdrRsrcs = old;
}
+ newRsrcs = addResource(ldr, clsLdrRsrcs, rsrc);
+
return !F.isEmpty(newRsrcs);
}
@@ -267,11 +284,12 @@ public class LocalDeploymentSpi extends IgniteSpiAdapter implements DeploymentSp
String oldCls = ldrRsrcs.putIfAbsent(entry.getKey(), entry.getValue());
if (oldCls != null) {
- if (!oldCls.equals(entry.getValue()))
+ if (!oldCls.equals(entry.getValue())) {
throw new IgniteSpiException("Failed to register resources with given task name " +
"(found another class with same task name in the same class loader) " +
"[taskName=" + entry.getKey() + ", existingCls=" + oldCls +
", newCls=" + entry.getValue() + ", ldr=" + ldr + ']');
+ }
}
else {
// New resource was added.
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/GridMultipleVersionsDeploymentSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/GridMultipleVersionsDeploymentSelfTest.java
index 95258cc..64f0742 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/GridMultipleVersionsDeploymentSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/GridMultipleVersionsDeploymentSelfTest.java
@@ -211,7 +211,7 @@ public class GridMultipleVersionsDeploymentSelfTest extends GridCommonAbstractTe
// Since we loader task/job classes with different class loaders we cannot
// use any kind of mutex because of the illegal state exception.
// We have to use timer here. DO NOT CHANGE 2 seconds here.
- Thread.sleep(2000);
+ Thread.sleep(1000);
// Deploy new one - this should move first task to the obsolete list.
g1.compute().localDeployTask(taskCls2, ldr2);
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/GridSpiExceptionSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/GridSpiExceptionSelfTest.java
index 0c8bf18..c7002fe 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/GridSpiExceptionSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/GridSpiExceptionSelfTest.java
@@ -143,8 +143,7 @@ public class GridSpiExceptionSelfTest extends GridCommonAbstractTest {
}
/** {@inheritDoc} */
- @Nullable @Override public DeploymentResource findResource(String rsrcName) {
- // No-op.
+ @Override public DeploymentResource findResource(String rsrcName) {
return null;
}
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/IgniteExplicitImplicitDeploymentSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/IgniteExplicitImplicitDeploymentSelfTest.java
index b38ede2..31839eb 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/IgniteExplicitImplicitDeploymentSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/IgniteExplicitImplicitDeploymentSelfTest.java
@@ -39,11 +39,11 @@ import org.apache.ignite.compute.ComputeTaskAdapter;
import org.apache.ignite.compute.ComputeTaskName;
import org.apache.ignite.configuration.DeploymentMode;
import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.internal.util.typedef.G;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.resources.IgniteInstanceResource;
import org.apache.ignite.resources.LoggerResource;
import org.apache.ignite.testframework.GridTestClassLoader;
+import org.apache.ignite.testframework.GridTestUtils;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.apache.ignite.testframework.junits.common.GridCommonTest;
import org.jetbrains.annotations.NotNull;
@@ -104,17 +104,59 @@ public class IgniteExplicitImplicitDeploymentSelfTest extends GridCommonAbstract
execExplicitDeployP2P(true, true, true);
}
- /**
- * @param ignite Grid.
+ /** Calls async compute execution with Class of the task.
+ *
+ * @param ignite Ignite server instance.
+ * @param client Ignite client instance.
+ * @param taskCls Class to compute.
+ * @param expected Expected result.
*/
- private void stopGrid(Ignite ignite) {
- try {
- if (ignite != null)
- G.stop(ignite.name(), true);
- }
- catch (Throwable e) {
- error("Got error when stopping grid.", e);
- }
+ private IgniteInternalFuture runAsyncByClass(
+ final IgniteEx ignite,
+ final IgniteEx client,
+ Class<? extends ComputeTask<String, Integer>> taskCls,
+ int expected
+ ) {
+ IgniteInternalFuture f = GridTestUtils.runAsync(() -> {
+ for (int i = 0; i < 10; ++i) {
+ Integer res1 = ignite.compute().execute(taskCls, null);
+ assertNotNull(res1);
+ assertEquals("Invalid res1: ", expected, (int)res1);
+
+ res1 = client.compute(ignite.compute().clusterGroup().forNodeId(ignite.localNode().id())).execute(taskCls, null);
+ assertNotNull(res1);
+ assertEquals("Invalid res1: ", expected, (int)res1);
+ }
+ });
+
+ return f;
+ }
+
+ /** Calls async compute execution with class instance.
+ * @param ignite Ignite server instance.
+ * @param client Ignite client instance.
+ * @param taskCls Instance to compute.
+ * @param expected Expected result.
+ */
+ private IgniteInternalFuture runAsyncByInstance(
+ final IgniteEx ignite,
+ final IgniteEx client,
+ ComputeTask<String, Integer> taskCls,
+ int expected
+ ) {
+ IgniteInternalFuture f = GridTestUtils.runAsync(() -> {
+ for (int i = 0; i < 10; ++i) {
+ Integer res1 = ignite.compute().execute(taskCls, null);
+ assertNotNull(res1);
+ assertEquals("Invalid res: ", expected, (int)res1);
+
+ res1 = client.compute(ignite.compute().clusterGroup().forNodeId(ignite.localNode().id())).execute(taskCls, null);
+ assertNotNull(res1);
+ assertEquals("Invalid res: ", expected, (int)res1);
+ }
+ });
+
+ return f;
}
/**
@@ -124,7 +166,7 @@ public class IgniteExplicitImplicitDeploymentSelfTest extends GridCommonAbstract
* @throws Exception If test failed.
*/
private void execExplicitDeployLocally(boolean byCls, boolean byTask, boolean byName) throws Exception {
- Ignite ignite = null;
+ Ignite ignite;
try {
ignite = startGrid();
@@ -171,14 +213,14 @@ public class IgniteExplicitImplicitDeploymentSelfTest extends GridCommonAbstract
if (byName) {
ignite.compute().localDeployTask(taskCls, ldr1);
- Integer res = (Integer) ignite.compute().execute(taskCls.getName(), null);
+ Integer res = ignite.compute().execute(taskCls.getName(), null);
assert res != null;
assert res == 1 : "Invalid response: " + res;
}
}
finally {
- stopGrid(ignite);
+ stopAllGrids();
}
}
@@ -189,11 +231,11 @@ public class IgniteExplicitImplicitDeploymentSelfTest extends GridCommonAbstract
* @throws Exception If test failed.
*/
private void execImplicitDeployLocally(boolean byCls, boolean byTask, boolean byName) throws Exception {
- Ignite ignite = null;
+ final IgniteEx ignite = startGrids(1);
- try {
- ignite = startGrid();
+ final IgniteEx client = startClientGrid(1);
+ try {
// First task class loader.
ClassLoader ldr1 = new GridTestClassLoader(
Collections.singletonMap("testResource", "1"),
@@ -218,45 +260,44 @@ public class IgniteExplicitImplicitDeploymentSelfTest extends GridCommonAbstract
ldr2.loadClass(GridDeploymentResourceTestTask.class.getName());
if (byCls) {
- Integer res1 = ignite.compute().execute(taskCls1, null);
- Integer res2 = ignite.compute().execute(taskCls2, null);
+ IgniteInternalFuture f1 = runAsyncByClass(ignite, client, taskCls1, 1);
- assert res1 != null;
- assert res2 != null;
+ IgniteInternalFuture f2 = runAsyncByClass(ignite, client, taskCls2, 2);
- assert res1 == 1 : "Invalid res1: " + res1;
- assert res2 == 2 : "Invalid res2: " + res2;
+ f1.get(); f2.get();
}
if (byTask) {
- Integer res1 = ignite.compute().execute(taskCls1.newInstance(), null);
- Integer res2 = ignite.compute().execute(taskCls2.newInstance(), null);
+ final ComputeTask<String, Integer> tc1 = taskCls1.newInstance();
+ final ComputeTask<String, Integer> tc2 = taskCls2.newInstance();
- assert res1 != null;
- assert res2 != null;
+ IgniteInternalFuture f1 = runAsyncByInstance(ignite, client, tc1, 1);
- assert res1 == 1 : "Invalid res1: " + res1;
- assert res2 == 2 : "Invalid res2: " + res2;
+ IgniteInternalFuture f2 = runAsyncByInstance(ignite, client, tc2, 2);
+
+ f1.get(); f2.get();
}
if (byName) {
ignite.compute().localDeployTask(taskCls1, ldr1);
- Integer res1 = (Integer) ignite.compute().execute(taskCls1.getName(), null);
+ Integer res1 = ignite.compute().execute(taskCls1.getName(), null);
+
+ assert res1 != null;
+
+ assert res1 == 1 : "Invalid res1: " + res1;
ignite.compute().localDeployTask(taskCls2, ldr2);
- Integer res2 = (Integer) ignite.compute().execute(taskCls2.getName(), null);
+ Integer res2 = ignite.compute().execute(taskCls2.getName(), null);
- assert res1 != null;
assert res2 != null;
- assert res1 == 1 : "Invalid res1: " + res1;
assert res2 == 2 : "Invalid res2: " + res2;
}
}
finally {
- stopGrid(ignite);
+ stopAllGrids();
}
}
@@ -267,12 +308,8 @@ public class IgniteExplicitImplicitDeploymentSelfTest extends GridCommonAbstract
* @throws Exception If test failed.
*/
private void execExplicitDeployP2P(boolean byCls, boolean byTask, boolean byName) throws Exception {
- Ignite ignite1 = null;
- Ignite ignite2 = null;
-
try {
- ignite1 = startGrid(1);
- ignite2 = startGrid(2);
+ IgniteEx ignite = startGrids(2);
ClassLoader ldr1 = new GridTestClassLoader(
Collections.singletonMap("testResource", "1"),
@@ -292,41 +329,40 @@ public class IgniteExplicitImplicitDeploymentSelfTest extends GridCommonAbstract
ldr2.loadClass(GridDeploymentResourceTestTask.class.getName());
if (byCls) {
- ignite1.compute().localDeployTask(taskCls, ldr1);
+ ignite.compute().localDeployTask(taskCls, ldr1);
// Even though the task is deployed with resource class loader,
// when we execute it, it will be redeployed with task class-loader.
- Integer res = ignite1.compute().execute(taskCls, null);
+ Integer res = ignite.compute().execute(taskCls, null);
assert res != null;
assert res == 2 : "Invalid response: " + res;
}
if (byTask) {
- ignite1.compute().localDeployTask(taskCls, ldr1);
+ ignite.compute().localDeployTask(taskCls, ldr1);
// Even though the task is deployed with resource class loader,
// when we execute it, it will be redeployed with task class-loader.
- Integer res = ignite1.compute().execute(taskCls.newInstance(), null);
+ Integer res = ignite.compute().execute(taskCls.newInstance(), null);
assert res != null;
assert res == 2 : "Invalid response: " + res;
}
if (byName) {
- ignite1.compute().localDeployTask(taskCls, ldr1);
+ ignite.compute().localDeployTask(taskCls, ldr1);
// Even though the task is deployed with resource class loader,
// when we execute it, it will be redeployed with task class-loader.
- Integer res = (Integer) ignite1.compute().execute(taskCls.getName(), null);
+ Integer res = ignite.compute().execute(taskCls.getName(), null);
assert res != null;
assert res == 1 : "Invalid response: " + res;
}
}
finally {
- stopGrid(ignite2);
- stopGrid(ignite1);
+ stopAllGrids();
}
}
@@ -337,12 +373,10 @@ public class IgniteExplicitImplicitDeploymentSelfTest extends GridCommonAbstract
* @throws Exception If test failed.
*/
private void execImplicitDeployP2P(boolean byCls, boolean byTask, boolean byName) throws Exception {
- Ignite ignite1 = null;
- Ignite ignite2 = null;
-
try {
- ignite1 = startGrid(1);
- ignite2 = startGrid(2);
+ IgniteEx ignite = startGrids(1);
+
+ final IgniteEx client = startClientGrid(1);
ClassLoader ldr1 = new GridTestClassLoader(
Collections.singletonMap("testResource", "1"),
@@ -365,46 +399,40 @@ public class IgniteExplicitImplicitDeploymentSelfTest extends GridCommonAbstract
ldr2.loadClass(GridDeploymentResourceTestTask.class.getName());
if (byCls) {
- Integer res1 = ignite1.compute().execute(taskCls1, null);
- Integer res2 = ignite1.compute().execute(taskCls2, null);
+ IgniteInternalFuture f1 = runAsyncByClass(ignite, client, taskCls1, 1);
- assert res1 != null;
- assert res2 != null;
+ IgniteInternalFuture f2 = runAsyncByClass(ignite, client, taskCls2, 2);
- assert res1 == 1 : "Invalid res1: " + res1;
- assert res2 == 2 : "Invalid res2: " + res2;
+ f1.get(); f2.get();
}
if (byTask) {
- Integer res1 = ignite1.compute().execute(taskCls1.newInstance(), null);
- Integer res2 = ignite1.compute().execute(taskCls2.newInstance(), null);
+ final ComputeTask<String, Integer> tc1 = taskCls1.newInstance();
+ final ComputeTask<String, Integer> tc2 = taskCls2.newInstance();
- assert res1 != null;
- assert res2 != null;
+ IgniteInternalFuture f1 = runAsyncByInstance(ignite, client, tc1, 1);
- assert res1 == 1 : "Invalid res1: " + res1;
- assert res2 == 2 : "Invalid res2: " + res2;
+ IgniteInternalFuture f2 = runAsyncByInstance(ignite, client, tc2, 2);
+
+ f1.get(); f2.get();
}
if (byName) {
- ignite1.compute().localDeployTask(taskCls1, ldr1);
-
- Integer res1 = (Integer) ignite1.compute().execute(taskCls1.getName(), null);
+ ignite.compute().localDeployTask(taskCls1, ldr1);
+ Integer res1 = ignite.compute().execute(taskCls1.getName(), null);
- ignite1.compute().localDeployTask(taskCls2, ldr2);
+ assert res1 != null;
+ assertEquals("Invalid res1: ", 1, (int)res1);
- Integer res2 = (Integer) ignite1.compute().execute(taskCls2.getName(), null);
+ ignite.compute().localDeployTask(taskCls2, ldr2);
+ Integer res2 = ignite.compute().execute(taskCls2.getName(), null);
- assert res1 != null;
assert res2 != null;
-
- assert res1 == 1 : "Invalid res1: " + res1;
- assert res2 == 2 : "Invalid res2: " + res2;
+ assertEquals("Invalid res2: ", 2, (int)res2);
}
}
finally {
- stopGrid(ignite1);
- stopGrid(ignite2);
+ stopAllGrids();
}
}
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/RaceOnDeployClassesWithSameAliases.java b/modules/core/src/test/java/org/apache/ignite/internal/RaceOnDeployClassesWithSameAliases.java
deleted file mode 100644
index 3f9b923..0000000
--- a/modules/core/src/test/java/org/apache/ignite/internal/RaceOnDeployClassesWithSameAliases.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * 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;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicBoolean;
-import javax.cache.processor.EntryProcessorException;
-import javax.cache.processor.MutableEntry;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.cache.CacheEntryProcessor;
-import org.apache.ignite.cluster.ClusterNode;
-import org.apache.ignite.compute.ComputeJob;
-import org.apache.ignite.compute.ComputeJobResult;
-import org.apache.ignite.compute.ComputeTaskAdapter;
-import org.apache.ignite.compute.ComputeTaskName;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.failure.StopNodeFailureHandler;
-import org.apache.ignite.testframework.ListeningTestLogger;
-import org.apache.ignite.testframework.LogListener;
-import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.apache.ignite.testframework.junits.common.GridCommonTest;
-import org.junit.Test;
-
-/**
- * Tets reproduces issue which can happens deploing classes to local store from difference class loaders.
- */
-@GridCommonTest(group = "P2P")
-public class RaceOnDeployClassesWithSameAliases extends GridCommonAbstractTest {
- /** Listening logger. */
- private final ListeningTestLogger listeningLog = new ListeningTestLogger(true, log);
-
- /** {@inheritDoc} */
- @Override protected void afterTest() throws Exception {
- super.afterTest();
-
- listeningLog.clearListeners();
-
- stopAllGrids();
- }
-
- /** {@inheritDoc} */
- @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
- return super.getConfiguration(igniteInstanceName)
- .setGridLogger(listeningLog)
- .setPeerClassLoadingEnabled(true)
- .setFailureHandler(new StopNodeFailureHandler())
- .setCacheConfiguration(new CacheConfiguration<>(DEFAULT_CACHE_NAME));
- }
-
- /**
- * Test loads class with same alias in time another class deploying.
- *
- * @throws Exception If failed.
- */
- @Test
- public void test() throws Exception {
- setRootLoggerDebugLevel();
-
- IgniteEx crd = startGrids(1);
-
- Ignite client = startClientGrid("client");
-
- awaitPartitionMapExchange();
-
- AtomicBoolean deployed = new AtomicBoolean();
-
- LogListener logLsnr = LogListener.matches(logStr -> {
- if (logStr.startsWith("Retrieved auto-loaded resource from spi:") &&
- logStr.contains(TestCacheEntryProcessor.class.getSimpleName())) {
-
- if (deployed.compareAndSet(false, true)) {
- System.out.println("dirty getting a breakdown location " + logStr);
-
- crd.compute().localDeployTask(TestTask.class, new TestClassLoader());
- }
- return true;
- }
-
- return false;
- }).build();
-
- listeningLog.registerListener(logLsnr);
-
- client.cache(DEFAULT_CACHE_NAME).invoke(1, new TestCacheEntryProcessor());
-
- assertTrue(logLsnr.check());
- }
-
- /**
- * Test entry processor.
- */
- private static class TestCacheEntryProcessor implements CacheEntryProcessor<Object, Object, Object> {
- /** {@inheritDoc} */
- @Override public Object process(
- MutableEntry<Object, Object> entry,
- Object... objects
- ) throws EntryProcessorException {
- return 2;
- }
- }
-
- /**
- * That is a compute task with same aliase as entry processor {@link TestCacheEntryProcessor}.
- */
- @ComputeTaskName("org.apache.ignite.internal.RaceOnDeployClassesWithSameAliases$TestCacheEntryProcessor")
- private static class TestTask extends ComputeTaskAdapter<Object, Object> {
- /** {@inheritDoc} */
- @Override public Map<? extends ComputeJob, ClusterNode> map(List<ClusterNode> subgrid, Object arg) {
- assert false;
-
- return Collections.emptyMap();
- }
-
- /** {@inheritDoc} */
- @Override public Object reduce(List<ComputeJobResult> results) {
- return new Object();
- }
- }
-
- /**
- * Test {@link ClassLoader}.
- */
- private static class TestClassLoader extends ClassLoader {
- /** {@inheritDoc} */
- @Override protected Class<?> findClass(String name) throws ClassNotFoundException {
- return Thread.currentThread().getContextClassLoader().loadClass(name);
- }
- }
-}
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/managers/deployment/GridDeploymentManagerStopSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/managers/deployment/GridDeploymentManagerStopSelfTest.java
index 29ce8ad..73bb3e7 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/managers/deployment/GridDeploymentManagerStopSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/managers/deployment/GridDeploymentManagerStopSelfTest.java
@@ -94,7 +94,9 @@ public class GridDeploymentManagerStopSelfTest extends GridCommonAbstractTest {
@Override public String getName() { return getClass().getSimpleName(); }
/** {@inheritDoc} */
- @Override public DeploymentResource findResource(String rsrcName) { return null; }
+ @Override public DeploymentResource findResource(String rsrcName) {
+ return null;
+ }
/** {@inheritDoc} */
@Override public boolean register(ClassLoader ldr, Class<?> rsrc) throws IgniteSpiException { return false; }
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/managers/deployment/GridDifferentLocalDeploymentSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/managers/deployment/GridDifferentLocalDeploymentSelfTest.java
new file mode 100644
index 0000000..bc02380
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/managers/deployment/GridDifferentLocalDeploymentSelfTest.java
@@ -0,0 +1,162 @@
+/*
+ * 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.deployment;
+
+import java.util.Deque;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentMap;
+import org.apache.ignite.compute.ComputeTask;
+import org.apache.ignite.configuration.DeploymentMode;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.junit.Test;
+
+/** Multiple local deployments. */
+public class GridDifferentLocalDeploymentSelfTest extends GridCommonAbstractTest {
+ /** Task name. */
+ private static final String TASK_NAME1 = "org.apache.ignite.tests.p2p.P2PTestTaskExternalPath1";
+
+ /** Task name. */
+ private static final String TASK_NAME2 = "org.apache.ignite.tests.p2p.P2PTestTaskExternalPath2";
+
+ /** */
+ private DeploymentMode depMode = DeploymentMode.PRIVATE;
+
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+ IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+ cfg.setDeploymentMode(depMode);
+
+ return cfg;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTest() throws Exception {
+ stopAllGrids();
+
+ super.afterTest();
+ }
+
+ /**
+ * Test GridDeploymentMode.SHARED mode.
+ *
+ * @throws Exception if error occur.
+ */
+ @Test
+ public void testCheckTaskClassloaderCacheSharedMode() throws Exception {
+ testCheckTaskClassloaderCache(DeploymentMode.SHARED);
+ }
+
+ /**
+ * Test GridDeploymentMode.PRIVATE mode.
+ *
+ * @throws Exception if error occur.
+ */
+ @Test
+ public void testCheckTaskClassloaderCachePrivateMode() throws Exception {
+ testCheckTaskClassloaderCache(DeploymentMode.PRIVATE);
+ }
+
+ /**
+ * Test GridDeploymentMode.ISOLATED mode.
+ *
+ * @throws Exception if error occur.
+ */
+ @Test
+ public void testCheckTaskClassloaderCacheIsolatedMode() throws Exception {
+ testCheckTaskClassloaderCache(DeploymentMode.ISOLATED);
+ }
+
+ /**
+ * Test GridDeploymentMode.CONTINUOUS mode.
+ *
+ * @throws Exception if error occur.
+ */
+ @Test
+ public void testCheckTaskClassloaderCacheContinuousMode() throws Exception {
+ testCheckTaskClassloaderCache(DeploymentMode.CONTINUOUS);
+ }
+
+ /** */
+ public void testCheckTaskClassloaderCache(DeploymentMode depMode) throws Exception {
+ this.depMode = depMode;
+
+ IgniteEx server = startGrid(0);
+
+ IgniteEx client = startClientGrid(1);
+
+ ClassLoader clsLdr1 = getExternalClassLoader();
+
+ ClassLoader clsLdr2 = getExternalClassLoader();
+
+ Class<ComputeTask> taskCls11 = (Class<ComputeTask>) clsLdr1.loadClass(TASK_NAME1);
+ Class<ComputeTask> taskCls12 = (Class<ComputeTask>) clsLdr2.loadClass(TASK_NAME1);
+ Class<ComputeTask> taskCls21 = (Class<ComputeTask>) clsLdr2.loadClass(TASK_NAME2);
+
+ IgniteInternalFuture f1 = GridTestUtils.runAsync(() -> {
+ for (int i = 0; i < 10; ++i) {
+ try {
+ client.compute().execute(taskCls11.newInstance(), server.localNode().id());
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ });
+
+ IgniteInternalFuture f2 = GridTestUtils.runAsync(() -> {
+ for (int i = 0; i < 10; ++i) {
+ try {
+ client.compute().execute(taskCls12.newInstance(), server.localNode().id());
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ });
+
+ f1.get(); f2.get();
+
+ client.compute().execute(taskCls21.newInstance(), server.localNode().id());
+
+ GridDeploymentManager deploymentMgr = client.context().deploy();
+
+ GridDeploymentStore store = GridTestUtils.getFieldValue(deploymentMgr, "locStore");
+
+ ConcurrentMap<String, Deque<GridDeployment>> cache = GridTestUtils.getFieldValue(store, "cache");
+
+ assertEquals(2, cache.get(TASK_NAME1).size());
+
+ deploymentMgr = server.context().deploy();
+
+ GridDeploymentStore verStore = GridTestUtils.getFieldValue(deploymentMgr, "verStore");
+
+ // deployments per userVer map.
+ Map<String, List<Object>> varCache = GridTestUtils.getFieldValue(verStore, "cache");
+
+ if (depMode == DeploymentMode.CONTINUOUS || depMode == DeploymentMode.SHARED) {
+ for (List<Object> deps : varCache.values())
+ assertEquals(2, deps.size());
+ }
+ }
+}
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheSizeFailoverTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheSizeFailoverTest.java
index 99c2b7d..c8c17e5 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheSizeFailoverTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheSizeFailoverTest.java
@@ -75,7 +75,7 @@ public class IgniteCacheSizeFailoverTest extends GridCommonAbstractTest {
final AtomicInteger cntr = new AtomicInteger();
IgniteInternalFuture<?> fut = GridTestUtils.runMultiThreadedAsync(new Callable<Object>() {
- @Override public Object call() throws Exception {
+ @Override public Object call() {
int idx = cntr.getAndIncrement() % 2;
IgniteCache<Object, Object> cache = ignite(idx).cache(DEFAULT_CACHE_NAME);
diff --git a/modules/core/src/test/java/org/apache/ignite/p2p/GridP2PUndeploySelfTest.java b/modules/core/src/test/java/org/apache/ignite/p2p/GridP2PUndeploySelfTest.java
index 17ed730..7c8c490 100644
--- a/modules/core/src/test/java/org/apache/ignite/p2p/GridP2PUndeploySelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/p2p/GridP2PUndeploySelfTest.java
@@ -21,16 +21,19 @@ import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.ConcurrentMap;
import org.apache.ignite.Ignite;
import org.apache.ignite.compute.ComputeTask;
import org.apache.ignite.configuration.DeploymentMode;
import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.spi.deployment.local.LocalDeploymentSpi;
import org.apache.ignite.testframework.GridTestClassLoader;
import org.apache.ignite.testframework.config.GridTestProperties;
import org.apache.ignite.testframework.junits.IgniteTestResources;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.apache.ignite.testframework.junits.common.GridCommonTest;
+import org.jsr166.ConcurrentLinkedHashMap;
import org.junit.Test;
/**
@@ -95,6 +98,9 @@ public class GridP2PUndeploySelfTest extends GridCommonAbstractTest {
assert spi1.findResource(task1.getName()) != null;
assert spi2.findResource(task1.getName()) != null;
+ checkResourceRegisteredInSpi(tstClsLdr, task1, spi1, true);
+ checkResourceRegisteredInSpi(tstClsLdr, task1, spi2, true);
+
assert ignite1.compute().localTasks().containsKey(task1.getName());
assert ignite2.compute().localTasks().containsKey(task1.getName());
@@ -106,6 +112,9 @@ public class GridP2PUndeploySelfTest extends GridCommonAbstractTest {
assert spi1.findResource(task1.getName()) == null;
assert spi2.findResource(task1.getName()) == null;
+ checkResourceRegisteredInSpi(tstClsLdr, task1, spi1, false);
+ checkResourceRegisteredInSpi(tstClsLdr, task1, spi2, false);
+
assert !ignite1.compute().localTasks().containsKey(task1.getName());
assert !ignite2.compute().localTasks().containsKey(task1.getName());
}
@@ -116,6 +125,30 @@ public class GridP2PUndeploySelfTest extends GridCommonAbstractTest {
}
/**
+ * Checks the resource is registered in SPI.
+ *
+ * @param tstClsLdr Class loader.
+ * @param task Task resource.
+ * @param spi Deployment SPI.
+ * @param registered True id the resource registered, false otherwise.
+ */
+ private void checkResourceRegisteredInSpi(ClassLoader tstClsLdr, Class<? extends ComputeTask<?, ?>> task,
+ LocalDeploymentSpi spi, boolean registered) {
+ ConcurrentLinkedHashMap<ClassLoader, ConcurrentMap<String, String>> ldrRsrcs = U.field(spi, "ldrRsrcs");
+
+ ConcurrentMap<String, String> rcsAliasMap = ldrRsrcs.get(tstClsLdr);
+
+ if (registered) {
+ assertNotNull(rcsAliasMap.get(U.getResourceName(task)));
+ assertNotNull(rcsAliasMap.get(task.getName()));
+ }
+ else {
+ assertTrue(rcsAliasMap == null || rcsAliasMap.get(U.getResourceName(task)) == null);
+ assertTrue(rcsAliasMap == null || rcsAliasMap.get(task.getName()) == null);
+ }
+ }
+
+ /**
* @param depMode deployment mode.
* @throws Exception If failed.
*/
@@ -139,20 +172,20 @@ public class GridP2PUndeploySelfTest extends GridCommonAbstractTest {
LocalDeploymentSpi spi1 = spis.get(ignite1.name());
LocalDeploymentSpi spi2 = spis.get(ignite2.name());
- assert spi1.findResource(task1.getName()) != null;
+ checkResourceRegisteredInSpi(ldr, task1, spi1, true);
assert ignite1.compute().localTasks().containsKey(task1.getName());
// P2P deployment will not deploy task into the SPI.
- assert spi2.findResource(task1.getName()) == null;
+ checkResourceRegisteredInSpi(ldr, task1, spi2, false);
ignite1.compute().undeployTask(task1.getName());
// Wait for undeploy.
Thread.sleep(1000);
- assert spi1.findResource(task1.getName()) == null;
- assert spi2.findResource(task1.getName()) == null;
+ checkResourceRegisteredInSpi(ldr, task1, spi1, false);
+ checkResourceRegisteredInSpi(ldr, task1, spi2, false);
assert !ignite1.compute().localTasks().containsKey(task1.getName());
assert !ignite2.compute().localTasks().containsKey(task1.getName());
diff --git a/modules/core/src/test/java/org/apache/ignite/spi/deployment/local/GridLocalDeploymentSpiSelfTest.java b/modules/core/src/test/java/org/apache/ignite/spi/deployment/local/GridLocalDeploymentSpiSelfTest.java
index 0972898..e0fede4 100644
--- a/modules/core/src/test/java/org/apache/ignite/spi/deployment/local/GridLocalDeploymentSpiSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/spi/deployment/local/GridLocalDeploymentSpiSelfTest.java
@@ -25,16 +25,19 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
import org.apache.ignite.compute.ComputeJob;
import org.apache.ignite.compute.ComputeJobResult;
import org.apache.ignite.compute.ComputeTask;
import org.apache.ignite.compute.ComputeTaskName;
import org.apache.ignite.compute.ComputeTaskSplitAdapter;
+import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.spi.IgniteSpiException;
import org.apache.ignite.spi.deployment.DeploymentListener;
import org.apache.ignite.spi.deployment.DeploymentResource;
import org.apache.ignite.testframework.junits.spi.GridSpiAbstractTest;
import org.apache.ignite.testframework.junits.spi.GridSpiTest;
+import org.jsr166.ConcurrentLinkedHashMap;
import org.junit.Test;
/**
@@ -96,20 +99,34 @@ public class GridLocalDeploymentSpiSelfTest extends GridSpiAbstractTest<LocalDep
deploy(task);
+ checkResourceRegisteredInSpi(task.getClassLoader(), taskName, getSpi(), true);
+
+ Map<String, String> rcsMap = new HashMap<>(2);
+ rcsMap.put(taskName, task.getName());
+ rcsMap.put(task.getName(), task.getName());
+
// Note we use task name instead of class name.
- DeploymentResource t1 = getSpi().findResource(taskName);
+ DeploymentResource t1 = U.invoke(
+ getSpi().getClass(),
+ getSpi(),
+ "findResource0",
+ rcsMap,
+ taskName,
+ task.getClassLoader()
+ );
+
+ assertNotNull(t1);
- assert t1 != null;
+ assertSame(t1.getResourceClass(), task);
- assert t1.getResourceClass().equals(task);
- assert t1.getName().equals(taskName);
+ assertEquals(t1.getName(), taskName);
getSpi().unregister(taskName);
checkUndeployed(task);
- assert getSpi().findResource(taskName) == null;
- assert getSpi().findResource(task.getName()) == null;
+ checkResourceRegisteredInSpi(task.getClassLoader(), taskName, getSpi(), false);
+ checkResourceRegisteredInSpi(task.getClassLoader(), task.getName(), getSpi(), false);
}
/**
@@ -139,7 +156,7 @@ public class GridLocalDeploymentSpiSelfTest extends GridSpiAbstractTest<LocalDep
checkUndeployed(t1);
- assert getSpi().findResource("GridDeploymentTestTask") == null;
+ checkResourceRegisteredInSpi(t1.getClassLoader(), "GridDeploymentTestTask", getSpi(), false);
tasks.clear();
@@ -158,8 +175,27 @@ public class GridLocalDeploymentSpiSelfTest extends GridSpiAbstractTest<LocalDep
checkUndeployed(t1);
- assert getSpi().findResource(taskName) == null;
- assert getSpi().findResource(t1.getName()) == null;
+ checkResourceRegisteredInSpi(t1.getClassLoader(), taskName, getSpi(), false);
+ checkResourceRegisteredInSpi(t1.getClassLoader(), t1.getName(), getSpi(), false);
+ }
+
+ /**
+ * Checks the resource is registered in SPI.
+ *
+ * @param tstClsLdr Class loader.
+ * @param taskName Name of resource.
+ * @param spi Deployment SPI.
+ * @param registered True id the resource registered, false otherwise.
+ */
+ private void checkResourceRegisteredInSpi(ClassLoader tstClsLdr, String taskName, LocalDeploymentSpi spi, boolean registered) {
+ ConcurrentLinkedHashMap<ClassLoader, ConcurrentMap<String, String>> ldrRsrcs = U.field(spi, "ldrRsrcs");
+
+ ConcurrentMap<String, String> rcsAliasMap = ldrRsrcs.get(tstClsLdr);
+
+ if (registered)
+ assertNotNull(rcsAliasMap.get(taskName));
+ else
+ assertTrue(rcsAliasMap == null || rcsAliasMap.get(taskName) == null);
}
/**
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteP2PSelfTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteP2PSelfTestSuite.java
index abee2b2..e788aea 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteP2PSelfTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteP2PSelfTestSuite.java
@@ -18,8 +18,8 @@
package org.apache.ignite.testsuites;
import org.apache.ignite.internal.GridP2PAffinitySelfTest;
-import org.apache.ignite.internal.RaceOnDeployClassesWithSameAliases;
import org.apache.ignite.internal.managers.deployment.GridDeploymentMessageCountSelfTest;
+import org.apache.ignite.internal.managers.deployment.GridDifferentLocalDeploymentSelfTest;
import org.apache.ignite.internal.managers.deployment.P2PCacheOperationIntoComputeTest;
import org.apache.ignite.p2p.DeploymentClassLoaderCallableTest;
import org.apache.ignite.p2p.GridP2PClassLoadingSelfTest;
@@ -73,10 +73,10 @@ import org.junit.runners.Suite;
GridDeploymentMessageCountSelfTest.class,
GridP2PComputeWithNestedEntryProcessorTest.class,
GridP2PCountTiesLoadClassDirectlyFromClassLoaderTest.class,
- RaceOnDeployClassesWithSameAliases.class,
GridP2PScanQueryWithTransformerTest.class,
P2PCacheOperationIntoComputeTest.class,
- GridP2PContinuousDeploymentClientDisconnectTest.class
+ GridP2PContinuousDeploymentClientDisconnectTest.class,
+ GridDifferentLocalDeploymentSelfTest.class,
})
public class IgniteP2PSelfTestSuite {
}