diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java index 0b64d6a94b956..be1ffc3cb5707 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java @@ -1091,6 +1091,11 @@ private Object newInstance() throws BinaryObjectException { } } + /** */ + Constructor ctor() { + return ctor; + } + /** * @param cls Class. * @return Constructor. diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java index ff9407fabf879..d5b0ea2df22db 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java @@ -275,6 +275,11 @@ public BinaryContext(BinaryMetadataHandler metaHnd, IgniteConfiguration igniteCf registerPredefinedType(PlatformDotNetSessionLockResult.class, 0); // IDs range [200..1000] is used by Ignite internal APIs. + + if (U.sunReflectionFactory() == null) { + U.warn(log, "ReflectionFactory not found, deserialization of binary objects for classes without " + + "default constructor is not possible"); + } } /** @@ -1455,6 +1460,11 @@ public synchronized void removeType(int typeId) { schemas.remove(typeId); } + /** */ + Collection predefinedTypes() { + return Collections.unmodifiableCollection(predefinedTypes.values()); + } + /** * Type descriptors. */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/websession/PlatformDotNetSessionLockResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/websession/PlatformDotNetSessionLockResult.java index 5c4dfff937046..ef41644940178 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/websession/PlatformDotNetSessionLockResult.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/websession/PlatformDotNetSessionLockResult.java @@ -42,6 +42,13 @@ public class PlatformDotNetSessionLockResult implements Binarylizable { /** Lock id. */ private long lockId; + /** + * Default constructor for deserialization. + */ + public PlatformDotNetSessionLockResult() { + // No-op. + } + /** * Constructor. * diff --git a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryContextPredefinedTypesTest.java b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryContextPredefinedTypesTest.java new file mode 100644 index 0000000000000..9e0c4b63a888d --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryContextPredefinedTypesTest.java @@ -0,0 +1,46 @@ +/* + * 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.binary; + +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; +import org.junit.Test; + +/** + * + */ +public class BinaryContextPredefinedTypesTest extends GridCommonAbstractTest { + /** + * Tests that all predefined types have default constructor. + */ + @Test + public void testDefaultConstructor() { + BinaryContext binCtx = new BinaryContext(BinaryNoopMetadataHandler.instance(), new IgniteConfiguration(), log); + + for (BinaryClassDescriptor desc : binCtx.predefinedTypes()) { + if (!desc.isBinary()) + continue; + + // Check that class descriptor uses default class constructor (not generated by U.ctorFactory()). + // Ignite can't start if any predefined type misses default constructor and U.ctorFactory() is not available + // (this can happens in some environments, for example, inside application server) + assertTrue("Missing default constructor for predifined type " + desc.describedClass().getName(), + desc.describedClass() == desc.ctor().getDeclaringClass()); + } + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBinaryObjectsTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBinaryObjectsTestSuite.java index 5bb3a4a013a7f..9fb83cfc7c8d4 100644 --- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBinaryObjectsTestSuite.java +++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBinaryObjectsTestSuite.java @@ -23,6 +23,7 @@ import org.apache.ignite.internal.binary.BinaryBasicNameMapperSelfTest; import org.apache.ignite.internal.binary.BinaryConfigurationConsistencySelfTest; import org.apache.ignite.internal.binary.BinaryConfigurationCustomSerializerSelfTest; +import org.apache.ignite.internal.binary.BinaryContextPredefinedTypesTest; import org.apache.ignite.internal.binary.BinaryEnumsSelfTest; import org.apache.ignite.internal.binary.BinaryFieldExtractionSelfTest; import org.apache.ignite.internal.binary.BinaryFieldsHeapSelfTest; @@ -173,7 +174,8 @@ GridCacheBinaryObjectUserClassloaderSelfTest.class, - BinaryMetadataMoveLegacyFolderTest.class + BinaryMetadataMoveLegacyFolderTest.class, + BinaryContextPredefinedTypesTest.class, }) public class IgniteBinaryObjectsTestSuite { }