use of org.apache.ignite.internal.util.lang.GridPeerDeployAware in project ignite by apache.
the class IgniteUtils method hasCommonClassLoader.
/**
* Check if all elements from the collection could be loaded with the same classloader as the given object.
*
* @param obj base object.
* @param c collection to check elements from.
* @return {@code true} if all elements could be loaded with {@code obj}'s classloader, {@code false} otherwise
*/
private static boolean hasCommonClassLoader(Object obj, Iterable<?> c) {
assert obj != null;
assert c != null;
ClassLoader ldr = obj instanceof GridPeerDeployAware ? ((GridPeerDeployAware) obj).classLoader() : detectClassLoader(obj.getClass());
boolean found = true;
for (Object obj2 : c) {
if (obj2 == null || obj2 == obj)
continue;
// Obj2 class name.
String clsName = obj2 instanceof GridPeerDeployAware ? ((GridPeerDeployAware) obj2).deployClass().getName() : obj2.getClass().getName();
if (!isLoadableBy(clsName, ldr)) {
found = false;
break;
}
}
return found;
}
use of org.apache.ignite.internal.util.lang.GridPeerDeployAware in project ignite by apache.
the class IgniteUtils method nestedPeerDeployAware.
/**
* Gets peer deploy class if there is any {@link GridPeerDeployAware} within reach.
*
* @param obj Object to check.
* @param top Indicates whether object is top level or a nested field.
* @param processed Set of processed objects to avoid infinite recursion.
* @return Peer deploy class, or {@code null} if one could not be found.
*/
@Nullable
private static GridPeerDeployAware nestedPeerDeployAware(Object obj, boolean top, Set<Object> processed) {
// Avoid infinite recursion.
if (!processed.add(obj))
return null;
if (obj instanceof GridPeerDeployAware) {
GridPeerDeployAware p = (GridPeerDeployAware) obj;
if (!top && p.deployClass() != null)
return p;
for (Class<?> cls = obj.getClass(); !cls.equals(Object.class); cls = cls.getSuperclass()) {
// Cache by class name instead of class to avoid infinite growth of the
// caching map in case of multiple redeployment of the same class.
IgniteBiTuple<Class<?>, Collection<Field>> tup = p2pFields.get(cls.getName());
boolean cached = tup != null && tup.get1().equals(cls);
Iterable<Field> fields = cached ? tup.get2() : Arrays.asList(cls.getDeclaredFields());
if (!cached) {
tup = new IgniteBiTuple<>();
tup.set1(cls);
}
for (Field f : fields) // Special handling for anonymous classes.
if (cached || f.getName().startsWith("this$") || f.getName().startsWith("val$")) {
if (!cached) {
f.setAccessible(true);
if (tup.get2() == null)
tup.set2(new LinkedList<Field>());
tup.get2().add(f);
}
try {
Object o = f.get(obj);
if (o != null) {
// Recursion.
p = nestedPeerDeployAware(o, false, processed);
if (p != null) {
if (!cached)
// Potentially replace identical value
// stored by another thread.
p2pFields.put(cls.getName(), tup);
return p;
}
}
} catch (IllegalAccessException ignored) {
return null;
}
}
}
} else // Don't go into internal Ignite structures.
if (isIgnite(obj.getClass()))
return null;
else if (obj instanceof Iterable)
for (Object o : (Iterable<?>) obj) {
// Recursion.
GridPeerDeployAware p = nestedPeerDeployAware(o, false, processed);
if (p != null)
return p;
}
else if (obj.getClass().isArray()) {
Class<?> type = obj.getClass().getComponentType();
// We don't care about primitives or internal JDK types.
if (!type.isPrimitive() && !isJdk(type)) {
Object[] arr = (Object[]) obj;
for (Object o : arr) {
// Recursion.
GridPeerDeployAware p = nestedPeerDeployAware(o, false, processed);
if (p != null)
return p;
}
}
}
return null;
}
use of org.apache.ignite.internal.util.lang.GridPeerDeployAware in project ignite by apache.
the class IgniteUtilsSelfTest method testDetectPeerDeployAwareInfiniteRecursion.
/**
* @throws Exception If test fails.
*/
@Test
public void testDetectPeerDeployAwareInfiniteRecursion() throws Exception {
Ignite g = startGrid(1);
try {
final SelfReferencedJob job = new SelfReferencedJob(g);
GridPeerDeployAware d = U.detectPeerDeployAware(U.peerDeployAware(job));
assert d != null;
assert SelfReferencedJob.class == d.deployClass();
assert d.classLoader() == SelfReferencedJob.class.getClassLoader();
} finally {
stopGrid(1);
}
}
Aggregations