Apache Ignite C++ Documentation

The apacheignite-cpp Developer Hub

Welcome to the apacheignite-cpp developer hub. You'll find comprehensive guides and documentation to help you start working with apacheignite-cpp as quickly as possible, as well as support if you get stuck. Let's jump right in!

Get Started    

Platform Interoperability

Seamlessly interoperate between C++ and Java nodes.

When using Apache Ignite C++, it is quite common to have several C++ and Java nodes working together within a cluster. To seamlessly interoperate between C++ and Java nodes, the following should be taken into consideration:

Binary Marshaller Configuration

Apache Ignite binary marshaller is responsible for data, logic and messages serialization and deserialization in the cluster. Due to architectural specificities, Java and C++ nodes are started with different default settings of the binary marshaller that can lead to exceptions like the one below during a node startup if you try to set up a heterogeneous cluster:

class org.apache.ignite.spi.IgniteSpiException: Local node's
binary configuration is not equal to remote node's binary configuration
[locNodeId=b3f0367d-3c2b-47b4-865f-a62c656b5d3f,
rmtNodeId=556a3f41-eab1-4d9f-b67c-d94d77ddd89d,
locBinaryCfg={globIdMapper=org.apache.ignite.binary.BinaryBasicIdMapper,
compactFooter=false, globSerializer=null}, rmtBinaryCfg=null]

To get over the exception and to make sure Java and C++ nodes can coexist in a single cluster add the following binary marshaller's settings to a Java nodes' configuration you have:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
	    ...
        <property name="binaryConfiguration">
            <bean class="org.apache.ignite.configuration.BinaryConfiguration">
                <property name="compactFooter" value="false"/>

                <property name="idMapper">
                    <bean class="org.apache.ignite.binary.BinaryBasicIdMapper">
                        <property name="lowerCase" value="true"/>
                    </bean>
                </property>
            </bean>
        </property>
		...
    </bean>
</beans>

Basic Types Compatibility

There are basic types in both C++ and Java that can be used in Ignite as is. It is not always easy to understand which primitive C++ type matches which Java type, and vice versa. To clarify that, you can refer to table below:

Java Type
C++ Type

boolean, java.lang.Boolean

bool

byte, java.lang.Byte

int8_t

short, java.lang.Short

int16_t

int, java.lang.Integer

int32_t

long, java.lang.Long

int64_t

float, java.lang.Float

float

double, java.lang.Double

double

char, java.lang.Character

uint16_t

java.lang.String

std::string, char[]

java.util.Date

ignite::Date

java.sql.Time

ignite::Time

java.sql.Timestamp

ignite::Timestamp

java.util.UUID

ignite::Guid

Defining Cross-Platform Type

To get access to the same object from both Java and C++ nodes, you should describe it in the same way in both the languages. This includes the same type name, type id, fields id, hash code algorithm, as well as read/write functions for the type.

To do so in C++, one should specialize ignite::binary::BinaryType class template.

Let's consider the following example that makes a Java class operable from the C++ side:

package org.apache.ignite.examples;

public class CrossClass implements Binarylizable {
    private long id;

    private int idPart;

    public void readBinary(BinaryReader reader) throws BinaryObjectException {
        id = reader.readLong("id");
        idPart = reader.readInt("idPart");
    }

    public void writeBinary(BinaryWriter writer) throws BinaryObjectException {
        writer.writeLong("id", id);
        writer.writeInt("idPart", idPart);
    }
}

We will also need to define an analogue class on the C++ side, like so:

namespace ignite
{
  namespace binary
  {
    template<>
    struct BinaryType<CrossClass>
    {
      static int32_t GetTypeId()
      {
        return GetBinaryStringHashCode("CrossClass");
      }

      static void GetTypeName(std::string& name)
      {
        name = "CrossClass";
      }

      static int32_t GetFieldId(const char* name)
      {
        return GetBinaryStringHashCode(name);
      }

      static bool IsNull(const CrossClass& obj)
      {
        return false;
      }

      static void GetNull(CrossClass& dst)
      {
        dst = CrossClass();
      }

      static void Read(BinaryReader& reader, CrossClass& dst)
      {
        dst.id = reader.ReadInt64("id");
        dst.idPart = reader.ReadInt32("idPart");
      }

      static void Write(BinaryWriter& writer, const CrossClass& obj)
      {
        writer.WriteInt64("id", obj.id);
        writer.WriteInt32("idPart", obj.idPart);
      }
    };
  }
}

Finally, we need to add the following beans to our BinaryConfiguration for both Java and C++ spring configuration files:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
	    ...
        <property name="binaryConfiguration">
            <bean class="org.apache.ignite.configuration.BinaryConfiguration">
                <property name="compactFooter" value="false"/>

                <property name="idMapper">
                    <bean class="org.apache.ignite.binary.BinaryBasicIdMapper">
                        <property name="lowerCase" value="true"/>
                    </bean>
                </property>

                <property name="nameMapper">
                    <bean class="org.apache.ignite.binary.BinaryBasicNameMapper">
                        <property name="simpleName" value="true"/>
                    </bean>
                </property>

                <property name="classNames">
                    <list>
                        <value>org.apache.ignite.examples.CrossClass</value>
                    </list>
                </property>
            </bean>
        </property>
		...
    </bean>
</beans>

It is especially important to implement GetTypeName() and GetTypeId() methods in the right manner for the types that you are planning to use as keys.

C++ function GetBinaryStringHashCode() always calculates hash as BinaryBasicIdMapper when its property lowerCase is set to true. So make sure you have the correct configuration for the BinaryBasicIdMapper if you are going to use this function to calculate the type id in C++.