Upgrading your Application to Ice 3.7.1 from Ice 3.5

In addition to the information provided in Upgrading your Application to Ice 3.7.1 from Ice 3.6, users who are upgrading from Ice 3.5 should also review this page.

On this page:

 

Timeout changes

In previous Ice versions, the timeout set for a connection also served as the timeout for all invocations on that connection, such that an invocation timeout would cause Ice to close the connection and consequently report a timeout exception for all pending invocations on that connection.

With the addition of invocation timeouts, Ice now provides a much cleaner separation between two distinct features:

  • Connection timeouts
    These timeouts should be used as a fail-safe strategy for handling unrecoverable network errors in a timely fashion.
  • Invocation timeouts
    You can now safely abort an invocation that's taking too long to complete without affecting other invocations pending on the same connection.

Together with the new heartbeat functionality offered by Ice's Active Connection Management facility, applications now have much more control over their connections.

Existing Ice applications could configure connection timeouts in several ways, such as by setting Ice::Connection interface provides several new operations, including the ability to obtain and modify a connection's current ACM settings. If you use the Glacier2 helper classes, they call the Connection operations to tailor the ACM timeout and heartbeat based on the router's ACM configuration. Applications that manually create a Glacier2 session can configure ACM like this:

C++
Glacier2::RouterPrx router = ...
// Create a session...
int acmTimeout = router->getACMTimeout();
if(acmTimeout > 0)
{
    Ice::ConnectionPtr connection = router->ice_getCachedConnection();
    connection->setACM(acmTimeout, IceUtil::None, Ice::HeartbeatAlways);
}

The new operation Glacier2::Router::getACMTimeout returns the router's server-side ACM timeout. In this example, the client calls setACM on its connection to the router, passing this same timeout value to ensure consistency between client and server. The client also enables automatic heartbeats so that the connection remains active and prevents the router's server-side ACM from closing the connection.

The ACM improvements include changes to the ACM configuration properties. You can use these properties to achieve the same result as the code above, however the properties can potentially affect other connections as well.

Finally, another new operation on the Connection interface lets you specify a callback object that will be notified when the connection receives a heartbeat message, and when the connection closes. This feature can be especially useful for session-based applications that need to closely monitor their connections.

 

Glacier2 compatibility for helper classes

The Glacier2 helper classes in Ice 3.6 now depend on the ACM heartbeat features described above to keep a session alive. This functionality requires a Glacier2 router that also uses Ice 3.6 or later. If you're upgrading a client to Ice 3.6, we strongly recommend upgrading the Glacier2 router to 3.6 as well. Using an earlier version of Glacier2 will require your application to manually keep the session alive.

SSL changes

IceSSL for C++ has been overhauled to make use of platform-native SSL APIs where possible:

  • IceSSL on Windows now uses SChannel
  • IceSSL on OS X now uses Secure Transport
  • Linux platforms continue to use OpenSSL as in previous releases

As a result, there have been a number of changes to the IceSSL configuration properties and its C++ API. In the IceSSL.*

SSLv3 disabled by default

To improve security, IceSSL now disables the SSLv3 protocol by default. In other words, only TLS protocols are enabled by default.

Although we do not recommend it, you can enable SSLv3 using the following settings:

# Enable only SSLv3
IceSSL.Protocols=SSL3
 
# Enable SSLv3 and TLS
IceSSL.Protocols=SSL3, TLS1_0, TLS1_1, TLS1_2
 
# OS X only: Enables SSLv3 and TLS
IceSSL.ProtocolVersionMin = "SSLv3"

Refer to IceSSL.*

Logger changes

We added a new operation getPrefix to the local interface Logger.

Slice
module Ice {
local interface Logger {
...
     string getPrefix();
};
};

If you implement your own logger, you will need to update your implementation with a new getPrefixgetPrefix returns the prefix associated with this logger.

Crypt Password changes

Both the Glacier2 router and IceGrid registry provide a simple file-based authentication mechanism using a "crypt password" file that contains a list of user name and password-hash pairs. In Ice 3.5 and earlier releases, the Glacier2 router and IceGrid registry use the archaic DES-based Unix Crypt algorithm to hash the provided password and verify if this hash matches the hash in the password-file.

Ice 3.6 no longer supports this hash format on Windows and OS X. As a result, you need to regenerate your crypt password files on these platforms when upgrading to Ice 3.6.

C++ changes

Garbage collection changes

We've made significant changes to the garbage collection facility for cyclic object graphs. If your application uses this facility, note that we've removed the following:

  • Ice.GC.Interval property
  • Ice.Trace.GC property
  • Ice::collectGarbage() function

