This is an automated email from the ASF dual-hosted git repository.

nizhikov 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 d7fe6cbf9b8 [MINOR] Compile time check for Message default constructor 
added (#13220)
d7fe6cbf9b8 is described below

commit d7fe6cbf9b8b07b6516d5f15f6c692335c4ff94d
Author: Nikolay <[email protected]>
AuthorDate: Mon Jun 22 13:00:41 2026 +0300

    [MINOR] Compile time check for Message default constructor added (#13220)
    
    `AbstractMarshallableMessageFactoryProvider` requires default (no-arg)
    constructor for all classes implementing `Message` interface.
    
    This PR moves check for default constructor to compile time.
---
 .../apache/ignite/internal/MessageProcessor.java   | 44 +++++++++++++++++++++-
 1 file changed, 42 insertions(+), 2 deletions(-)

diff --git 
a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageProcessor.java
 
b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageProcessor.java
index 7d0e469425d..d6d331175e8 100644
--- 
a/modules/codegen/src/main/java/org/apache/ignite/internal/MessageProcessor.java
+++ 
b/modules/codegen/src/main/java/org/apache/ignite/internal/MessageProcessor.java
@@ -33,12 +33,14 @@ import javax.annotation.processing.SupportedSourceVersion;
 import javax.lang.model.SourceVersion;
 import javax.lang.model.element.Element;
 import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
 import javax.lang.model.element.Modifier;
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.element.VariableElement;
 import javax.lang.model.type.TypeKind;
 import javax.lang.model.type.TypeMirror;
 import javax.tools.Diagnostic;
+import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.lang.IgniteBiTuple;
 
 import static 
org.apache.ignite.internal.MessageSerializerGenerator.DLFT_ENUM_MAPPER_CLS;
@@ -75,11 +77,20 @@ public class MessageProcessor extends AbstractProcessor {
     /** Externalizable message. */
     static final String MARSHALLABLE_MESSAGE_INTERFACE = 
"org.apache.ignite.internal.MarshallableMessage";
 
+    /** */
+    public static final String GRID_H2_NULL = 
"org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2Null";
+
+    /** */
+    public static final String ZK_NO_SERVERS_MESSAGE = 
"org.apache.ignite.spi.discovery.zk.internal.ZkNoServersMessage";
+
+    /** */
+    public static final Set<String> NO_PUBLIC_CTOR_MSGS = Set.of(GRID_H2_NULL, 
ZK_NO_SERVERS_MESSAGE);
+
     /** Messages with no fields. A serializer must be generated due to 
restrictions in our communication process. */
     static final String[] EMPTY_MESSAGES = {
         
"org.apache.ignite.spi.communication.tcp.messages.HandshakeWaitMessage",
-        "org.apache.ignite.spi.discovery.zk.internal.ZkNoServersMessage",
-        
"org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2Null",
+        ZK_NO_SERVERS_MESSAGE,
+        GRID_H2_NULL,
     };
 
     /** Messages with no fields. A serializer generation intentionally 
skipped. */
@@ -128,6 +139,9 @@ public class MessageProcessor extends AbstractProcessor {
                     clazz);
             }
 
+            if (!checkConstructors(clazz))
+                continue;
+
             msgFields.put(clazz, fields);
         }
 
@@ -146,6 +160,32 @@ public class MessageProcessor extends AbstractProcessor {
         return true;
     }
 
+    /** */
+    private boolean checkConstructors(TypeElement clazz) {
+        if (NO_PUBLIC_CTOR_MSGS.contains(clazz.getQualifiedName().toString()))
+            return true;
+
+        for (Element el : clazz.getEnclosedElements()) {
+            if (el.getKind() != ElementKind.CONSTRUCTOR || 
!el.getModifiers().contains(Modifier.PUBLIC))
+                continue;
+
+            ExecutableElement c = (ExecutableElement)el;
+
+            boolean isDfltConstructor = F.isEmpty(c.getParameters());
+
+            if (isDfltConstructor)
+                return true;
+        }
+
+        processingEnv.getMessager().printMessage(
+            Diagnostic.Kind.ERROR,
+            "A class must have a public default constructor: " + 
clazz.getQualifiedName(),
+            clazz
+        );
+
+        return false;
+    }
+
     /**
      * Collects all fields annotated with {@link Order} from the given {@link 
TypeElement} and all its superclasses.
      * <p>

Reply via email to