Communicator Initialization
On this page:
Creating a Communicator with initialize
The first step for any Ice application is to initialize the Ice run time by calling the Ice initialize native function or method. (initialize is named createCommunicator in Objective-C). initialize returns a Communicator object, which represents an instance of the Ice run time.
You can call initialize directly (all language mappings) or in C++ through the Ice::CommunicatorHolder helper class.
Each language mapping provides several overloads for initialize with the following parameters:
- the arguments given to the application
Thisinitializeextracts Ice properties from the provided arguments, and sets them in the newly created communicator. See Command-Line Parsing and Initialization for further details. - the arguments given to the application plus an
InitializationDataparameter
Thisinitializeuses theInitializationDataparameter (described below on this page) to create a new communicator, and then extracts Ice properties from the provided arguments. The properties extracted from the arguments overwrite properties set inInitializationData. the arguments given to the application plus a config file parameter
Thisinitializeis a shortcut for theinitializein 2. above, where theInitializationDataparameter contains only properties loaded from the provided configuration file. For example, here is the corresponding implementation in Java:Javapublic static Communicator initialize(String[] args, String configFile, java.util.List<String> remainingArgs) { InitializationData initData = null; if(configFile != null) { initData = new InitializationData(); initData.properties = Util.createProperties(); initData.properties.load(configFile); } return initialize(args, initData, remainingArgs); }- an
InitializationDataparameter
Thisinitializeuses theInitializationDataparameter (described below on this page) to create a new communicator. It's similar toinitializein 2. above, except thisinitializedoes not take arguments and does not check theICE_CONFIGenvironment variable. - a config file parameter
Thisinitializeis a shortcut for theinitializein 4. above, where theInitializationDataparameter contains only properties loaded from the provided configuration file. - no parameters at all
Thisinitializecreates a communicator with no properties (meaning all Ice properties have their default value), and only default features. It also does not check theICE_CONFIGenvironment variable.
namespace Ice
{
// (1) and (2): argc/argv + InitializationData
std::shared<Communicator> initialize(int& argv, const char* argv[], const InitializationData& initData = InitializationData(),
int = ICE_INT_VERSION);
// (3): argc/argv + config file
std::shared<Communicator> initialize(int& argc, const char* argv[], const std::string& configFile,
int version = ICE_INT_VERSION);
#ifdef _WIN32
// (1) and (2): wide argc/argv + InitializationData
std::shared<Communicator> initialize(int& argc, const wchar_t* argv[], const InitializationData& initData = InitializationData(),
int version = ICE_INT_VERSION);
// (3): wide argc/argv + config file
std::shared<Communicator> initialize(int& argc, const wchar_t* argv[], const std::string& configFile,
int version = ICE_INT_VERSION);
#endif
// (1) and (2): args as a vector<string> + InitializationData
std::shared<Communicator> initialize(StringSeq& args, const InitializationData& initData = InitializationData(),
int version = ICE_INT_VERSION);
// (3): args as a vector<string> + config file
std::shared<Communicator> initialize(StringSeq& args, const std::string& configFile,
int version = ICE_INT_VERSION);
// (4) and (6): no args + InitializationData
std::shared<Communicator> initialize(const InitializationData& initData = InitializationData(),
int version = ICE_INT_VERSION);
// (5) no args + config file
std::shared<Communicator> initialize(const std::string& configFile,
int version= ICE_INT_VERSION);
}
All initialize functions have a trailing parameter int version = ICE_INT_VERSION. This parameter ensures the Ice version in the header files you used to compile your application is compatible with the Ice version in the Ice libraries loaded by this application. You should always keep the default value (ICE_INT_VERSION) for this parameter.
namespace Ice
{
// (1) and (2): argc/argv + InitializationData
CommunicatorPtr initialize(int& argv, const char* argv[], const InitializationData& initData = InitializationData(),
int = ICE_INT_VERSION);
// (3): argc/argv + config file
CommunicatorPtr initialize(int& argc, const char* argv[], const char* configFile,
int version = ICE_INT_VERSION);
#ifdef _WIN32
// (1) and (2): wide argc/argv + InitializationData
CommunicatorPtr initialize(int& argc, const wchar_t* argv[], const InitializationData& initData = InitializationData(),
int version = ICE_INT_VERSION);
// (3): wide argc/argv + config file
CommunicatorPtr initialize(int& argc, const wchar_t* argv[], const char* configFile,
int version = ICE_INT_VERSION);
#endif
// (1) and (2): args as a vector<string> + InitializationData
CommunicatorPtr initialize(StringSeq& args, const InitializationData& initData = InitializationData(),
int version = ICE_INT_VERSION);
// (3): args as a vector<string> + config file
CommunicatorPtr initialize(StringSeq& args, const char* configFile,
int version = ICE_INT_VERSION);
// (4) and (6): no args + optional InitializationData
CommunicatorPtr initialize(const InitializationData& initData = InitializationData(),
int version = ICE_INT_VERSION);
// (5): no args + config file
CommunicatorPtr initialize(const char* configFile,
int version= ICE_INT_VERSION);
}
All initialize functions have a trailing parameter int version = ICE_INT_VERSION. This parameter ensures the Ice version in the header files you used to compile your application is compatible with the Ice version in the Ice libraries loaded by this application. You should always keep the default value (ICE_INT_VERSION) for this parameter.
namespace Ice
{
public sealed class Util
{
// (1): args only
public static Communicator initialize(ref string[] args) { ... }
// (2): args + InitializationData
public static Communicator initialize(ref string[] args, InitializationData initData) { ... }
// (3): args + config file
public static Communicator initialize(ref string[] args, string configFile) { ... }
// (4): no args + InitializationData
public static Communicator initialize(InitializationData initData) { ... }
// (5): no args + config file
public static Communicator initialize(string configFile) { ... }
// (6): no parameter at all
public static Communicator initialize() { ... }
...
}
}
package com.zeroc.Ice;
public final class Util
{
// (1): args only
public static Communicator initialize(String[] args) { ... }
public static Communicator initialize(String[] args, java.util.List<String> remainingArgs) { ... }
// (2): args + InitializationData
public static Communicator initialize(String[] args, InitializationData initData) { ... }
public static Communicator initialize(String[] args, InitializationData initData, java.util.List<String> remainingArgs) { ... }
// (3): args + config file
public static Communicator initialize(String[] args, String configFile) { ... }
public static Communicator initialize(String[] args, String configFile, java.util.List<String> remainingArgs) { ... }
// (4): no args + InitializationData
public static Communicator initialize(InitializationData initData) { ... }
// (5): no args + config file
public static Communicator initialize(String configFile) { ... }
// (6): no parameter at all
public static Communicator initialize() { ... }
...
}
package Ice;
public final class Util
{
// (1): args only
public static Communicator initialize(String[] args) { ... }
public static Communicator initialize(StringSeqHolder args) { ... }
// (2): args + InitializationData
public static Communicator initialize(String[] args, InitializationData initData) { ... }
public static Communicator initialize(StringSeqHolder args, InitializationData initData) { ... }
// (3): args + config file
public static Communicator initialize(String[] args, String configFile) { ... }
public static Communicator initialize(StringSeqHolder args, String configFile) { ... }
// (4): no args + InitializationData
public static Communicator initialize(InitializationData initData) { ... }
// (5) no args + config file
public static Communicator initialize(String configFile) { ... }
// (6): no parameter at all
public static Communicator initialize() { ... }
...
}
// (1): args // (2): args + InitializationData // (4): InitializationData // (6): no parameter at all Ice.initialize = function(arg1, arg2)
% in Ice package % initialize returns the new communicator and the remaining args % (1): args (a cell array of character vectors) % (2): args + InitializationData % (3): args + config file % (4): InitializationData % (5): config file % (6): no parameter at all function [communicator, remainingArgs] = initialize(varargin)
@interface ICEUtil : NSObject // (1): argc/argv only +(id<ICECommunicator>) createCommunicator:(int*)argc argv:(char*[])argv; // (2): argc/argv + ICEInitializationData +(id<ICECommunicator>) createCommunicator:(int*)argc argv:(char*[])argv initData:(ICEInitializationData*)initData; // (3): argc/argv + config file +(id<ICECommunicator>) createCommunicator:(int*)argc argv:(char*[])argv configFile:(NSString*)configFile; // (4): no args + InitializationData +(id<ICECommunicator>) createCommunicator:(ICEInitializationData*)initData; // (5) not provided in Objective-C due to overload ambiguity // (6): no parameter at all +(id<ICECommunicator>) createCommunicator; ... @end
namespace Ice
{
// (1): args
// (2): args + InitializationData
// (4): InitializationData
// (6): no parameter at all
function initialize(args=null, initData=null)
}
# in Ice module # (1): args # (2): args + InitializationData # (3): args + config file # (4): InitializationData # (5): config file # (6): no parameter at all def initialize(args=None, data=None)
module Ice
# (1): args
# (2): args + InitializationData
# (3): args + config file
# (4): InitializationData
# (5): config file
# (6): no parameter at all
def Ice.initialize(args=nil, initData=nil)
The initialize function optionally accepts a block.
// (1) and (2): args + optional InitializationData
public func initialize(_ args: [String], initData: InitializationData? = nil) throws -> Communicator {
...
}
public func initialize(_ args: inout [String], initData: InitializationData? = nil) throws -> Communicator {
...
}
// (3): args + config file
public func initialize(args: [String], configFile: String) throws -> Communicator {
...
}
public func initialize(args: inout [String], configFile: String) throws -> Communicator {
...
}
// (4) and (6): optional InitializationData
public func initialize(_ initData: InitializationData? = nil) throws -> Communicator {
...
}
// (5) config file
public func initialize(_ configFile: String) throws -> Communicator {
...
}
InitializationData
During the creation of a communicator, the Ice run time initializes a number of features that affect the communicator's operation. Once set, these features remain in effect for the life time of the communicator, that is, you cannot change these features after you have created a communicator. Therefore, if you want to customize these features, you must do so when you create the communicator.
The following features can be customized at communicator creation time:
- the property set
- the logger object
- the instrumentation observer
- the thread start and stop notification hooks
- the dispatcher
- the compact ID resolver (used by the streaming interfaces when extracting Ice objects)
- the class loader (Java only)
- the batch request interceptor
- the value factory manager
- an array of type ID namespaces (C# only)
To establish these features, you initialize a structure or class of type InitializationData, set one or more fields of this structure or class, and pass this InitializationData to initialize or to a helper class (such as Ice Application) that calls initialize for you.
The exact definition of InitializationData depends on the language mapping you use, and some language mappings only support a subset of these features:
namespace Ice
{
struct InitializationData
{
std::shared_ptr<Ice::Properties> properties;
std::shared_ptr<Ice::Logger> logger;
std::shared_ptr<Ice::Instrumentation::CommunicatorObserver> observer;
std::function<void()> threadStart;
std::function<void()> threadStop;
std::function<void(std::function<void()>, const std::shared_ptr<Ice::Connection>&)> dispatcher;
std::function<std::string(int)> compactIdResolver;
std::function<void(const Ice::BatchRequest&, int, int)> batchRequestInterceptor;
std::shared_ptr<Ice::ValueFactoryManager> valueFactoryManager;
};
}
namespace Ice
{
struct InitializationData
{
PropertiesPtr properties;
LoggerPtr logger;
Instrumentation::CommunicatorObserverPtr observer;
ThreadNotificationPtr threadHook;
DispatcherPtr dispatcher;
CompactIdResolverPtr compactIdResolver;
BatchRequestInterceptorPtr batchRequestInterceptor;
ValueFactoryManagerPtr valueFactoryManager;
};
}
namespace Ice
{
public class InitializationData : ICloneable
{
public object Clone() { ... }
public Properties properties;
public Logger logger;
public Instrumentation.CommunicatorObserver observer;
public System.Action threadStart;
public System.Action threadStop;
public System.Action<System.Action, Connection> dispatcher;
public System.Func<int, string> compactIdResolver;
public System.Action<BatchRequest, int, int> batchRequestInterceptor;
public ValueFactoryManager valueFactoryManager;
public string[] typeIdNamespaces = { "Ice.TypeId" };
}
}
package com.zeroc.Ice;
public final class InitializationData implements Cloneable
{
@Override
public InitializationData clone() { ... }
public Properties properties;
public Logger logger;
public com.zeroc.Ice.Instrumentation.CommunicatorObserver observer;
public Runnable threadStart;
public Runnable threadStop;
public ClassLoader classLoader;
public java.util.function.BiConsumer<Runnable, Connection> dispatcher;
public java.util.function.IntFunction<String> compactIdResolver;
public BatchRequestInterceptor batchRequestInterceptor;
public ValueFactoryManager valueFactoryManager;
}
package Ice;
public final class InitializationData implements Cloneable
{
@Override
public InitializationData clone() { ... }
public Properties properties;
public Logger logger;
public Ice.Instrumentation.CommunicatorObserver observer;
public ThreadNotification threadHook;
public ClassLoader classLoader;
public Dispatcher dispatcher;
public CompactIdResolver compactIdResolver;
public BatchRequestInterceptor batchRequestInterceptor;
public ValueFactoryManager valueFactoryManager;
}
Ice.InitializationData = function()
{
this.properties = null;
this.logger = null;
this.valueFactoryManager = null;
};
% in Ice package
classdef (Sealed) InitializationData
properties
properties_
end
end
@interface ICEInitializationData : NSObject
{
...
}
@property(retain, nonatomic) id<ICEProperties> properties;
@property(retain, nonatomic) id<ICELogger> logger;
@property(copy, nonatomic) void(^dispatcher)(id<ICEDispatcherCall>, id<ICEConnection>);
@property(copy, nonatomic) void(^batchRequestInterceptor)(id<ICEBatchRequest>, int, int);
-(id) init:(id<ICEProperties>)properties logger:(id<ICELogger>)logger
dispatcher:(void(^)(id<ICEDispatcherCall>, id<ICEConnection>))d
batchRequestInterceptor:(void(^)(id<ICEBatchRequest>, int, int))i;
+(id) initializationData;
+(id) initializationData:(id<ICEProperties>)properties logger:(id<ICELogger>)logger
dispatcher:(void(^)(id<ICEDispatcherCall>, id<ICEConnection>))d
batchRequestInterceptor:(void(^)(id<ICEBatchRequest>, int, int))i;
// This class also overrides copyWithZone:, hash, isEqual:, and dealloc.
@end
namespace Ice
{
class InitializationData
{
public function __construct($properties=null, $logger=null) { ... }
public $properties;
public $logger;
}
}
# in Ice module
class InitializationData(object):
def __init__(self):
self.properties = None
self.logger = None
self.threadStart = None
self.threadStop = None
self.dispatcher = None
self.batchRequestInterceptor = None
module Ice
class InitializationData
def initialize(properties=nil, logger=nil)
...
end
attr_accessor :properties, :logger
end
end
public struct InitializationData {
public var properties: Properties?
public var logger: Logger?
public init() {}
}
For example, to set a custom logger of type MyLogger in C++, you could use:
Ice::InitializationData initData; initData.logger = std::make_shared<MyLoggerI>(); auto communicator = Ice::initialize(argc, argv, initData);
or
Ice::InitializationData initData; initData.logger = std::make_shared<MyLoggerI>(); Ice::CommunicatorHolder ich(argc, argv, initData);
Ice::InitializationData initData; initData.logger = new MyLoggerI; Ice::CommunicatorPtr communicator = Ice::initialize(argc, argv, initData);
or
Ice::InitializationData initData; initData.logger = new MyLoggerI; Ice::CommunicatorHolder ich(argc, argv, initData);