The new property Ice.CollectObjects determines whether garbage collection is enabled by default for Slice class instances that are unmarshaled by the Ice run time. Refer to the garbage collection discussion for more information on using this feature.

 

String converter changes

A number of changes have been made to the C++ string conversion API in this release:

  • The stringConverter and wstringConverter members of Ice::InitializationData have been removed. Applications should use the process-wide string converter API instead.
  • The classes and functions have moved from the Ice namespace to the IceUtil namespace.
  • Overloaded versions of the nativeToUTF8 and UTF8ToNative convenience functions that accepted a communicator argument have been removed.
  • The arguments have changed for the stringToWstring and wstringToString convenience functions.

OS X with C++

C++ developers on OS X need to be aware of several changes:

  • C++11 libraries
    With Ice 3.5, C++11 applications needed to link with a separate set of C++11-specific Ice libraries located in <Ice installation directory>/lib/c++11. The Ice 3.6 binary distribution includes a single set of libraries that also support C++11, so you'll need to modify your application's library path to use <Ice installation directory>/lib instead.
  • Minimum required version
    Ice 3.6 supports OS X 10.9 and 10.10, therefore the C++ libraries in the Ice binary distribution are built with macosx-min-version=10.9. Consequently, these libraries require libc++ and are not compatible with libstdc++.

Java changes

Java mapping changes

The default constructor generated for Slice structures, exceptions and classes behaves differently for Ice 3.6 than in previous releases. Specifically, the default constructor now initializes string data members to an empty string, enumerator data members to the first enumerator in the enumeration, and structure data members to a default-constructed value.

In previous releases, the default constructor initialized these data members to null. Applications that depend on this behavior will require updating.

For situations where the overhead of default-constructing structure data members is undesirable, applications can call the one-shot constructor instead.

The Java mapping has also relaxed its marshaling prerequisites: it is no longer necessary to initialize data members of type structure or enumerator prior to an invocation. In Ice 3.6, passing a null value for a structure or enumerator causes Ice to marshal a default-constructed structure or the first enumerator, respectively.

New Java features

We have added several features that you may wish to incorporate into your Java application:

C# changes

C# mapping changes

The default constructor generated for Slice structures, exceptions and classes behaves differently for Ice 3.6 than in previous releases. Specifically, the default constructor now initializes string data members to an empty string and structure data members to a default-constructed value.

In previous releases, the default constructor did not explicitly initialize these data members and so they had the default C# values. Applications that depend on this behavior will require updating.

For situations where the overhead of default-constructing structure data members is undesirable, applications can call the one-shot constructor instead.

The C# mapping has also relaxed its marshaling prerequisites: it is no longer necessary to initialize data members of type structure prior to an invocation. In Ice 3.6, passing a null value for a structure causes Ice to marshal a default-constructed structure.

C# serialization changes

One of the new features in Ice 3.6 is support for .NET serialization for all Slice types (except proxies). Existing applications may be affected by this change because the Ice.Optional type now implements ISerializable and the serialized format of an optional value is different than in Ice 3.5.

Python changes

Developers who are migrating existing Ice applications from Ice 3.5 should be aware of a change that affects the Python language mapping. The Ice.Unset value now has False semantics, making it more convenient to test whether an optional Slice data member has a value:

Python
# Only valid with Ice 3.6!
if obj.optionalMember:
    # optionalMember has a value

With Ice 3.5, the code above would not have the intended behavior because the test would be true even when optionalMember is set to Ice.Unset. The correct way to write this using Ice 3.5 is shown below: 

Python
# Correct test with Ice 3.5
if obj.optionalMember is not Ice.Unset:
    # optionalMember has a value

This code will also have the correct behavior with Ice 3.6, but the new style is easier to read. Also note that the Ice 3.6 semantics mean you need to use caution for optional values that can legally be set to None:

Python
if obj.optionalMember: # Fails for None AND Ice.Unset!
    # optionalMember is not Ice.Unset or None

You can distinguish between Ice.Unset and None as follows:

Python
if obj.optionalMember is Ice.Unset:
    # optionalMember is unset
elif obj.optionalMember is None:
    # optionalMember is set to None
else:
    # optionalMember is set to a value other than None 

We recommend that you review for correctness all uses of Ice.Unset and tests of optional data members.

PHP changes

No changes to the PHP mapping in Ice 3.6 affect compatibility for existing applications.

Ruby changes

No changes to the Ruby mapping in Ice 3.6 affect compatibility for existing applications.

JavaScript changes

JavaScript mapping changes

The default constructor generated for Slice structures, exceptions and classes behaves differently for Ice 3.6 than in previous releases. Specifically, the default constructor now initializes string data members to an empty string and structure data members to a default-constructed value.

In previous releases, the default constructor initialized these data members to null. Applications that depend on this behavior will require updating.

