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
Thisinitialize
extracts 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
InitializationData
parameter
Thisinitialize
uses theInitializationData
parameter (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
Thisinitialize
is a shortcut for theinitialize
in 2. above, where theInitializationData
parameter 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
InitializationData
parameter
Thisinitialize
uses theInitializationData
parameter (described below on this page) to create a new communicator. It's similar toinitialize
in 2. above, except thisinitialize
does not take arguments and does not check theICE_CONFIG
environment variable. - a config file parameter
Thisinitialize
is a shortcut for theinitialize
in 4. above, where theInitializationData
parameter contains only properties loaded from the provided configuration file. - no parameters at all
Thisinitialize
creates a communicator with no properties (meaning all Ice properties have their default value), and only default features. It also does not check theICE_CONFIG
environment 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);