enumMap) throws BinaryObjectException {
assert mapper != null;
- Class> cls = null;
-
- try {
- cls = CommonUtils.resolveClassLoader(null, classLoader()).loadClass(clsName);
- }
- catch (ClassNotFoundException | NoClassDefFoundError ignored) {
- // No-op.
- }
+ Class> cls = loadClassOrNull(clsName);
String typeName = mapper.typeName(clsName);
diff --git a/modules/binary/api/src/main/java/org/apache/ignite/internal/marshaller/ClassLoaderUtils.java b/modules/binary/api/src/main/java/org/apache/ignite/internal/marshaller/ClassLoaderUtils.java
index 10c8f697e2862..00ccbf9e5d6f5 100644
--- a/modules/binary/api/src/main/java/org/apache/ignite/internal/marshaller/ClassLoaderUtils.java
+++ b/modules/binary/api/src/main/java/org/apache/ignite/internal/marshaller/ClassLoaderUtils.java
@@ -29,6 +29,12 @@
/**
* Utility class to deal with class loading.
* Contains internal class cache.
+ *
+ * A {@code null} class loader passed to any method of this class means the loader Ignite itself was loaded by,
+ * {@link CommonUtils#gridClassLoader()}. This fallback serves {@link org.apache.ignite.marshaller.Marshaller} API
+ * callers and deployment code.
+ * Binary code resolves loaders through {@code BinaryContext#resolveClassLoader(ClassLoader)} and never passes
+ * {@code null} here.
*/
public class ClassLoaderUtils {
/** Primitive class map. */
diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryArray.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryArray.java
index 6fd7ef9bff346..62b8de21afc72 100644
--- a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryArray.java
+++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryArray.java
@@ -104,7 +104,7 @@ public BinaryArray(BinaryContext ctx, int compTypeId, @Nullable String compClsNa
/** {@inheritDoc} */
@Override public T deserialize(ClassLoader ldr) throws BinaryObjectException {
- if (ldr != null)
+ if (ctx.isCustomLoader(ldr))
Marshallers.USE_CACHE.set(Boolean.FALSE);
try {
diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java
index 4242ac535fe61..2f3ea279920b9 100644
--- a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java
+++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java
@@ -169,13 +169,15 @@ public BinaryEnumObjectImpl(BinaryContext ctx, byte[] arr) {
/** {@inheritDoc} */
@Override public T deserialize(@Nullable ClassLoader ldr) throws BinaryObjectException {
- if (ldr != null)
+ boolean customLdr = ctx.isCustomLoader(ldr);
+
+ if (customLdr)
Marshallers.USE_CACHE.set(Boolean.FALSE);
try {
Class cls = BinaryImplUtils.resolveClass(ctx, typeId, clsName, ldr, false);
- return (T)(ldr == null ? BinaryEnumCache.get(cls, ord) : uncachedValue(cls));
+ return (T)(customLdr ? uncachedValue(cls) : BinaryEnumCache.get(cls, ord));
}
finally {
Marshallers.USE_CACHE.set(Boolean.TRUE);
diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryImplUtils.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryImplUtils.java
index 0ca035ef9b78e..f9a3a4509e141 100644
--- a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryImplUtils.java
+++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryImplUtils.java
@@ -17,13 +17,11 @@
package org.apache.ignite.internal.binary;
import java.io.ByteArrayInputStream;
-
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.binary.BinaryInvalidTypeException;
import org.apache.ignite.binary.BinaryObjectException;
import org.apache.ignite.internal.binary.streams.BinaryInputStream;
import org.apache.ignite.internal.marshaller.ClassLoaderUtils;
-import org.apache.ignite.internal.util.CommonUtils;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.lang.IgniteBiTuple;
import org.jetbrains.annotations.Nullable;
@@ -370,7 +368,7 @@ public static Object doReadOptimized(BinaryInputStream in, BinaryContext ctx, @N
ByteArrayInputStream input = new ByteArrayInputStream(in.array(), in.position(), len);
try {
- return ctx.optimizedMarsh().unmarshal(input, CommonUtils.resolveClassLoader(clsLdr, ctx.classLoader()));
+ return ctx.optimizedMarsh().unmarshal(input, ctx.resolveClassLoader(clsLdr));
}
catch (IgniteCheckedException e) {
throw new BinaryObjectException("Failed to unmarshal object with optimized marshaller", e);
@@ -394,8 +392,7 @@ static Class resolveClass(BinaryContext ctx, int typeId, @Nullable String clsNam
@Nullable ClassLoader ldr, boolean registerMeta) {
Class cls;
- if (ldr == null)
- ldr = ctx.classLoader();
+ ldr = ctx.resolveClassLoader(ldr);
if (typeId != GridBinaryMarshaller.UNREGISTERED_TYPE_ID)
cls = ctx.descriptorForTypeId(true, typeId, ldr, registerMeta).describedClass();
diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java
index a0bac1118da80..65bf49609c9f6 100644
--- a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java
+++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryObjectImpl.java
@@ -701,7 +701,7 @@ else if (fieldOffsetLen == BinaryImplUtils.OFFSET_2)
/** {@inheritDoc} */
@Nullable @Override public T deserialize(@Nullable ClassLoader ldr) throws BinaryObjectException {
- if (ldr == null)
+ if (!ctx.isCustomLoader(ldr))
return deserialize();
Marshallers.USE_CACHE.set(Boolean.FALSE);
diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryObjectOffheapImpl.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryObjectOffheapImpl.java
index 3f21909780a31..320124813f812 100644
--- a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryObjectOffheapImpl.java
+++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryObjectOffheapImpl.java
@@ -400,7 +400,7 @@ else if (fieldOffLen == BinaryImplUtils.OFFSET_2)
/** {@inheritDoc} */
@Nullable @Override public T deserialize(@Nullable ClassLoader ldr) throws BinaryObjectException {
- if (ldr == null)
+ if (!ctx.isCustomLoader(ldr))
return deserialize();
Marshallers.USE_CACHE.set(Boolean.FALSE);
diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java
index 8e4c96ee78b83..c0b26c046f2c1 100644
--- a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java
+++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java
@@ -110,7 +110,10 @@ public final class BinaryReaderExImpl extends BinaryReaderHandlesHolder implemen
/** Input stream. */
private final BinaryInputStream in;
- /** Class loader. */
+ /**
+ * Class loader to resolve classes with: custom loader or {@link BinaryContext#classLoader()}, resolved once here.
+ * {@code null} only when {@link #ctx} is {@code null}; such readers can read primitives only.
+ */
private final ClassLoader ldr;
/** */
@@ -204,14 +207,14 @@ public BinaryReaderExImpl(BinaryContext ctx,
*
* @param ctx Context.
* @param in Input stream.
- * @param ldr Class loader.
+ * @param ldr Custom class loader or {@code null} to use {@link BinaryContext#classLoader()}.
* @param hnds Reader handles or {@code null} to start a new handles context.
* @param skipHdrCheck Whether to skip header check.
* @param forUnmarshal {@code True} if reader is need to unmarshal object.
*/
public BinaryReaderExImpl(BinaryContext ctx,
BinaryInputStream in,
- ClassLoader ldr,
+ @Nullable ClassLoader ldr,
@Nullable BinaryReaderHandles hnds,
boolean skipHdrCheck,
boolean forUnmarshal) {
@@ -220,7 +223,7 @@ public BinaryReaderExImpl(BinaryContext ctx,
this.ctx = ctx;
this.in = in;
- this.ldr = ldr;
+ this.ldr = ctx == null ? ldr : ctx.resolveClassLoader(ldr);
start = in.position();
@@ -3278,7 +3281,7 @@ private static Object doReadProxy(BinaryInputStream in, BinaryContext ctx, Class
InvocationHandler ih = (InvocationHandler)doReadObject(in, ctx, ldr, handles);
- return Proxy.newProxyInstance(ldr != null ? ldr : CommonUtils.gridClassLoader(), intfs, ih);
+ return Proxy.newProxyInstance(ldr, intfs, ih);
}
/**
@@ -3381,9 +3384,9 @@ private static Object[] doReadBinaryEnumArray(BinaryInputStream in, BinaryContex
* @return Unmarshalled value.
* @throws BinaryObjectException In case of error.
*/
- @Nullable static Object unmarshal(BinaryInputStream in, BinaryContext ctx, ClassLoader ldr)
+ @Nullable static Object unmarshal(BinaryInputStream in, BinaryContext ctx, @Nullable ClassLoader ldr)
throws BinaryObjectException {
- return unmarshal(in, ctx, ldr, new BinaryReaderHandlesHolder(null));
+ return unmarshal(in, ctx, ctx.resolveClassLoader(ldr), new BinaryReaderHandlesHolder(null), false, false);
}
/**
diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderReader.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderReader.java
index 2c650e8e75fbc..66562d280386d 100644
--- a/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderReader.java
+++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderReader.java
@@ -491,7 +491,7 @@ public Object getValueQuickly(int pos, int len) {
case GridBinaryMarshaller.OPTM_MARSH: {
final BinaryInputStream bin = BinaryStreams.inputStream(arr, pos + 1);
- final Object obj = BinaryImplUtils.doReadOptimized(bin, ctx, ctx.classLoader());
+ final Object obj = BinaryImplUtils.doReadOptimized(bin, ctx, null);
return obj;
}
@@ -843,7 +843,7 @@ else if (flag == GridBinaryMarshaller.DECIMAL) {
case GridBinaryMarshaller.OPTM_MARSH: {
final BinaryInputStream bin = BinaryStreams.inputStream(arr, pos);
- final Object obj = BinaryImplUtils.doReadOptimized(bin, ctx, ctx.classLoader());
+ final Object obj = BinaryImplUtils.doReadOptimized(bin, ctx, null);
pos = bin.position();
diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectInputStream.java b/modules/binary/impl/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectInputStream.java
index e1a41bda6ba53..6fe80a6ec938b 100644
--- a/modules/binary/impl/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectInputStream.java
+++ b/modules/binary/impl/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectInputStream.java
@@ -43,7 +43,6 @@
import java.util.concurrent.ConcurrentMap;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.marshaller.ClassLoaderUtils;
-import org.apache.ignite.internal.util.CommonUtils;
import org.apache.ignite.internal.util.GridUnsafe;
import org.apache.ignite.internal.util.io.GridDataInput;
import org.apache.ignite.internal.util.typedef.internal.SB;
@@ -330,7 +329,7 @@ private Object readObject0() throws ClassNotFoundException, IOException {
InvocationHandler ih = (InvocationHandler)readObject();
- return Proxy.newProxyInstance(clsLdr != null ? clsLdr : CommonUtils.gridClassLoader(), intfs, ih);
+ return Proxy.newProxyInstance(clsLdr, intfs, ih);
case ENUM:
case EXTERNALIZABLE:
diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerImpl.java b/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerImpl.java
index e2f6d37bb9acb..1451be43174d4 100644
--- a/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerImpl.java
+++ b/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerImpl.java
@@ -116,9 +116,6 @@ else if (!(objFilter instanceof IgniteObjectInputFilter)) {
@Override protected T unmarshal0(InputStream in, @Nullable ClassLoader clsLdr) throws IgniteCheckedException {
assert in != null;
- if (clsLdr == null)
- clsLdr = getClass().getClassLoader();
-
try (ObjectInputStream objIn = new JdkMarshallerObjectInputStream(new JdkMarshallerInputStreamWrapper(in), clsLdr)) {
return (T)objIn.readObject();
}
diff --git a/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerObjectInputStream.java b/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerObjectInputStream.java
index 6a5c5cb6fbdb4..15705c559e67a 100644
--- a/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerObjectInputStream.java
+++ b/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerObjectInputStream.java
@@ -22,13 +22,14 @@
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;
import org.apache.ignite.internal.marshaller.ClassLoaderUtils;
+import org.jetbrains.annotations.Nullable;
/**
* This class defines custom JDK object input stream.
*/
class JdkMarshallerObjectInputStream extends ObjectInputStream {
/** */
- private final ClassLoader clsLdr;
+ private final @Nullable ClassLoader clsLdr;
/**
* @param in Parent input stream.
@@ -38,8 +39,6 @@ class JdkMarshallerObjectInputStream extends ObjectInputStream {
JdkMarshallerObjectInputStream(InputStream in, ClassLoader clsLdr) throws IOException {
super(in);
- assert clsLdr != null;
-
this.clsLdr = clsLdr;
enableResolveObject(true);
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
index 38ee2eb4d9df0..3a66112f7d96a 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
@@ -414,10 +414,8 @@ private GridQueryFieldsResult executeSelectLocal(
// Convert parameters into BinaryObjects.
BinaryMarshaller m = ctx.marshaller();
byte[] paramsBytes = U.marshal(m, qryParams.arguments());
- final ClassLoader ldr = U.resolveClassLoader(ctx.config());
- Object[] params = BinaryUtils.rawArrayFromBinary(m.binaryMarshaller()
- .unmarshal(paramsBytes, ldr));
+ Object[] params = BinaryUtils.rawArrayFromBinary(m.binaryMarshaller().unmarshal(paramsBytes, null));
H2Utils.bindParameters(stmt, F.asList(params));
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2DmlRequest.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2DmlRequest.java
index 31a5de860155a..80f186fde6b64 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2DmlRequest.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2DmlRequest.java
@@ -354,10 +354,8 @@ public GridH2DmlRequest queryInitiatorId(String qryInitiatorId) {
assert paramsBytes != null;
- final ClassLoader ldr = U.resolveClassLoader(ctx.config());
-
// To avoid deserializing of enum types.
- params = BinaryUtils.rawArrayFromBinary(ctx.marshaller().binaryMarshaller().unmarshal(paramsBytes, ldr));
+ params = BinaryUtils.rawArrayFromBinary(ctx.marshaller().binaryMarshaller().unmarshal(paramsBytes, null));
}
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2DmlResponse.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2DmlResponse.java
index 834b9f3996381..edfb767a2a226 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2DmlResponse.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2DmlResponse.java
@@ -125,10 +125,8 @@ public String error() {
if (errKeys != null || errKeysBytes == null)
return;
- final ClassLoader ldr = U.resolveClassLoader(ctx.config());
-
// To avoid deserializing of enum types.
- errKeys = BinaryUtils.rawArrayFromBinary(ctx.marshaller().binaryMarshaller().unmarshal(errKeysBytes, ldr));
+ errKeys = BinaryUtils.rawArrayFromBinary(ctx.marshaller().binaryMarshaller().unmarshal(errKeysBytes, null));
}
/** {@inheritDoc} */
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2QueryRequest.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2QueryRequest.java
index 85b91e92e1139..ef7d9223ace43 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2QueryRequest.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2QueryRequest.java
@@ -543,10 +543,8 @@ public static Boolean isDataPageScanEnabled(int flags) {
@Override public void unmarshall(GridKernalContext ctx) {
assert paramsBytes != null;
- final ClassLoader ldr = U.resolveClassLoader(ctx.config());
-
// To avoid deserializing of enum types.
- params = BinaryUtils.rawArrayFromBinary(ctx.marshaller().binaryMarshaller().unmarshal(paramsBytes, ldr));
+ params = BinaryUtils.rawArrayFromBinary(ctx.marshaller().binaryMarshaller().unmarshal(paramsBytes, null));
}