For situations where the overhead of default-constructing structure data members is undesirable, applications can call the one-shot constructor instead.

The JavaScript mapping has also relaxed its marshaling prerequisites: it is no longer necessary to initialize data members of type structure or enumerator prior to an invocation. In Ice 3.6, passing a null value for a structure or enumerator causes Ice to marshal a default-constructed structure or the first enumerator, respectively.

JavaScript packaging changes

The NodeJS packaging has changed from the original Ice for JavaScript 0.1 release, meaning existing JavaScript applications will need to modify their require statements. All of the top-level Ice modules (Ice, Glacier2, etc.) are now accessible by including the ice package:

JavaScript
var Ice = require("ice").Ice;
var Glacier2 = require("ice").Glacier2;
// ...

Loading the generated code for your own Slice definitions looks similar. Suppose we have the following definitions in Hello.ice:

Slice
module Demo {
interface Hello {
    idempotent void sayHello(int delay);
    void shutdown();
};
};

To make the Demo module conveniently accessible in our code, we can write:

JavaScript
var Demo = require("Hello").Demo;
var proxy = Demo.HelloPrx.uncheckedCast(...);

Nothing has changed for browser-based JavaScript applications, where loading Ice.js adds the Ice definitions to the global window object, and other Ice modules (Glacier2.js, etc.) must be loaded individually.

Note that Ice 3.6 adds support for the WebSocket transport to the Ice core, and includes new implementations of the WebSocket transport in Java and C#. This means you no longer need to use Glacier2 as an intermediary if your JavaScript client needs to communicate with a Java or C# server.

Objective-C changes

The default init method and convenience constructor generated for Slice structures, exceptions and classes behave differently for Ice 3.6 than in previous releases. Specifically, these methods now initialize string data members to an empty string, enumerator data members to the first enumerator, and structure data members to a default-constructed value.

In previous releases, the default constructor zero-initialized these data members. Applications that depend on this behavior will require updating.

For situations where the overhead of default-constructing structure data members is undesirable, applications can call the one-shot constructor instead.

The Objective-C mapping has also relaxed its marshaling prerequisites: it is no longer necessary to initialize data members of type structure prior to an invocation. In Ice 3.6, passing a null value for a structure causes Ice to marshal a default-constructed structure.

 

Ubuntu packages

Users of Ice 3.5 on Ubuntu had the choice of using Debian's packages or ZeroC's own experimental packages. We called them "experimental" because we expected we might eventually change the packaging structure, and in fact we have changed the structure for Ice 3.6.

Upgrading an existing installation of the ZeroC packages for Ice 3.5 on Ubuntu to Ice 3.6 is relatively straightforward. First add the Ice repository to the system and update the package list:

$ sudo apt-add-repository "deb http://zeroc.com/download/Ice/3.6/ubuntu14.04 stable main"

$ sudo apt-get update

To upgrade all of the run-time packages:

$ sudo apt-get install zeroc-ice-all-runtime

To upgrade all of the development packages:

$ sudo apt-get install libzeroc-ice-dev libzeroc-ice-java zeroc-ice-all-dev

Refer to our binary distribution page for details on the individual packages.

Migrating IceGrid databases from Ice 3.5

Ice 3.6 supports the migration of IceGrid databases from Ice 3.3, 3.4 and 3.5. To migrate from earlier Ice versions, you will first need to migrate the databases to the Ice 3.3 format. If you require assistance with such migration, please contact support@zeroc.com.

To migrate, first stop the IceGrid registry you wish to upgrade.

Next, copy the IceGrid database environment to a second location:

$ cp -r db recovered.db

Locate the correct version of the Berkeley DB recovery tool (usually named db_recover). It is essential that you use the db_recover executable that matches the Berkeley DB version of your existing Ice release. For Ice 3.3, use db_recover from Berkeley DB 4.6. For Ice 3.4, use db_recover from Berkeley DB 4.8. For Ice 3.5, use db_recover from Berkeley DB 5.3. You can verify the version of your db_recover tool by running it with the -V option:

$ db_recover -V

Now run the utility on your copy of the database environment:

$ db_recover -h recovered.db

Change to the location where you will store the database environments for IceGrid 3.6:

$ cd <new-location>

Next, run the upgradeicegrid36.py utility located in the config directory of your Ice distribution (or in /usr/share/Ice-3.6 if using an RPM installation). The first argument is the path to the old database environment. The second argument is the path to the new database environment.

In this example we'll create a new directory db in which to store the migrated database environment:

$ mkdir db
$ upgradeicegrid36.py <path-to-recovered.db> db

Upon completion, the db directory contains the migrated IceGrid databases.

