This page describes notable additions and improvements in Ice 3.7. For a detailed list of the changes in this release, please refer to the changelog in the source tree. Our upgrade guide documents the changes that may affect the operation of your applications or have an impact on your source code.
On this page:
New Features Introduced in Ice 3.7.1
This section describes the new features first introduced with Ice 3.7.1.
New MATLAB Mapping
Ice provides a new Slice to MATLAB mapping, which allows you to develop Ice clients using only MATLAB. For example:
Support for .NET Core 2.0 on Linux and Windows
You can now use Ice for C#/.NET to build .NET Core 2.0 applications on Linux and Windows. See Building Ice Applications for .NET for additional details.
In Ice 3.7.0 and Ice 3.6, Ice for C#/.NET was only available for Windows applications built with the .NET Framework.
ice_fixed Proxy Factory Method
A fixed proxy is a proxy bound to a connection, and you need to create such a proxy to send a request from a server to a client over a bidirectional connection (in this context the sender of the request is the server and the receiver is the client).
The new proxy factory method
ice_fixed creates a fixed proxy bound to the connection given as parameter.
As of this release, the preferred way to pass a proxy to a callback object from a client to a server is as a proxy. The server then calls
ice_fixed on this proxy with
current.con to create the fixed proxy it needs. Ice demo programs, such as
Ice/bidir, use this pattern. In previous releases, the recommended approach was to send the identity of the client's callback object to the server; the server then created the fixed proxy by calling
createProxy on the connection. Passing the callback proxy as a proxy instead of an identity is type-safe and follows our general recommendation to pass proxies as proxies - not as strings or identities.
Main New Features Introduced in Ice 3.7.0
This section describes the major new features introduced in Ice 3.7.0.
Ice-E and Ice Touch Merged into Ice
Ice-E and Ice Touch are now part of Ice. They are no longer separate products.
In particular, the latest Ice binary distribution for macOS includes support for Xcode SDKs and iOS. Refer to Using the macOS binary distribution for information on how to use the Xcode SDKs provided with the Ice binary distribution.
New C++11 Mapping
Ice now provides two distinct Slice to C++ mappings:
- The C++98 mapping, which corresponds to the C++ mapping provided by prior Ice releases.
- A new C++11 mapping, which takes full advantage of C++11 features, including standard smart pointers, move semantics, lambda expressions, futures and promises, and much more.
Standard shared_ptr for Everything
With the C++11 mapping, virtually all Ice objects are manipulated through
std::shared_ptr smart pointers. For example:
With the C++11 mapping, Ice provides two options for asynchronous method invocation (AMI): a function that returns a
std::future of the result, and a function that takes
std::function "callbacks" to process the result. For example, the Slice operation
string getName() is mapped to a proxy class with the following Async functions:
Your code can then use the standard future API, or lambda expressions, to process the result of these asynchronous calls. For example:
With the C++11 mapping, the API for asynchronous method dispatch (AMD) closely resembles its AMI counterpart with callbacks:
Even though the response callbacks are not identical in AMI and AMD, they are compatible, which allows you to easily chain AMD and AMI calls:
On the server-side, the generated code allocates
in parameters on the stack before dispatching the call to your operation implementation. With the C++98 mapping, "big" parameters such as strings, structs and sequences are passed as
const&, just like on the client-side. With the C++11 mapping, they are passed as values, which allows you to move them. For example:
is mapped to:
So you can now keep this parameter without additional memory allocation:
The same rule applies for any parameter that Ice allocates and then gives to your application, like (for example) return and out parameters given to AMI response callbacks.
New Java Mapping
Similar to what we've done for C++, Ice 3.7 supports two Java mappings: Java and Java Compat. As its name suggests, the Java Compat mapping is provided primarily for backward compatibility purposes so that existing Java applications can be upgraded to Ice 3.7 without requiring much change. Note however that the Java Compat mapping will be removed in the next release and we recommend migrating applications to the new Java mapping as soon as possible.
The primary goals of the new Java mapping were modernization, standardization, and simplification. We provide an overview of the new features below. Please refer to the Java Mapping and Java Compat Mapping chapters for additional information.
Regardless of whether you use the Java Compat mapping or the Java mapping, the minimum required Java version for Ice 3.7 is Java 8.
Clients can easily use lambdas as asynchronous callbacks by configuring the future:
CompletableFuture class provides a great deal of flexibility and power for implementing your asynchronous programming requirements.
The implementation is responsible for creating and returning a completion stage that must eventually be completed with a result or an exception. Typically the implementation will return an instance of
CompletableFuture, which implements the
The Java mapping no longer uses "holder" classes to provide the values of out parameters. For Slice operations that return a single value (either as the return type or as an out parameter), the mapped method provides the value as its return type. Consider these operations:
The mapping for these two operations is identical:
For Slice operations that return multiple values, the mapping generates an extra class to hold the operation's results:
The mapping for
getAll is shown below:
Changing the API to ensure that all mapped operations return at most one logical value enabled us to use
CompletionStage in our AMI and AMD mappings, respectively.
As part of the standardization goal, optional parameters and data members are now mapped to the
java.util.Optional family of classes.
Servant Interfaces and Tie Classes
Tie classes are no longer necessary or supported with the Java mapping. Tie classes were a useful implementation technique in prior Ice versions that allowed a servant to implement Slice operations without the need to extend a generated class, making it possible for the servant to extend an arbitrary base class.
Now all servant code is generated in an interface, so your servant class only needs to implement the generated interface and can extend an arbitrary base class without the need for a tie class.
All classes have been moved to the
com.zeroc package (e.g.,
C# Support for async and await
The C# mappings for asynchronous method invocation (AMI) and asynchronous method dispatch (AMD) are completely new in Ice 3.7 and take advantage of the new asynchronous programming features introduced with .NET 4.5.
begin_/end_ proxy API from previous Ice versions is still supported for backward compatibility purposes but is now deprecated and will be removed in the next Ice version. No backward-compatible API is provided for AMD operations.
The sections below provide an overview of these changes.
The API for asynchronous method invocation (AMI) now uses .NET's
Task class. For example, the Slice operation
string getName() would be mapped as follows:
Clients can use the
await keyword to suspend processing of the current thread and resume it as a continuation when the task is complete:
You could also interact with the task directly:
Or configure a lambda to execute as the continuation:
As with AMI, the API for asynchronous method dispatch (AMD) has also changed significantly. Now the mapping closely resembles its AMI counterpart in that an AMD operation returns a
The implementation is responsible for creating and returning a task that must eventually be completed with a result or an exception.
The C# mapping for AMI and AMD no longer uses out parameters. For Slice operations that return a single value (either as the return type or as an out parameter), the mapped method provides the value as its return type. Consider these operations:
The AMI mapping for these two operations is identical:
For Slice operations that return multiple values, the mapping generates an extra type to hold the operation's results:
The mapping for
getAll is shown below:
Changing the API to ensure that all mapped operations return at most one logical value enabled us to use tasks in our AMI and AMD mappings, respectively.
- All Promise objects returned by the Ice run time are derived from the standard Promise type.
- The mapping for dictionaries is now based on the standard Map type. The
The API for Asynchronous Method Dispatch (AMD) has been updated to use the standard Promise class. There are several differences with respect to the previous API:
- The Servant skeleton does not generate separate
_asyncmethods for AMD.
- At run time a servant can take advantage of AMD by returning a Promise object.
Consider the following example, where we define a
getName operation in Slice:
Python Changes for AMI and AMD
We've added a new AMI mapping and modified the AMD mapping in Python.
The existing AMI mapping is still supported for backward compatibility, but new applications should use the new AMI mapping. The changes to the AMD mapping break backward compatibility and require modifications to existing applications. Refer to the upgrade guide for more information.
The new API for asynchronous method invocation (AMI) uses future objects and adds the
Async suffix to proxy methods. For example, the Slice operation
string getName() would be mapped as follows:
Asynchronous proxy methods return instances of
Ice.Future, which has an API similar to the built-in Python types
Clients can easily configure the future with a completion callback:
Ice.Future class also provides methods for checking the status of an invocation, cancelling an invocation, and blocking until the invocation completes, among others.
The API for asynchronous method dispatch (AMD) has changed significantly:
_asyncsuffix is no longer used in the name of a dispatch method
- The dispatch method does not receive a callback object
- The dispatch method can either return results directly (like a synchronous dispatch method), or return a future object to be completed later
In essence, the synchronous and asynchronous mappings have been merged into a single mapping in which the value returned at run time dictates the semantics of the dispatch. If the implementation returns a future, Ice configures it with a callback and marshals the results when the future completes. For all other return types, Ice assumes the dispatch completed successfully and marshals the results immediately.
Here's an example:
Python 3.5 Features
The Python mapping adds the following features for applications using Python 3.5 or later:
- Servant dispatch methods can be implemented as coroutines
Ice.Futureobjects are awaitable, meaning they can be targets of the
Aside from these features, all of the improvements to the Python mapping can be used in Python 2.x or later.
New Database Back-end for IceGrid and IceStorm
IceGrid and IceStorm now store their data in LMDB databases. LMDB is a popular embedded database system known for its speed and reliability.
In prior Ice releases, IceGrid and IceStorm relied on Freeze for persistent storage, and Freeze itself stores its data in Oracle Berkeley DB databases. The migration instructions describe how to migrate your existing IceGrid and IceStorm databases to the new LMDB format.
Bluetooth Transport for Linux and Android
Our newest transport plug-in enables Ice applications on Linux and Android to communicate with one another via Bluetooth. Once two devices are paired, establishing a peer-to-peer Bluetooth connection is just as convenient as with any other Ice transport. For example, a client can use a stringified proxy like this:
objectId:bt -a "01:23:45:67:89:AB" -u dfde1c02-d907-4ca1-bd99-31804c569624
-a option denotes the device address of the peer and the
-u option defines the unique identifier (UUID) associated with the desired Ice service on the peer device. It's also possible to secure the bluetooth connection with SSL by configuring IceSSL and using a
bts endpoint instead.
iAP Transport for iOS
The new Ice iAP transport enables iOS clients to communicate with accessories over Bluetooth or the Apple Lightning or 30-pin connector.
This transport requires special support on the accessory-side and is only provided as a preview to demonstrate how it can be used in iOS applications to support Bluetooth communications. Please contact us for more information.
For example, a client can use a stringified proxy like this to communicate with an accessory that advertises the
objectId:iap -p com.zeroc.helloWorld
It's also possible to secure the accessory connection with SSL by configuring IceSSL and using an
iaps endpoint instead.
Refer to the Ice manual for more information on the plug-in.
Other New Features Introduced in Ice 3.7.0
This section describes other noteworthy features introduced in Ice 3.7.0
Optional Semicolons after Braces in Slice
Semicolons are now optional after a closing brace in Slice. For example, with Ice releases up to Ice 3.6, you would write:
With Ice 3.7, the definitions above remain valid, but you can also remove the semicolons after the closing braces, as in:
Simplified Communicator Destruction
Ice 3.7 provides support for automatic communicator destruction in most programming languages.
- C#: Communicator implements
IDisposable(since Ice 3.6)
- Java: Communicator is
- Python: Communicator implements the Python context manager protocol
The Freeze persistent service is no longer included in the ice source repository or in the Ice binary distributions. It's now a separate add-on, with its own source repository and binary distributions.