Apache Ignite.NET Documentation

The Apache Ignite .NET Developer Hub

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

Get Started    

Platform Interoperability

Ignite allows different platforms, such as .NET, Java and C++, to interoperate with each other.
Classes defined on different platforms could be converted to each other.

Identifiers

To achieve interoperability Ignite writes objects using common binary format. This format encodes object type and fields using integer identifiers.

To transform an object's type and field names to integer value, Ignite passes them through two stage:

  • Name transformation - full type name and field names are passed to IBinaryNameMapper interface and converted to some common form.
  • ID transformation - resulting strings are passed to IBinaryIdMapper to produce either type ID of field ID.

Mappers can be set either globally in BinaryConfiguration or for concrete type in BinaryTypeConfiguration.

Java has the same interfaces BinaryNameMapper and BinaryIdMapper. They are set on BinaryConfiguration or BinaryTypeConfiguration.

.NET and Java types must map to the same type ID and relevant fields must map to the same field ID.

Default behavior

.NET part of Ignite.NET applies the following conversions by default:

  • Name transformation: System.Type.FullName property for non-generics types; field or property name is unchanged.
  • ID transformation: names are converted to lower case and then ID is calculated in the same way as in java.lang.String.hashCode() method in Java.

Java part of Ignite.NET applies the following conversions by default:

  • Name transformation: Class.getName() method to get class name; field name is unchanged.
  • ID transformation: names are converted to lower case and then java.lang.String.hashCode() is used to calculate IDs.

For example, the following two types will automatically map to each other, if they are outside namespaces (.NET) and packages (Java):

class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public byte[] Data { get; set; }
}
class Person 
{
    public int id;
    public String name;
    public byte[] data;
}

However, types are normally within some namespace or package. And naming conventions for packages and namespaces differ in Java and .NET. It may be problematic to have .NET namespace be the same as Java package.

Simple name mapper (which ignores namespace) can be used to avoid this problem. It should be configured both on .NET and Java sides:

<bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
    ...
    <property name="binaryConfiguration">
        <bean class="org.apache.ignite.configuration.BinaryConfiguration">
            <property name="nameMapper">
                <bean class="org.apache.ignite.binary.BinaryBasicNameMapper">
                    <property name="simpleName" value="true"/>
                </bean>
            </property>
        </bean>
    </property>
    ...
</bean>
var cfg = new IgniteConfiguration
{
  BinaryConfiguration = new BinaryConfiguration
  {
    NameMapper = new BinaryBasicNameMapper {IsSimpleName = true}
  }
}
<igniteConfiguration>
  <binaryConfiguration>
    <nameMapper type="Apache.Ignite.Core.Binary.BinaryBasicNameMapper, Apache.Ignite.Core" isSimpleName="true" />
  </binaryConfiguration>
</igniteConfiguration>

Type Compatibility

C#
Java

bool

boolean

byte (*), sbyte

byte

short, ushort (*)

short

int, uint (*)

int

long, ulong (*)

long

char

char

float

float

double

double

decimal

java.math.BigDecimal (**)

string

java.lang.String

Guid

java.util.UUID

DateTime

java.util.Date, java.sql.Timestamp

* byte, ushort, uint, ulong do not have Java counterparts, and are mapped directly byte-by-byte (no range check). For example, byte value of 200 in C# will result in signed byte value of -56 in Java.

** Java BigDecimal has arbitrary size and precision, while C# decimal is fixed to 16 bytes and 28-29 digit precision. Ignite.NET will throw BinaryObjectException if a BigDecimal value does not fit into decimal on deserialization.

DateTime Serialization

DateTime can be Local and UTC; Java Timestamp can only be UTC. Because of that, Ignite.NET can serialize DateTime in two ways: .NET style (can work with non-UTC values, does not work in SQL) and as Timestamp (throws exception on non-UTC values, works properly in SQL).

Reflective serialization: mark field with [QuerySqlField] to enforce Timestamp serialization.

IBinarizable: use IBinaryWriter.WriteTimestamp method.

When it is not possible to modify class to mark fields with [QuerySqlField] or implement IBinarizable, use IBinarySerializer approach. See Serialization for more details.

Collection Compatibility

Arrays of simple types (from the table above) and arrays of objects are interoperable in all cases. For all other collections and arrays default behavior (with reflective serialization or IBinaryWriter.WriteObject) in Ignite.NET is to use BinaryFormatter, and the result can not be read by Java code (this is done to properly support generics). To write collections in interoperable format, implement 'IBinarizable' interface and use IBinaryWriter.WriteCollection / IBinaryWriter.WriteDictionary / IBinaryReader.ReadCollection / IBinaryReader.ReadDictionarymethods.

Mixed-Platform Clusters

Ignite, Ignite.NET and Ignite.C++ nodes can join the same cluster

All platforms are built on top of Java, so any node can execute Java computations.
However, .NET and C++ computations can be executed only by corresponding nodes.

The following Ignite.NET functionality is not supported when there is at least one non-.NET node in the cluster:

  • Scan Queries with filter
  • Continuous Queries with filter
  • ICache.Invoke methods
  • ICache.LoadCache with filter
  • Services
  • IMessaging.RemoteListen
  • IEvents.RemoteQuery

Blog post with detailed walkthrough: Multi-Platform Ignite Cluster: Java + .NET

Compute in Mixed-Platform Clusters

ICompute.ExecuteJavaTask methods work without limitations in any cluster.
Other ICompute methods will execute closures only on .NET nodes. If there are no server-mode .NET nodes in the cluster, ClusterGroupEmptyException will be thrown.

Platform Interoperability