By default, the migration utility assumes that the servers deployed with IceGrid also use Ice 3.6. If your servers still use an older Ice version, you need to specify the --server-version command-line option when running upgradeicegrid36.py:

$ upgradeicegrid36.py --server-version 3.5.1 <path-to-recovered.db> db

The migration utility will set the server descriptor attribute ice-version to the specified version and the IceGrid registry will generate configuration files compatible with the given version.

If you are upgrading the master IceGrid registry in a replicated environment and the slaves are still running, you should first restart the master registry in read-only mode using the --readonly option, for example:

$ icegridregistry --Ice.Config=config.master --readonly

Next, you can connect to the master registry with icegridadmin or the IceGrid administrative GUI from Ice 3.6 to ensure that the database is correct. If everything looks fine, you can shutdown and restart the master registry without the --readonly option.

IceGrid slaves from Ice 3.3, 3.4 or 3.5 won't interoperate with the IceGrid 3.6 master. You can leave them running during the upgrade of the master to not interrupt your applications. Once the master upgrade is done, you should upgrade the IceGrid slaves to Ice 3.6 using the instructions above.

Migrating IceStorm databases from Ice 3.5

No changes were made to the database schema for IceStorm in this release. Furthermore, Ice 3.5 and Ice 3.6 use the same version of Berkeley DB (Berkeley DB 5.3.x). You can use IceStorm databases created with Ice 3.5 with Ice 3.6 without any transformation.

Migrating Freeze databases from Ice 3.5

No changes were made that would affect the content of your Freeze databases. Furthermore, Ice 3.5 and Ice 3.6 use the same version of Berkeley DB (Berkeley DB 5.3.x). You can use Freeze databases created with Ice 3.5 with Ice 3.6 without any transformation.

Migrating Android applications from Ice 3.5

Our recommended development environment for Android applications is Android Studio. Refer to the Using the Binary Distribution page appropriate for your platform for instructions on configuring a project in Android Studio.

 

Changed APIs

This section describes APIs whose semantics have changed, potentially in ways that are incompatible with previous releases.

The following APIs were changed in Ice 3.6:

  • String conversion in C++
    Several changes were made to the string conversion API in C++.
  • IceSSL
    The native IceSSL APIs changed on some platforms.
  • C++ garbage collection
    The Ice::collectGarbage function was removed and replaced by a new garbage collection facility. 

 

Removed APIs

This section generally describes APIs that were deprecated in a previous release and have now been removed. Your application may no longer compile or operate successfully if it relies on one of these APIs.

The following APIs were removed in Ice 3.6:

  • Deprecated API for asynchronous method invocations (AMI)
    This API, which uses proxy operations such as sayHello_async, was deprecated in Ice 3.4 and is no longer available. The new API should be used instead. Refer to the appropriate language mapping section for more information.
  • Ice.MonitorConnections
    This setting is no longer necessary.
  • IceSSL::Plugin::setContext()
    IceSSL::Plugin::getContext()
    These C++ methods are no longer available on Windows or OS X.

  • Ice::InitializationData::stringConverter
    Ice::InitializationData::wstringConverter
    These C++ data members are no longer available.  Use IceUtil::setProcessStringConverter and IceUtil::setProcessWstringConverter instead.
  • Ice::Router::addProxy()
    IceGrid::Admin::writeMessage()

    IceStorm::Topic::subscribe()
    These Slice operations were deprecated in previous Ice releases.
  • IceUtil.Version
    This Java class was deprecated in previous Ice releases. Use Ice.Util.stringVersion() and Ice.Util.intVersion() instead.
  • Ice::Object::ice_getHash()
    This C++ method was deprecated in Ice 3.5.
  • IcePatch2.ChunkSize
    IcePatch2.Directory

    IcePatch2.Remove
    IcePatch2.Thorough
    These properties were deprecated in previous Ice releases and replaced by properties that use the prefix IcePatch2Client.
  • Glacier2.AddSSLContext
    This property was deprecated in Ice 3.3.1 and replaced by Glacier2.AddConnectionContext.

The following components were removed in Ice 3.6:

  • Qt SQL database plug-ins for IceGrid and IceStorm, which were deprecated in Ice 3.5.
    Freeze is now the only persistence mechanism for these services. 

 

Deprecated APIs

This section discusses APIs and components that are now deprecated. These APIs will be removed in a future Ice release, therefore we encourage you to update your applications and eliminate the use of these APIs as soon as possible.

The following APIs were deprecated in Ice 3.6:

  • Ice.ACM.Client
    Ice.ACM.Server
    Use Ice.ACM.Client.Timeout and Ice.ACM.Server.Timeout instead. See Active Connection Management for more information.
  • IceSSL.CertAuthFile
    Use the new property IceSSL.*