diff options
60 files changed, 2939 insertions, 351 deletions
diff --git a/cpp/allTests.py b/cpp/allTests.py index f124bf519bd..d3107df594f 100755 --- a/cpp/allTests.py +++ b/cpp/allTests.py @@ -66,6 +66,7 @@ tests = [ ("Ice/defaultServant", ["core"]), ("Ice/defaultValue", ["core"]), ("Ice/invoke", ["core", "novc6"]), + ("Ice/plugin", ["core"]), ("Ice/hash", ["once"]), ("IceSSL/configuration", ["once", "novalgrind"]), # valgrind doesn't work well with openssl ("IceBox/configuration", ["core", "noipv6", "novc6", "nomingw"]), diff --git a/cpp/src/Ice/DynamicLibrary.cpp b/cpp/src/Ice/DynamicLibrary.cpp index 5b690df5f2b..ab724a9847a 100644 --- a/cpp/src/Ice/DynamicLibrary.cpp +++ b/cpp/src/Ice/DynamicLibrary.cpp @@ -50,7 +50,28 @@ IceInternal::DynamicLibrary::~DynamicLibrary() IceInternal::DynamicLibrary::symbol_type IceInternal::DynamicLibrary::loadEntryPoint(const string& entryPoint, bool useIceVersion) { + +#ifdef _WIN32 + bool isFilePath = entryPoint.find('\\') != string::npos || entryPoint.find('/') != string::npos; +#else + bool isFilePath = entryPoint.find('/') != string::npos; +#endif + string::size_type colon = entryPoint.rfind(':'); + +#ifdef _WIN32 + const string driveLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + if(colon == 1 && driveLetters.find(entryPoint[0]) != string::npos && + (entryPoint[2] == '\\' || entryPoint[2] == '/')) + { + // + // The only colon we found is in the drive specification, as in "C:\MyDir". + // This means the function name is missing. + // + colon = string::npos; + } +#endif + string::size_type comma = entryPoint.find(','); if(colon == string::npos || colon == entryPoint.size() - 1 || (comma != string::npos && (comma > colon || comma == colon - 1))) @@ -58,9 +79,22 @@ IceInternal::DynamicLibrary::loadEntryPoint(const string& entryPoint, bool useIc _err = "invalid entry point format `" + entryPoint + "'"; return 0; } + string libSpec = entryPoint.substr(0, colon); string funcName = entryPoint.substr(colon + 1); - string libName, version, debug; + string libPath, libName, version, debug; + + if(isFilePath) + { +#ifdef _WIN32 + string::size_type separator = entryPoint.find_last_of("/\\"); +#else + string::size_type separator = entryPoint.rfind('/'); +#endif + libPath = libSpec.substr(0, separator + 1); + libSpec = libSpec.substr(separator + 1); + } + if(comma == string::npos) { libName = libSpec; @@ -70,7 +104,7 @@ IceInternal::DynamicLibrary::loadEntryPoint(const string& entryPoint, bool useIc int minorVersion = (ICE_INT_VERSION / 100) - majorVersion * 100; ostringstream os; os << majorVersion * 10 + minorVersion; - + int patchVersion = ICE_INT_VERSION % 100; if(patchVersion > 50) { @@ -89,10 +123,10 @@ IceInternal::DynamicLibrary::loadEntryPoint(const string& entryPoint, bool useIc version = libSpec.substr(comma + 1); } - string lib; + string lib = libPath; #ifdef _WIN32 - lib = libName; + lib += libName; # ifdef COMPSUFFIX // @@ -114,13 +148,13 @@ IceInternal::DynamicLibrary::loadEntryPoint(const string& entryPoint, bool useIc lib += ".dll"; #elif defined(__APPLE__) - lib = "lib" + libName; - if(!version.empty()) + lib += "lib" + libName; + if(!version.empty()) { lib += "." + version; } #elif defined(__hpux) - lib = "lib" + libName; + lib += "lib" + libName; if(!version.empty()) { lib += "." + version; @@ -130,14 +164,14 @@ IceInternal::DynamicLibrary::loadEntryPoint(const string& entryPoint, bool useIc lib += ".sl"; } #elif defined(_AIX) - lib = "lib" + libName + ".a(lib" + libName + ".so"; + lib += "lib" + libName + ".a(lib" + libName + ".so"; if(!version.empty()) { lib += "." + version; } lib += ")"; #else - lib = "lib" + libName + ".so"; + lib += "lib" + libName + ".so"; if(!version.empty()) { lib += "." + version; @@ -217,16 +251,16 @@ IceInternal::DynamicLibrary::getSymbol(const string& name) #else symbol_type result = dlsym(_hnd, name.c_str()); #endif - + if(result == 0) { // // Remember the most recent error in _err. // #ifdef _WIN32 - _err = IceUtilInternal::lastErrorToString(); + _err = IceUtilInternal::lastErrorToString(); #else - const char* err = dlerror(); + const char* err = dlerror(); if(err) { _err = err; diff --git a/cpp/src/Ice/PluginManagerI.cpp b/cpp/src/Ice/PluginManagerI.cpp index 513a3036ea6..bb2bcd37959 100644 --- a/cpp/src/Ice/PluginManagerI.cpp +++ b/cpp/src/Ice/PluginManagerI.cpp @@ -7,6 +7,7 @@ // // ********************************************************************** +#include <IceUtil/Options.h> #include <Ice/PluginManagerI.h> #include <Ice/DynamicLibrary.h> #include <Ice/Communicator.h> @@ -40,10 +41,10 @@ Ice::PluginManagerI::initializePlugins() vector<PluginPtr> initializedPlugins; try { - for(vector<PluginPtr>::iterator p = _initOrder.begin(); p != _initOrder.end(); ++p) + for(PluginInfoList::iterator p = _plugins.begin(); p != _plugins.end(); ++p) { - (*p)->initialize(); - initializedPlugins.push_back(*p); + p->plugin->initialize(); + initializedPlugins.push_back(p->plugin); } } catch(...) @@ -75,10 +76,9 @@ Ice::PluginManagerI::getPlugins() IceUtil::Mutex::Lock sync(*this); StringSeq names; - map<string, PluginPtr>::iterator r; - for(r = _plugins.begin(); r != _plugins.end(); ++r) + for(PluginInfoList::iterator p = _plugins.begin(); p != _plugins.end(); ++p) { - names.push_back((*r).first); + names.push_back(p->name); } return names; } @@ -93,10 +93,10 @@ Ice::PluginManagerI::getPlugin(const string& name) throw CommunicatorDestroyedException(__FILE__, __LINE__); } - map<string, PluginPtr>::const_iterator r = _plugins.find(name); - if(r != _plugins.end()) + PluginPtr p = findPlugin(name); + if(p) { - return (*r).second; + return p; } NotRegisteredException ex(__FILE__, __LINE__); @@ -115,15 +115,18 @@ Ice::PluginManagerI::addPlugin(const string& name, const PluginPtr& plugin) throw CommunicatorDestroyedException(__FILE__, __LINE__); } - map<string, PluginPtr>::const_iterator r = _plugins.find(name); - if(r != _plugins.end()) + if(findPlugin(name)) { AlreadyRegisteredException ex(__FILE__, __LINE__); ex.kindOfObject = _kindOfObject; ex.id = name; throw ex; } - _plugins[name] = plugin; + + PluginInfo info; + info.name = name; + info.plugin = plugin; + _plugins.push_back(info); } void @@ -135,40 +138,44 @@ Ice::PluginManagerI::destroy() { if(_initialized) { - map<string, PluginPtr>::iterator r; - for(r = _plugins.begin(); r != _plugins.end(); ++r) + + // + // Destroy the plug-ins that have been successfully initialized, in the + // reverse order. + // + for(PluginInfoList::reverse_iterator p = _plugins.rbegin(); p != _plugins.rend(); ++p) { try { - r->second->destroy(); - r->second = 0; + p->plugin->destroy(); } catch(const std::exception& ex) { Warning out(getProcessLogger()); - out << "unexpected exception raised by plug-in `" << r->first << "' destruction:\n" << ex.what(); + out << "unexpected exception raised by plug-in `" << p->name << "' destruction:\n" << ex.what(); } catch(const std::string& str) { Warning out(getProcessLogger()); - out << "unexpected exception raised by plug-in `" << r->first << "' destruction:\n" << str; + out << "unexpected exception raised by plug-in `" << p->name << "' destruction:\n" << str; } catch(const char* msg) { Warning out(getProcessLogger()); - out << "unexpected exception raised by plug-in `" << r->first << "' destruction:\n" << msg; + out << "unexpected exception raised by plug-in `" << p->name << "' destruction:\n" << msg; } catch(...) { Warning out(getProcessLogger()); - out << "unexpected exception raised by plug-in `" << r->first << "' destruction"; + out << "unexpected exception raised by plug-in `" << p->name << "' destruction"; } } } - + _communicator = 0; } + _plugins.clear(); _libraries = 0; } @@ -206,7 +213,7 @@ Ice::PluginManagerI::loadPlugins(int& argc, char* argv[]) { string name = *p; - if(_plugins.find(name) != _plugins.end()) + if(findPlugin(name)) { PluginInitializationException ex(__FILE__, __LINE__); ex.reason = "plug-in `" + name + "' already loaded"; @@ -239,7 +246,7 @@ Ice::PluginManagerI::loadPlugins(int& argc, char* argv[]) // // Load any remaining plug-ins that weren't specified in PluginLoadOrder. // - + while(!plugins.empty()) { PropertyDict::iterator p = plugins.begin(); @@ -262,7 +269,7 @@ Ice::PluginManagerI::loadPlugins(int& argc, char* argv[]) name = name.substr(0, dotPos); loadPlugin(name, p->second, cmdArgs); plugins.erase(p); - + plugins.erase("Ice.Plugin." + name); } else @@ -273,7 +280,7 @@ Ice::PluginManagerI::loadPlugins(int& argc, char* argv[]) dotPos = string::npos; } } - + if(dotPos == string::npos) { // @@ -299,36 +306,29 @@ Ice::PluginManagerI::loadPlugin(const string& name, const string& pluginSpec, St { assert(_communicator); // - // Separate the entry point from the arguments. + // Split the entire property value into arguments. An entry point containing spaces + // must be enclosed in quotes. // - string entryPoint; StringSeq args; - const string delim = " \t\n"; - string::size_type pos = pluginSpec.find_first_of(delim); - if(pos == string::npos) + try { - entryPoint = pluginSpec; + args = IceUtilInternal::Options::split(pluginSpec); } - else + catch(const IceUtilInternal::BadOptException& ex) { - entryPoint = pluginSpec.substr(0, pos); - string::size_type beg = pluginSpec.find_first_not_of(delim, pos); - while(beg != string::npos) - { - string::size_type end = pluginSpec.find_first_of(delim, beg); - if(end == string::npos) - { - args.push_back(pluginSpec.substr(beg)); - beg = end; - } - else - { - args.push_back(pluginSpec.substr(beg, end - beg)); - beg = pluginSpec.find_first_not_of(delim, end); - } - } + PluginInitializationException e(__FILE__, __LINE__); + e.reason = "invalid arguments for plug-in `" + name + "':\n" + ex.reason; + throw e; } + assert(!args.empty()); + + // + // Shift the arguments. + // + const string entryPoint = args[0]; + args.erase(args.begin()); + // // Convert command-line options into properties. First we // convert the options from the plug-in configuration, then @@ -373,15 +373,30 @@ Ice::PluginManagerI::loadPlugin(const string& name, const string& pluginSpec, St throw e; } - _plugins[name] = plugin; - _initOrder.push_back(plugin); + PluginInfo info; + info.name = name; + info.plugin = plugin; + _plugins.push_back(info); _libraries->add(library); } +Ice::PluginPtr +Ice::PluginManagerI::findPlugin(const string& name) const +{ + for(PluginInfoList::const_iterator p = _plugins.begin(); p != _plugins.end(); ++p) + { + if(name == p->name) + { + return p->plugin; + } + } + return 0; +} + void -IceInternal::loadPlugin(const Ice::CommunicatorPtr& communicator, - const string& name, +IceInternal::loadPlugin(const Ice::CommunicatorPtr& communicator, + const string& name, const string& pluginSpec, Ice::StringSeq& cmdArgs) { diff --git a/cpp/src/Ice/PluginManagerI.h b/cpp/src/Ice/PluginManagerI.h index ecb73fa3a43..a7b7578ebaa 100644 --- a/cpp/src/Ice/PluginManagerI.h +++ b/cpp/src/Ice/PluginManagerI.h @@ -41,17 +41,25 @@ private: PluginManagerI(const CommunicatorPtr&, const IceInternal::DynamicLibraryListPtr&); friend class IceInternal::Instance; - friend void IceInternal::loadPlugin(const Ice::CommunicatorPtr&, const std::string&, const std::string&, + friend void IceInternal::loadPlugin(const Ice::CommunicatorPtr&, const std::string&, const std::string&, Ice::StringSeq&); void loadPlugins(int&, char*[]); void loadPlugin(const std::string&, const std::string&, StringSeq&); + PluginPtr findPlugin(const std::string&) const; + CommunicatorPtr _communicator; IceInternal::DynamicLibraryListPtr _libraries; - std::map<std::string, PluginPtr> _plugins; - std::vector<PluginPtr> _initOrder; + struct PluginInfo + { + std::string name; + PluginPtr plugin; + }; + typedef std::vector<PluginInfo> PluginInfoList; + + PluginInfoList _plugins; bool _initialized; static const char * const _kindOfObject; }; diff --git a/cpp/src/IceBox/ServiceManagerI.cpp b/cpp/src/IceBox/ServiceManagerI.cpp index 60f0959dcb5..f91e9cd8da2 100644 --- a/cpp/src/IceBox/ServiceManagerI.cpp +++ b/cpp/src/IceBox/ServiceManagerI.cpp @@ -22,18 +22,18 @@ using namespace std; typedef IceBox::Service* (*SERVICE_FACTORY)(CommunicatorPtr); -namespace +namespace { class PropertiesAdminI : public PropertiesAdmin { public: - + PropertiesAdminI(const PropertiesPtr& properties) : _properties(properties) { } - + virtual string getProperty(const string& name, const Current&) { return _properties->getProperty(name); @@ -43,10 +43,10 @@ public: { return _properties->getPropertiesForPrefix(prefix); } - + private: - const PropertiesPtr _properties; + const PropertiesPtr _properties; }; struct StartServiceInfo @@ -56,28 +56,28 @@ struct StartServiceInfo name = service; // - // Separate the entry point from the arguments. + // Split the entire property value into arguments. An entry point containing spaces + // must be enclosed in quotes. // - string::size_type pos = value.find_first_of(" \t\n"); - if(pos == string::npos) + try { - entryPoint = value; + args = IceUtilInternal::Options::split(value); } - else + catch(const IceUtilInternal::BadOptException& ex) { - entryPoint = value.substr(0, pos); - try - { - args = IceUtilInternal::Options::split(value.substr(pos + 1)); - } - catch(const IceUtilInternal::BadOptException& ex) - { - FailureException e(__FILE__, __LINE__); - e.reason = "ServiceManager: invalid arguments for service `" + name + "':\n" + ex.reason; - throw e; - } + PluginInitializationException e(__FILE__, __LINE__); + e.reason = "invalid arguments for service `" + name + "':\n" + ex.reason; + throw e; } + assert(!args.empty()); + + // + // Shift the arguments. + // + entryPoint = args[0]; + args.erase(args.begin()); + for(Ice::StringSeq::const_iterator p = serverArgs.begin(); p != serverArgs.end(); ++p) { if(p->find("--" + name + ".") == 0) @@ -92,10 +92,9 @@ struct StartServiceInfo Ice::StringSeq args; }; - } -IceBox::ServiceManagerI::ServiceManagerI(CommunicatorPtr communicator, int& argc, char* argv[]) : +IceBox::ServiceManagerI::ServiceManagerI(CommunicatorPtr communicator, int& argc, char* argv[]) : _communicator(communicator), _pendingStatusChanges(false), _traceServiceObserver(0), @@ -169,7 +168,7 @@ IceBox::ServiceManagerI::startService(const string& name, const Current&) Warning out(_logger); out << "ServiceManager: unknown exception in start for service " << info.name; } - + { IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); @@ -290,7 +289,7 @@ IceBox::ServiceManagerI::addObserver(const ServiceObserverPrx& observer, const I { Trace out(_logger, "IceBox.ServiceObserver"); out << "Added service observer " << _communicator->proxyToString(observer); - } + } vector<string> activeServices; for(vector<ServiceInfo>::iterator p = _services.begin(); p != _services.end(); ++p) @@ -301,7 +300,7 @@ IceBox::ServiceManagerI::addObserver(const ServiceObserverPrx& observer, const I activeServices.push_back(info.name); } } - + if(activeServices.size() > 0) { observer->begin_servicesStarted(activeServices, _observerCompletedCB); @@ -345,7 +344,7 @@ IceBox::ServiceManagerI::start() // // IceBox.Service.Foo=entry_point [args] // - // We parse the service properties specified in IceBox.LoadOrder + // We parse the service properties specified in IceBox.LoadOrder // first, then the ones from remaining services. // const string prefix = "IceBox.Service."; @@ -369,7 +368,7 @@ IceBox::ServiceManagerI::start() { servicesInfo.push_back(StartServiceInfo(p->first.substr(prefix.size()), p->second, _argv)); } - + // // Check if some services are using the shared communicator in which // case we create the shared communicator now with a property set which @@ -416,12 +415,12 @@ IceBox::ServiceManagerI::start() { initData.properties->setProperty(r->first, r->second); } - + // - // Parse <service>.* command line options (the Ice command line options + // Parse <service>.* command line options (the Ice command line options // were parsed by the createProperties above) // - q->args = initData.properties->parseCommandLineOptions(q->name, q->args); + q->args = initData.properties->parseCommandLineOptions(q->name, q->args); } _sharedCommunicator = initialize(initData); } @@ -462,7 +461,7 @@ IceBox::ServiceManagerI::start() // // Add a Properties facet for each service - // + // for(vector<ServiceInfo>::iterator r = _services.begin(); r != _services.end(); ++r) { const ServiceInfo& info = *r; @@ -470,7 +469,7 @@ IceBox::ServiceManagerI::start() _communicator->addAdminFacet(new PropertiesAdminI(communicator->getProperties()), "IceBox.Service." + info.name + ".Properties"); } - + _communicator->getAdmin(); } catch(const ObjectAdapterDeactivatedException&) @@ -611,7 +610,7 @@ IceBox::ServiceManagerI::start(const string& service, const string& entryPoint, communicator = _sharedCommunicator; } else - { + { // // Create the service properties. We use the communicator properties as the default // properties if IceBox.InheritProperties is set. @@ -627,25 +626,25 @@ IceBox::ServiceManagerI::start(const string& service, const string& entryPoint, initData.properties = createProperties(info.args, initData.properties); // - // Next, parse the service "<service>.*" command line options (the Ice command + // Next, parse the service "<service>.*" command line options (the Ice command // line options were parsed by the createProperties above) // info.args = initData.properties->parseCommandLineOptions(service, info.args); } - + // // Clone the logger to assign a new prefix. // initData.logger = _logger->cloneWithPrefix(initData.properties->getProperty("Ice.ProgramName")); - + // - // Remaining command line options are passed to the communicator. This is + // Remaining command line options are passed to the communicator. This is // necessary for Ice plug-in properties (e.g.: IceSSL). // info.communicator = initialize(info.args, initData); communicator = info.communicator; } - + // // Start the service. // @@ -656,8 +655,8 @@ IceBox::ServiceManagerI::start(const string& service, const string& entryPoint, // // There is no need to notify the observers since the 'start all' - // (that indirectly calls this function) occurs before the creation of - // the Server Admin object, and before the activation of the main + // (that indirectly calls this function) occurs before the creation of + // the Server Admin object, and before the activation of the main // object adapter (so before any observer can be registered) // } @@ -750,7 +749,7 @@ IceBox::ServiceManagerI::stopAll() vector<string> stoppedServices; // - // First, for each service, we call stop on the service and flush its database environment to + // First, for each service, we call stop on the service and flush its database environment to // the disk. // for(p = _services.rbegin(); p != _services.rend(); ++p) @@ -782,7 +781,7 @@ IceBox::ServiceManagerI::stopAll() for(p = _services.rbegin(); p != _services.rend(); ++p) { ServiceInfo& info = *p; - + try { _communicator->removeAdminFacet("IceBox.Service." + info.name + ".Properties"); @@ -815,9 +814,9 @@ IceBox::ServiceManagerI::stopAll() } // - // Release the service, the service communicator and then the library. The order is important, + // Release the service, the service communicator and then the library. The order is important, // the service must be released before destroying the communicator so that the communicator - // leak detector doesn't report potential leaks, and the communicator must be destroyed before + // leak detector doesn't report potential leaks, and the communicator must be destroyed before // the library is released since the library will destroy its global state. // try @@ -850,7 +849,7 @@ IceBox::ServiceManagerI::stopAll() out << ex; } } - + try { info.library = 0; @@ -915,7 +914,7 @@ IceBox::ServiceManagerI::servicesStopped(const vector<string>& services, const s void IceBox::ServiceManagerI::observerRemoved(const ServiceObserverPrx& observer, const std::exception& ex) -{ +{ if(_traceServiceObserver >= 1) { // @@ -929,8 +928,8 @@ IceBox::ServiceManagerI::observerRemoved(const ServiceObserverPrx& observer, con out << "Removed service observer " << _communicator->proxyToString(observer) << "\nafter catching " << ex.what(); } - } -} + } +} Ice::PropertiesPtr IceBox::ServiceManagerI::createServiceProperties(const string& service) @@ -946,7 +945,7 @@ IceBox::ServiceManagerI::createServiceProperties(const string& service) { properties = createProperties(); } - + string programName = communicatorProperties->getProperty("Ice.ProgramName"); if(programName.empty()) { diff --git a/cpp/test/Ice/Makefile b/cpp/test/Ice/Makefile index 15092758312..ea2d27fe5fa 100644 --- a/cpp/test/Ice/Makefile +++ b/cpp/test/Ice/Makefile @@ -42,7 +42,8 @@ SUBDIRS = proxy \ defaultValue \ threadPoolPriority \ invoke \ - properties + properties \ + plugin $(EVERYTHING):: @for subdir in $(SUBDIRS); \ diff --git a/cpp/test/Ice/Makefile.mak b/cpp/test/Ice/Makefile.mak index eaa8112b30a..dfd91c1bda1 100644 --- a/cpp/test/Ice/Makefile.mak +++ b/cpp/test/Ice/Makefile.mak @@ -29,6 +29,7 @@ SUBDIRS = proxy \ retry \
timeout \
udp \
+ plugin \
stream
!if "$(WINRT)" != "yes"
diff --git a/cpp/test/Ice/plugin/.depend b/cpp/test/Ice/plugin/.depend new file mode 100644 index 00000000000..1d479e875ec --- /dev/null +++ b/cpp/test/Ice/plugin/.depend @@ -0,0 +1 @@ +Plugin$(OBJEXT): Plugin.cpp $(includedir)/Ice/Ice.h $(includedir)/Ice/Initialize.h $(includedir)/Ice/CommunicatorF.h $(includedir)/Ice/LocalObjectF.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/Ice/Handle.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h $(includedir)/Ice/Config.h $(includedir)/Ice/ProxyF.h $(includedir)/Ice/ProxyHandle.h $(includedir)/Ice/ObjectF.h $(includedir)/Ice/Exception.h $(includedir)/Ice/LocalObject.h $(includedir)/IceUtil/ScopedArray.h $(includedir)/Ice/UndefSysMacros.h $(includedir)/Ice/PropertiesF.h $(includedir)/Ice/Proxy.h $(includedir)/IceUtil/Mutex.h $(includedir)/IceUtil/Lock.h $(includedir)/IceUtil/ThreadException.h $(includedir)/IceUtil/Time.h $(includedir)/IceUtil/MutexProtocol.h $(includedir)/Ice/ProxyFactoryF.h $(includedir)/Ice/ConnectionIF.h $(includedir)/Ice/RequestHandlerF.h $(includedir)/Ice/EndpointIF.h $(includedir)/Ice/EndpointF.h $(includedir)/Ice/EndpointTypes.h $(includedir)/Ice/ObjectAdapterF.h $(includedir)/Ice/ReferenceF.h $(includedir)/Ice/OutgoingAsync.h $(includedir)/IceUtil/Monitor.h $(includedir)/IceUtil/Cond.h $(includedir)/IceUtil/Timer.h $(includedir)/IceUtil/Thread.h $(includedir)/Ice/OutgoingAsyncF.h $(includedir)/Ice/InstanceF.h $(includedir)/Ice/Current.h $(includedir)/Ice/ConnectionF.h $(includedir)/Ice/Identity.h $(includedir)/Ice/BasicStream.h $(includedir)/Ice/ObjectFactoryF.h $(includedir)/Ice/Buffer.h $(includedir)/Ice/Protocol.h $(includedir)/Ice/StreamF.h $(includedir)/Ice/Object.h $(includedir)/Ice/GCShared.h $(includedir)/Ice/GCCountMap.h $(includedir)/Ice/IncomingAsyncF.h $(includedir)/Ice/LoggerF.h $(includedir)/Ice/StatsF.h $(includedir)/Ice/Dispatcher.h $(includedir)/Ice/StringConverter.h $(includedir)/Ice/Plugin.h $(includedir)/Ice/BuiltinSequences.h $(includedir)/Ice/Stream.h $(includedir)/IceUtil/Unicode.h $(includedir)/Ice/LocalException.h $(includedir)/Ice/Properties.h $(includedir)/Ice/Outgoing.h $(includedir)/Ice/Incoming.h $(includedir)/Ice/ServantLocatorF.h $(includedir)/Ice/ServantManagerF.h $(includedir)/Ice/Direct.h $(includedir)/Ice/Logger.h $(includedir)/Ice/LoggerUtil.h $(includedir)/Ice/Stats.h $(includedir)/Ice/Communicator.h $(includedir)/Ice/RouterF.h $(includedir)/Ice/LocatorF.h $(includedir)/Ice/PluginF.h $(includedir)/Ice/ImplicitContextF.h $(includedir)/Ice/CommunicatorAsync.h $(includedir)/Ice/ObjectFactory.h $(includedir)/Ice/ObjectAdapter.h $(includedir)/Ice/FacetMap.h $(includedir)/Ice/Endpoint.h $(includedir)/Ice/ServantLocator.h $(includedir)/Ice/IncomingAsync.h $(includedir)/Ice/Process.h $(includedir)/Ice/Application.h $(includedir)/Ice/Connection.h $(includedir)/Ice/ConnectionAsync.h $(includedir)/Ice/Functional.h $(includedir)/IceUtil/Functional.h $(includedir)/Ice/ImplicitContext.h $(includedir)/Ice/Locator.h $(includedir)/Ice/FactoryTableInit.h $(includedir)/Ice/FactoryTable.h $(includedir)/Ice/UserExceptionFactory.h $(includedir)/Ice/ProcessF.h $(includedir)/Ice/Router.h $(includedir)/Ice/DispatchInterceptor.h $(includedir)/Ice/IconvStringConverter.h ../../include/TestCommon.h diff --git a/cpp/test/Ice/plugin/.depend.mak b/cpp/test/Ice/plugin/.depend.mak new file mode 100644 index 00000000000..e02b2718caf --- /dev/null +++ b/cpp/test/Ice/plugin/.depend.mak @@ -0,0 +1 @@ +Plugin$(OBJEXT): Plugin.cpp "$(includedir)/Ice/Ice.h" "$(includedir)/Ice/Initialize.h" "$(includedir)/Ice/CommunicatorF.h" "$(includedir)/Ice/LocalObjectF.h" "$(includedir)/IceUtil/Shared.h" "$(includedir)/IceUtil/Config.h" "$(includedir)/Ice/Handle.h" "$(includedir)/IceUtil/Handle.h" "$(includedir)/IceUtil/Exception.h" "$(includedir)/Ice/Config.h" "$(includedir)/Ice/ProxyF.h" "$(includedir)/Ice/ProxyHandle.h" "$(includedir)/Ice/ObjectF.h" "$(includedir)/Ice/Exception.h" "$(includedir)/Ice/LocalObject.h" "$(includedir)/IceUtil/ScopedArray.h" "$(includedir)/Ice/UndefSysMacros.h" "$(includedir)/Ice/PropertiesF.h" "$(includedir)/Ice/Proxy.h" "$(includedir)/IceUtil/Mutex.h" "$(includedir)/IceUtil/Lock.h" "$(includedir)/IceUtil/ThreadException.h" "$(includedir)/IceUtil/Time.h" "$(includedir)/IceUtil/MutexProtocol.h" "$(includedir)/Ice/ProxyFactoryF.h" "$(includedir)/Ice/ConnectionIF.h" "$(includedir)/Ice/RequestHandlerF.h" "$(includedir)/Ice/EndpointIF.h" "$(includedir)/Ice/EndpointF.h" "$(includedir)/Ice/EndpointTypes.h" "$(includedir)/Ice/ObjectAdapterF.h" "$(includedir)/Ice/ReferenceF.h" "$(includedir)/Ice/OutgoingAsync.h" "$(includedir)/IceUtil/Monitor.h" "$(includedir)/IceUtil/Cond.h" "$(includedir)/IceUtil/Timer.h" "$(includedir)/IceUtil/Thread.h" "$(includedir)/Ice/OutgoingAsyncF.h" "$(includedir)/Ice/InstanceF.h" "$(includedir)/Ice/Current.h" "$(includedir)/Ice/ConnectionF.h" "$(includedir)/Ice/Identity.h" "$(includedir)/Ice/BasicStream.h" "$(includedir)/Ice/ObjectFactoryF.h" "$(includedir)/Ice/Buffer.h" "$(includedir)/Ice/Protocol.h" "$(includedir)/Ice/StreamF.h" "$(includedir)/Ice/Object.h" "$(includedir)/Ice/GCShared.h" "$(includedir)/Ice/GCCountMap.h" "$(includedir)/Ice/IncomingAsyncF.h" "$(includedir)/Ice/LoggerF.h" "$(includedir)/Ice/StatsF.h" "$(includedir)/Ice/Dispatcher.h" "$(includedir)/Ice/StringConverter.h" "$(includedir)/Ice/Plugin.h" "$(includedir)/Ice/BuiltinSequences.h" "$(includedir)/Ice/Stream.h" "$(includedir)/IceUtil/Unicode.h" "$(includedir)/Ice/LocalException.h" "$(includedir)/Ice/Properties.h" "$(includedir)/Ice/Outgoing.h" "$(includedir)/Ice/Incoming.h" "$(includedir)/Ice/ServantLocatorF.h" "$(includedir)/Ice/ServantManagerF.h" "$(includedir)/Ice/Direct.h" "$(includedir)/Ice/Logger.h" "$(includedir)/Ice/LoggerUtil.h" "$(includedir)/Ice/Stats.h" "$(includedir)/Ice/Communicator.h" "$(includedir)/Ice/RouterF.h" "$(includedir)/Ice/LocatorF.h" "$(includedir)/Ice/PluginF.h" "$(includedir)/Ice/ImplicitContextF.h" "$(includedir)/Ice/CommunicatorAsync.h" "$(includedir)/Ice/ObjectFactory.h" "$(includedir)/Ice/ObjectAdapter.h" "$(includedir)/Ice/FacetMap.h" "$(includedir)/Ice/Endpoint.h" "$(includedir)/Ice/ServantLocator.h" "$(includedir)/Ice/IncomingAsync.h" "$(includedir)/Ice/Process.h" "$(includedir)/Ice/Application.h" "$(includedir)/Ice/Connection.h" "$(includedir)/Ice/ConnectionAsync.h" "$(includedir)/Ice/Functional.h" "$(includedir)/IceUtil/Functional.h" "$(includedir)/Ice/ImplicitContext.h" "$(includedir)/Ice/Locator.h" "$(includedir)/Ice/FactoryTableInit.h" "$(includedir)/Ice/FactoryTable.h" "$(includedir)/Ice/UserExceptionFactory.h" "$(includedir)/Ice/ProcessF.h" "$(includedir)/Ice/Router.h" "$(includedir)/Ice/DispatchInterceptor.h" "$(includedir)/Ice/IconvStringConverter.h" ../../include/TestCommon.h diff --git a/cpp/test/Ice/plugin/.gitignore b/cpp/test/Ice/plugin/.gitignore new file mode 100644 index 00000000000..a86ad423f93 --- /dev/null +++ b/cpp/test/Ice/plugin/.gitignore @@ -0,0 +1,7 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +client +plugins/libTestPlugin.so.3.4.2 +plugins/libTestPlugin.so.34 +plugins/libTestPlugin.so diff --git a/cpp/test/Ice/plugin/Client.cpp b/cpp/test/Ice/plugin/Client.cpp new file mode 100644 index 00000000000..a54ec9e65c2 --- /dev/null +++ b/cpp/test/Ice/plugin/Client.cpp @@ -0,0 +1,187 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <Ice/Ice.h> +#include <TestCommon.h> + +using namespace std; + +DEFINE_TEST("client") + +namespace +{ + +class MyPlugin : public Ice::Plugin +{ + +public: + + MyPlugin() : + _initialized(false), + _destroyed(false) + { + } + + bool + isInitialized() const + { + return _initialized; + } + + bool + isDestroyed() const + { + return _destroyed; + } + + void + initialize() + { + _initialized = true; + } + + void + destroy() + { + _destroyed = true; + } + + ~MyPlugin() + { + test(_initialized); + test(_destroyed); + } + +private: + + const Ice::CommunicatorPtr _communicator; + bool _initialized; + bool _destroyed; +}; +typedef IceUtil::Handle<MyPlugin> MyPluginPtr; + +} + +int +main(int argc, char* argv[]) +{ + int status = EXIT_SUCCESS; + Ice::CommunicatorPtr communicator; + + cout << "testing a simple plug-in... " << flush; + try + { + Ice::InitializationData initData; + initData.properties = Ice::createProperties(argc, argv); + initData.properties->setProperty("Ice.Plugin.Test", + "plugins/TestPlugin:createPlugin 'C:\\Program Files\\' --DatabasePath " + "'C:\\Program Files\\Application\\db'" ); + communicator = Ice::initialize(argc, argv, initData); + communicator->destroy(); + } + catch(const Ice::Exception& ex) + { + cerr << ex << endl; + test(false); + } + cout << "ok" << endl; + + cout << "testing a simple plug-in that fails to initialize... " << flush; + communicator = 0; + try + { + Ice::InitializationData initData; + initData.properties = Ice::createProperties(argc, argv); + initData.properties->setProperty("Ice.Plugin.Test", "plugins/TestPlugin:createPluginInitializeFail"); + communicator = Ice::initialize(argc, argv, initData); + test(false); + } + catch(const std::exception& ex) + { + test(string(ex.what()) == "PluginInitializeFailExeption"); + } + test(!communicator); + cout << "ok" << endl; + + cout << "testing plug-in load order... " << flush; + try + { + Ice::InitializationData initData; + initData.properties = Ice::createProperties(argc, argv); + initData.properties->setProperty("Ice.Plugin.PluginOne", "plugins/TestPlugin:createPluginOne"); + initData.properties->setProperty("Ice.Plugin.PluginTwo", "plugins/TestPlugin:createPluginTwo"); + initData.properties->setProperty("Ice.Plugin.PluginThree", "plugins/TestPlugin:createPluginThree"); + initData.properties->setProperty("Ice.PluginLoadOrder", "PluginOne, PluginTwo"); // Exclude PluginThree + communicator = Ice::initialize(argc, argv, initData); + communicator->destroy(); + } + catch(const Ice::Exception& ex) + { + cerr << ex << endl; + test(false); + } + cout << "ok" << endl; + + cout << "testing plug-in manager... " << flush; + try + { + Ice::InitializationData initData; + initData.properties = Ice::createProperties(argc, argv); + initData.properties->setProperty("Ice.Plugin.PluginOne", "plugins/TestPlugin:createPluginOne"); + initData.properties->setProperty("Ice.Plugin.PluginTwo", "plugins/TestPlugin:createPluginTwo"); + initData.properties->setProperty("Ice.Plugin.PluginThree", "plugins/TestPlugin:createPluginThree"); + initData.properties->setProperty("Ice.PluginLoadOrder", "PluginOne, PluginTwo"); + initData.properties->setProperty("Ice.InitPlugins", "0"); + communicator = Ice::initialize(argc, argv, initData); + + Ice::PluginManagerPtr pm = communicator->getPluginManager(); + test(pm->getPlugin("PluginOne")); + test(pm->getPlugin("PluginTwo")); + test(pm->getPlugin("PluginThree")); + + MyPluginPtr p4 = new MyPlugin; + pm->addPlugin("PluginFour", p4); + test(pm->getPlugin("PluginFour")); + + pm->initializePlugins(); + + test(p4->isInitialized()); + + communicator->destroy(); + + test(p4->isDestroyed()); + } + catch(const Ice::Exception& ex) + { + cerr << ex << endl; + test(false); + } + cout << "ok" << endl; + + cout << "testing destroy when a plug-in fails to initialize... " << flush; + communicator = 0; + try + { + Ice::InitializationData initData; + initData.properties = Ice::createProperties(argc, argv); + initData.properties->setProperty("Ice.Plugin.PluginOneFail", "plugins/TestPlugin:createPluginOneFail"); + initData.properties->setProperty("Ice.Plugin.PluginTwoFail", "plugins/TestPlugin:createPluginTwoFail"); + initData.properties->setProperty("Ice.Plugin.PluginThreeFail", "plugins/TestPlugin:createPluginThreeFail"); + initData.properties->setProperty("Ice.PluginLoadOrder", "PluginOneFail, PluginTwoFail, PluginThreeFail"); + communicator = Ice::initialize(argc, argv, initData); + } + catch(const std::exception& ex) + { + test(string(ex.what()) == "PluginInitializeFailExeption"); + } + test(!communicator); + cout << "ok" << endl; + + return status; +} diff --git a/cpp/test/Ice/plugin/Makefile b/cpp/test/Ice/plugin/Makefile new file mode 100644 index 00000000000..446a4b7c8ac --- /dev/null +++ b/cpp/test/Ice/plugin/Makefile @@ -0,0 +1,51 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +top_srcdir = ../../.. + +PLUGINLIBFILENAME = $(call mklibfilename,TestPlugin,$(VERSION)) +PLUGINSONAME = $(call mksoname,TestPlugin,$(SOVERSION)) +PLUGINLIBNAME = $(call mklibname,TestPlugin) +CLIENT = client +PLUGINDIR = plugins + +TARGETS = $(CLIENT) $(call mklibtargets,$(PLUGINDIR)/$(PLUGINLIBFILENAME),$(PLUGINDIR)/$(PLUGINSONAME),$(PLUGINDIR)/$(PLUGINLIBNAME)) + +COBJS = Client.o \ + +POBJS = Plugin.o + +SRCS = $(COBJS:.o=.cpp) \ + $(SOBJS:.o=.cpp) \ + $(POBJS:.o=.cpp) + +LINKWITH := -lIceUtil -lIce + +include $(top_srcdir)/config/Make.rules + +CPPFLAGS := -I. -I../../include $(CPPFLAGS) + +$(CLIENT): $(COBJS) + rm -f $@ + $(CXX) $(LDFLAGS) -o $@ $(COBJS) $(LIBS) + +$(PLUGINDIR)/$(PLUGINLIBFILENAME): $(POBJS) + rm -f $@ + $(call mkshlib,$@,$(PLUGINSONAME),$(POBJS),$(LINKWITH)) + +$(PLUGINDIR)/$(PLUGINSONAME): $(PLUGINDIR)/$(PLUGINLIBFILENAME) + rm -f $@ + ln -s $(PLUGINLIBFILENAME) $@ + +$(PLUGINDIR)/$(PLUGINLIBNAME): $(PLUGINDIR)/$(PLUGINSONAME) + rm -f $@ + ln -s $(PLUGINSONAME) $@ + + +include .depend diff --git a/cpp/test/Ice/plugin/Makefile.mak b/cpp/test/Ice/plugin/Makefile.mak new file mode 100644 index 00000000000..c1baf6957f2 --- /dev/null +++ b/cpp/test/Ice/plugin/Makefile.mak @@ -0,0 +1,68 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+!if "$(WINRT)" != "yes"
+NAME_PREFIX =
+EXT = .exe
+!else
+NAME_PREFIX = Ice_plugin_
+EXT = .dll
+!endif
+
+CLIENT = $(NAME_PREFIX)client
+LIBNAME = TestPlugin$(LIBSUFFIX).lib
+DLLNAME = TestPlugin$(SOVERSION)$(LIBSUFFIX).dll
+PLUGINDIR = plugins
+
+TARGETS = $(CLIENT)$(EXT) $(PLUGINDIR)\$(LIBNAME) $(PLUGINDIR)\$(DLLNAME)
+
+COBJS = Client.obj
+
+POBJS = Plugin.obj
+
+SRCS = $(COBJS:.obj=.cpp) \
+ $(POBJS:.obj=.cpp)
+
+!include $(top_srcdir)/config/Make.rules.mak
+
+CPPFLAGS = -I. -I../../include $(CPPFLAGS) -DWIN32_LEAN_AND_MEAN
+
+!if "$(GENERATE_PDB)" == "yes"
+CPDBFLAGS = /pdb:$(CLIENT).pdb
+PPDBFLAGS = /pdb:$(DLLNAME:.dll=.pdb)
+!endif
+
+!if "$(WINRT)" != "yes"
+LD_TESTFLAGS = $(LD_EXEFLAGS) $(SETARGV)
+!else
+LD_TESTFLAGS = $(LD_DLLFLAGS) /export:dllMain
+!endif
+
+LINKWITH = $(LIBS)
+
+$(PLUGINDIR)\$(LIBNAME): $(PLUGINDIR)\$(DLLNAME)
+
+$(PLUGINDIR)\$(DLLNAME): $(POBJS)
+ $(LINK) $(BASE):0x22000000 $(LD_DLLFLAGS) $(PDBFLAGS) $(POBJS) $(PREOUT)$@ $(PRELIBS)$(LINKWITH)
+ move $(PLUGINDIR)\$(DLLNAME:.dll=.lib) $(PLUGINDIR)\$(LIBNAME)
+ @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \
+ $(MT) -nologo -manifest $@.manifest -outputresource:$@;#2 && del /q $@.manifest
+ @if exist $(PLUGINDIR)\$(DLLNAME:.dll=.exp) del /q $(PLUGINDIR)\$(DLLNAME:.dll=.exp)
+
+$(CLIENT)$(EXT): $(COBJS)
+ $(LINK) $(LD_TESTFLAGS) $(CPDBFLAGS) $(SETARGV) $(COBJS) $(PREOUT)$@ $(PRELIBS)$(LIBS)
+ @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \
+ $(MT) -nologo -manifest $@.manifest -outputresource:$@;#1 && del /q $@.manifest
+
+clean::
+ del /q $(PLUGINDIR)\*.ilk $(PLUGINDIR)\*.pdb
+
+!include .depend.mak
diff --git a/cpp/test/Ice/plugin/Plugin.cpp b/cpp/test/Ice/plugin/Plugin.cpp new file mode 100644 index 00000000000..0fc9cbad24d --- /dev/null +++ b/cpp/test/Ice/plugin/Plugin.cpp @@ -0,0 +1,404 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <Ice/Ice.h> +#include <TestCommon.h> + +using namespace std; + +namespace +{ + +class Plugin : public Ice::Plugin +{ + +public: + + Plugin(const Ice::CommunicatorPtr& communicator, const Ice::StringSeq& args) : + _communicator(communicator), + _args(args), + _initialized(false), + _destroyed(false) + { + } + + void + initialize() + { + _initialized = true; + test(_args.size() == 3); + test(_args[0] == "C:\\Program Files\\"); + test(_args[1] == "--DatabasePath"); + test(_args[2] == "C:\\Program Files\\Application\\db"); + } + + void + destroy() + { + _destroyed = true; + } + + ~Plugin() + { + test(_initialized); + test(_destroyed); + } + +private: + + const Ice::CommunicatorPtr _communicator; + Ice::StringSeq _args; + bool _initialized; + bool _destroyed; +}; + +class PluginInitializeFailExeption : public std::exception +{ + +public: + + PluginInitializeFailExeption() throw() {} + virtual ~PluginInitializeFailExeption() throw() {} + virtual const char* what() const throw() { return "PluginInitializeFailExeption"; } +}; + +class PluginInitializeFail : public Ice::Plugin +{ + +public: + + PluginInitializeFail(const Ice::CommunicatorPtr& communicator) : + _communicator(communicator) + { + } + + void + initialize() + { + throw PluginInitializeFailExeption(); + } + + void + destroy() + { + test(false); + } + +private: + + const Ice::CommunicatorPtr _communicator; +}; + +class BasePlugin; +typedef IceUtil::Handle<BasePlugin> BasePluginPtr; + +class BasePlugin : public Ice::Plugin +{ + +public: + + BasePlugin(const Ice::CommunicatorPtr& communicator) : + _communicator(communicator), + _initialized(false), + _destroyed(false) + { + } + + bool + isInitialized() const + { + return _initialized; + } + + bool + isDestroyed() const + { + return _destroyed; + } + +protected: + + const Ice::CommunicatorPtr _communicator; + bool _initialized; + bool _destroyed; + BasePluginPtr _other; +}; + + +class PluginOne : public BasePlugin +{ + +public: + + PluginOne(const Ice::CommunicatorPtr& communicator) : + BasePlugin(communicator) + { + } + + void + initialize() + { + _other = BasePluginPtr::dynamicCast(_communicator->getPluginManager()->getPlugin("PluginTwo")); + test(!_other->isInitialized()); + _initialized = true; + } + + void + destroy() + { + _destroyed = true; + test(_other->isDestroyed()); + } +}; + +class PluginTwo : public BasePlugin +{ + +public: + + PluginTwo(const Ice::CommunicatorPtr& communicator) : + BasePlugin(communicator) + { + } + + void + initialize() + { + _initialized = true; + _other = BasePluginPtr::dynamicCast(_communicator->getPluginManager()->getPlugin("PluginOne")); + test(_other->isInitialized()); + } + + void + destroy() + { + _destroyed = true; + test(!_other->isDestroyed()); + } +}; + +class PluginThree : public BasePlugin +{ + +public: + + PluginThree(const Ice::CommunicatorPtr& communicator) : + BasePlugin(communicator) + { + } + + void + initialize() + { + _initialized = true; + _other = BasePluginPtr::dynamicCast(_communicator->getPluginManager()->getPlugin("PluginTwo")); + test(_other->isInitialized()); + } + + void + destroy() + { + _destroyed = true; + test(!_other->isDestroyed()); + } +}; + +class BasePluginFail; +typedef IceUtil::Handle<BasePluginFail> BasePluginFailPtr; + +class BasePluginFail : public Ice::Plugin +{ + +public: + + BasePluginFail(const Ice::CommunicatorPtr& communicator) : + _communicator(communicator), + _initialized(false), + _destroyed(false) + { + } + + bool + isInitialized() const + { + return _initialized; + } + + bool + isDestroyed() const + { + return _destroyed; + } + +protected: + + const Ice::CommunicatorPtr _communicator; + bool _initialized; + bool _destroyed; + BasePluginFailPtr _one; + BasePluginFailPtr _two; + BasePluginFailPtr _three; +}; + + +class PluginOneFail : public BasePluginFail +{ + +public: + + PluginOneFail(const Ice::CommunicatorPtr& communicator) : + BasePluginFail(communicator) + { + } + + void + initialize() + { + _two = BasePluginFailPtr::dynamicCast(_communicator->getPluginManager()->getPlugin("PluginTwoFail")); + test(!_two->isInitialized()); + _three = BasePluginFailPtr::dynamicCast(_communicator->getPluginManager()->getPlugin("PluginThreeFail")); + test(!_three->isInitialized()); + _initialized = true; + } + + void + destroy() + { + test(_two->isDestroyed()); + // + // Not destroyed because initialize fails. + // + test(!_three->isDestroyed()); + _destroyed = true; + } + + ~PluginOneFail() + { + test(_initialized); + test(_destroyed); + } +}; + +class PluginTwoFail : public BasePluginFail +{ + +public: + + PluginTwoFail(const Ice::CommunicatorPtr& communicator) : + BasePluginFail(communicator) + { + } + + void + initialize() + { + _initialized = true; + _one = BasePluginFailPtr::dynamicCast(_communicator->getPluginManager()->getPlugin("PluginOneFail")); + test(_one->isInitialized()); + _three = BasePluginFailPtr::dynamicCast(_communicator->getPluginManager()->getPlugin("PluginThreeFail")); + test(!_three->isInitialized()); + } + + void + destroy() + { + _destroyed = true; + test(!_one->isDestroyed()); + } + + ~PluginTwoFail() + { + test(_initialized); + test(_destroyed); + } +}; + +class PluginThreeFail : public BasePluginFail +{ + +public: + + PluginThreeFail(const Ice::CommunicatorPtr& communicator) : + BasePluginFail(communicator) + { + } + + void + initialize() + { + throw PluginInitializeFailExeption(); + } + + void + destroy() + { + test(false); + } + + ~PluginThreeFail() + { + test(!_initialized); + test(!_destroyed); + } +}; + +} + +extern "C" +{ + +ICE_DECLSPEC_EXPORT ::Ice::Plugin* +createPlugin(const Ice::CommunicatorPtr& communicator, const string&, const Ice::StringSeq& args) +{ + return new Plugin(communicator, args); +} + +ICE_DECLSPEC_EXPORT ::Ice::Plugin* +createPluginInitializeFail(const Ice::CommunicatorPtr& communicator, const string&, const Ice::StringSeq&) +{ + return new PluginInitializeFail(communicator); +} + +ICE_DECLSPEC_EXPORT ::Ice::Plugin* +createPluginOne(const Ice::CommunicatorPtr& communicator, const string&, const Ice::StringSeq&) +{ + return new PluginOne(communicator); +} + +ICE_DECLSPEC_EXPORT ::Ice::Plugin* +createPluginTwo(const Ice::CommunicatorPtr& communicator, const string&, const Ice::StringSeq&) +{ + return new PluginTwo(communicator); +} + +ICE_DECLSPEC_EXPORT ::Ice::Plugin* +createPluginThree(const Ice::CommunicatorPtr& communicator, const string&, const Ice::StringSeq&) +{ + return new PluginThree(communicator); +} + +ICE_DECLSPEC_EXPORT ::Ice::Plugin* +createPluginOneFail(const Ice::CommunicatorPtr& communicator, const string&, const Ice::StringSeq&) +{ + return new PluginOneFail(communicator); +} + +ICE_DECLSPEC_EXPORT ::Ice::Plugin* +createPluginTwoFail(const Ice::CommunicatorPtr& communicator, const string&, const Ice::StringSeq&) +{ + return new PluginTwoFail(communicator); +} + +ICE_DECLSPEC_EXPORT ::Ice::Plugin* +createPluginThreeFail(const Ice::CommunicatorPtr& communicator, const string&, const Ice::StringSeq&) +{ + return new PluginThreeFail(communicator); +} + +} diff --git a/cpp/test/Ice/plugin/plugins/.gitignore b/cpp/test/Ice/plugin/plugins/.gitignore new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/cpp/test/Ice/plugin/plugins/.gitignore diff --git a/cpp/test/Ice/plugin/run.py b/cpp/test/Ice/plugin/run.py new file mode 100755 index 00000000000..3c4472ca289 --- /dev/null +++ b/cpp/test/Ice/plugin/run.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise "can't find toplevel directory!" +sys.path.append(os.path.join(path[0])) +from scripts import * + +client = os.path.join(os.getcwd(), "client") +TestUtil.simpleTest(client) + diff --git a/cpp/test/WinRT/TestSuite/MainPage.xaml.cpp b/cpp/test/WinRT/TestSuite/MainPage.xaml.cpp index 1b36c721576..becadead55f 100644 --- a/cpp/test/WinRT/TestSuite/MainPage.xaml.cpp +++ b/cpp/test/WinRT/TestSuite/MainPage.xaml.cpp @@ -301,7 +301,8 @@ static const TestCase allTest[] = {"Ice\\stream", "Ice_stream_", "client.dll", 0, 0, 0}, {"Ice\\timeout", "Ice_timeout_", "client.dll", "server.dll", 0, 0 }, {"Ice\\udp", "Ice_udp_", "client.dll", "server.dll", 0, 0 }, - {"Ice\\hash", "Ice_hash_", "client.dll", 0, 0, 0} + {"Ice\\hash", "Ice_hash_", "client.dll", 0, 0, 0}, + {"Ice\\plugin", "Ice_plugin_", "client.dll", 0, 0, 0} }; class TestRunner : public IceUtil::Thread diff --git a/cs/allTests.py b/cs/allTests.py index 1a2e6093e62..813cf75456d 100755 --- a/cs/allTests.py +++ b/cs/allTests.py @@ -60,6 +60,7 @@ tests = [ ("Ice/threadPoolPriority", ["core", "nomono", "nosilverlight"]), ("Ice/invoke", ["core"]), ("Ice/hash", ["once"]), + ("Ice/plugin", ["core"]), ("IceBox/configuration", ["core", "noipv6", "nosilverlight"]), ("Glacier2/router", ["service", "nosilverlight"]), ("Glacier2/sessionHelper", ["service", "nosilverlight"]), diff --git a/cs/src/Ice/PluginManagerI.cs b/cs/src/Ice/PluginManagerI.cs index 9e128ebf71d..81171a5639a 100644 --- a/cs/src/Ice/PluginManagerI.cs +++ b/cs/src/Ice/PluginManagerI.cs @@ -51,10 +51,10 @@ namespace Ice ArrayList initializedPlugins = new ArrayList(); try { - foreach(Plugin p in _initOrder) + foreach(PluginInfo p in _plugins) { - p.initialize(); - initializedPlugins.Add(p); + p.plugin.initialize(); + initializedPlugins.Add(p.plugin); } } catch(System.Exception) @@ -86,9 +86,9 @@ namespace Ice lock(this) { ArrayList names = new ArrayList(); - foreach(DictionaryEntry entry in _plugins) + foreach(PluginInfo p in _plugins) { - names.Add(entry.Key); + names.Add(p.name); } return (string[])names.ToArray(typeof(string)); } @@ -102,12 +102,13 @@ namespace Ice { throw new CommunicatorDestroyedException(); } - - Plugin p = (Plugin)_plugins[name]; + + Plugin p = findPlugin(name); if(p != null) { return p; } + NotRegisteredException ex = new NotRegisteredException(); ex.id = name; ex.kindOfObject = _kindOfObject; @@ -123,15 +124,19 @@ namespace Ice { throw new CommunicatorDestroyedException(); } - - if(_plugins.Contains(name)) + + if(findPlugin(name) != null) { AlreadyRegisteredException ex = new AlreadyRegisteredException(); ex.id = name; ex.kindOfObject = _kindOfObject; throw ex; } - _plugins[name] = plugin; + + PluginInfo info = new PluginInfo(); + info.name = name; + info.plugin = plugin; + _plugins.Add(info); } } @@ -143,39 +148,38 @@ namespace Ice { if(_initialized) { - foreach(DictionaryEntry entry in _plugins) + ArrayList plugins = (ArrayList)_plugins.Clone(); + plugins.Reverse(); + foreach(PluginInfo p in plugins) { try { - Plugin plugin = (Plugin)entry.Value; - plugin.destroy(); + p.plugin.destroy(); } catch(System.Exception ex) { - Ice.Util.getProcessLogger().warning("unexpected exception raised by plug-in `" + - entry.Key.ToString() + "' destruction:\n" + - ex.ToString()); + Ice.Util.getProcessLogger().warning("unexpected exception raised by plug-in `" + + p.name + "' destruction:\n" + ex.ToString()); } } } - + _communicator = null; } } } - + public PluginManagerI(Communicator communicator) { _communicator = communicator; - _plugins = new Hashtable(); - _initOrder = new ArrayList(); + _plugins = new ArrayList(); _initialized = false; } public void loadPlugins(ref string[] cmdArgs) { Debug.Assert(_communicator != null); - + // // Load and initialize the plug-ins defined in the property set // with the prefix "Ice.Plugin.". These properties should @@ -204,7 +208,7 @@ namespace Ice continue; } - if(_plugins.Contains(loadOrder[i])) + if(findPlugin(loadOrder[i]) != null) { PluginInitializationException e = new PluginInitializationException(); e.reason = "plug-in `" + loadOrder[i] + "' already loaded"; @@ -265,7 +269,7 @@ namespace Ice loadPlugin(name, val, ref cmdArgs); plugins.Remove(key); plugins.Remove("Ice.Plugin." + name); - + } else { @@ -275,7 +279,7 @@ namespace Ice dotPos = -1; } } - + if(dotPos == -1) { plugins.Remove(key); @@ -288,60 +292,43 @@ namespace Ice { val = plugins[clrKey]; plugins.Remove(clrKey); - } + } loadPlugin(name, val, ref cmdArgs); } } } - + private void loadPlugin(string name, string pluginSpec, ref string[] cmdArgs) { Debug.Assert(_communicator != null); // - // Separate the entry point from the arguments. First - // look for the :, then for the next whitespace. This - // represents the end of the entry point. + // Split the entire property value into arguments. An entry point containing spaces + // must be enclosed in quotes. // - // The remainder of the configuration line represents - // the arguments. - // - string entryPoint = pluginSpec; - string[] args = new string[0]; - int start = pluginSpec.IndexOf(':'); - if(start != -1) + string[] args = null; + try { - // - // Skip drive letter, if any. - // - if(pluginSpec.Length > 3 && - start == 1 && - System.Char.IsLetter(pluginSpec[0]) && - (pluginSpec[2] == '\\' || pluginSpec[2] == '/')) - { - start = pluginSpec.IndexOf(':', 3); - } - - // - // Find the whitespace. - // - int pos = pluginSpec.IndexOf(' ', start); - if(pos == -1) - { - pos = pluginSpec.IndexOf('\t', start); - } - if(pos == -1) - { - pos = pluginSpec.IndexOf('\n', start); - } - if(pos != -1) - { - entryPoint = pluginSpec.Substring(0, pos); - char[] delims = { ' ', '\t', '\n' }; - args = pluginSpec.Substring(pos).Trim().Split(delims); - } + args = IceUtilInternal.Options.split(pluginSpec); } - + catch(IceUtilInternal.Options.BadQuote ex) + { + PluginInitializationException e = new PluginInitializationException(); + e.reason = "invalid arguments for plug-in `" + name + "':\n" + ex.Message; + throw e; + } + + Debug.Assert(args.Length > 0); + + string entryPoint = args[0]; + + // + // Shift the arguments. + // + string[] tmp = new string[args.Length - 1]; + Array.Copy(args, 1, tmp, 0, args.Length - 1); + args = tmp; + // // Convert command-line options into properties. First // we convert the options from the plug-in @@ -351,38 +338,41 @@ namespace Ice Properties properties = _communicator.getProperties(); args = properties.parseCommandLineOptions(name, args); cmdArgs = properties.parseCommandLineOptions(name, cmdArgs); - + // - // Retrieve the assembly name and the type. + // Extract the assembly name and the class name. // - string err = "unable to load plug-in '" + entryPoint + "': "; + string err = "unable to load plug-in `" + entryPoint + "': "; int sepPos = entryPoint.IndexOf(':'); - if(sepPos != -1) + if(sepPos != -1 && IceInternal.AssemblyUtil.platform_ == IceInternal.AssemblyUtil.Platform.Windows) { + const string driveLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; if(entryPoint.Length > 3 && sepPos == 1 && - System.Char.IsLetter(entryPoint[0]) && + driveLetters.IndexOf(entryPoint[0]) != -1 && (entryPoint[2] == '\\' || entryPoint[2] == '/')) { sepPos = entryPoint.IndexOf(':', 3); } } - if (sepPos == -1) + if(sepPos == -1) { PluginInitializationException e = new PluginInitializationException(); e.reason = err + "invalid entry point format"; throw e; } - + System.Reflection.Assembly pluginAssembly = null; string assemblyName = entryPoint.Substring(0, sepPos); + string className = entryPoint.Substring(sepPos + 1); + try { // - // First try to load the assemby using Assembly.Load which will succeed - // if full name is configured or partial name has been qualified in config. - // If that fails, try Assembly.LoadFrom() which will succeed if a file name - // is configured or partial name is configured and DEVPATH is used. + // First try to load the assembly using Assembly.Load, which will succeed + // if a fully-qualified name is provided or if a partial name has been qualified + // in configuration. If that fails, try Assembly.LoadFrom(), which will succeed + // if a file name is configured or a partial name is configured and DEVPATH is used. // try { @@ -434,7 +424,7 @@ namespace Ice #endif PluginInitializationException e = new PluginInitializationException(); - e.reason = err + "unable to load assembly: '" + assemblyName + "': " + ex.ToString(); + e.reason = err + "unable to load assembly: `" + assemblyName + "': " + ex.ToString(); throw e; } @@ -442,7 +432,6 @@ namespace Ice // Instantiate the class. // PluginFactory pluginFactory = null; - string className = entryPoint.Substring(sepPos + 1); System.Type c = null; try { @@ -451,7 +440,7 @@ namespace Ice catch(System.Exception ex) { PluginInitializationException e = new PluginInitializationException(ex); - e.reason = err + "GetType failed for '" + className + "'"; + e.reason = err + "GetType failed for `" + className + "'"; throw e; } @@ -461,7 +450,7 @@ namespace Ice if(pluginFactory == null) { PluginInitializationException e = new PluginInitializationException(); - e.reason = err + "Can't find constructor for '" + className + "'"; + e.reason = err + "can't find constructor for `" + className + "'"; throw e; } } @@ -483,7 +472,7 @@ namespace Ice e.reason = err + "System.Exception: " + ex.ToString(); throw e; } - + Plugin plugin = null; try { @@ -500,7 +489,7 @@ namespace Ice e.reason = err + "System.Exception in factory.create: " + ex.ToString(); throw e; } - + if(plugin == null) { PluginInitializationException ex = new PluginInitializationException(); @@ -508,13 +497,32 @@ namespace Ice throw ex; } - _plugins[name] = plugin; - _initOrder.Add(plugin); + PluginInfo info = new PluginInfo(); + info.name = name; + info.plugin = plugin; + _plugins.Add(info); + } + + private Plugin findPlugin(string name) + { + foreach(PluginInfo p in _plugins) + { + if(name.Equals(p.name)) + { + return p.plugin; + } + } + return null; + } + + internal class PluginInfo + { + internal string name; + internal Plugin plugin; } private Communicator _communicator; - private Hashtable _plugins; - private ArrayList _initOrder; + private ArrayList _plugins; private bool _initialized; private static bool _sslWarnOnce = false; } diff --git a/cs/src/IceBox/ServiceManagerI.cs b/cs/src/IceBox/ServiceManagerI.cs index 30e218abae4..86a5310e138 100644 --- a/cs/src/IceBox/ServiceManagerI.cs +++ b/cs/src/IceBox/ServiceManagerI.cs @@ -30,14 +30,12 @@ class ServiceManagerI : ServiceManagerDisp_ _traceServiceObserver = _communicator.getProperties().getPropertyAsInt("IceBox.Trace.ServiceObserver"); } - public override Dictionary<string, string> - getSliceChecksums(Ice.Current current) + public override Dictionary<string, string> getSliceChecksums(Ice.Current current) { return Ice.SliceChecksums.checksums; } - public override void - startService(string name, Ice.Current current) + public override void startService(string name, Ice.Current current) { ServiceInfo info = new ServiceInfo(); _m.Lock(); @@ -119,8 +117,7 @@ class ServiceManagerI : ServiceManagerDisp_ } } - public override void - stopService(string name, Ice.Current current) + public override void stopService(string name, Ice.Current current) { ServiceInfo info = new ServiceInfo(); _m.Lock(); @@ -201,8 +198,7 @@ class ServiceManagerI : ServiceManagerDisp_ } } - public override void - addObserver(ServiceObserverPrx observer, Ice.Current current) + public override void addObserver(ServiceObserverPrx observer, Ice.Current current) { List<string> activeServices = new List<string>(); @@ -250,14 +246,12 @@ class ServiceManagerI : ServiceManagerDisp_ } } - public override void - shutdown(Ice.Current current) + public override void shutdown(Ice.Current current) { _communicator.shutdown(); } - public int - run() + public int run() { try { @@ -466,8 +460,7 @@ class ServiceManagerI : ServiceManagerDisp_ return 0; } - private void - startService(string service, string entryPoint, string[] args) + private void startService(string service, string entryPoint, string[] args) { _m.Lock(); try @@ -478,15 +471,16 @@ class ServiceManagerI : ServiceManagerDisp_ info.args = args; // - // Retrieve the assembly name and the type. + // Extract the assembly name and the class name. // string err = "ServiceManager: unable to load service '" + entryPoint + "': "; int sepPos = entryPoint.IndexOf(':'); - if(sepPos != -1) + if(sepPos != -1 && IceInternal.AssemblyUtil.platform_ == IceInternal.AssemblyUtil.Platform.Windows) { + const string driveLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; if(entryPoint.Length > 3 && sepPos == 1 && - System.Char.IsLetter(entryPoint[0]) && + driveLetters.IndexOf(entryPoint[0]) != -1 && (entryPoint[2] == '\\' || entryPoint[2] == '/')) { sepPos = entryPoint.IndexOf(':', 3); @@ -495,19 +489,21 @@ class ServiceManagerI : ServiceManagerDisp_ if(sepPos == -1) { FailureException e = new FailureException(); - e.reason = err + "invalid entry point format: " + entryPoint; + e.reason = err + "invalid entry point format"; throw e; } System.Reflection.Assembly serviceAssembly = null; string assemblyName = entryPoint.Substring(0, sepPos); + string className = entryPoint.Substring(sepPos + 1); + try { // - // First try to load the assemby using Assembly.Load which will succeed - // if full name is configured or partial name has been qualified in config. - // If that fails, try Assembly.LoadFrom() which will succeed if a file name - // is configured or partial name is configured and DEVPATH is used. + // First try to load the assembly using Assembly.Load, which will succeed + // if a fully-qualified name is provided or if a partial name has been qualified + // in configuration. If that fails, try Assembly.LoadFrom(), which will succeed + // if a file name is configured or a partial name is configured and DEVPATH is used. // try { @@ -535,7 +531,6 @@ class ServiceManagerI : ServiceManagerDisp_ // // Instantiate the class. // - string className = entryPoint.Substring(sepPos + 1); System.Type c = null; try { @@ -614,7 +609,7 @@ class ServiceManagerI : ServiceManagerDisp_ else { FailureException e = new FailureException(ex.InnerException); - e.reason = "ServiceManager: exception in service constructor for " + className; + e.reason = err + "exception in service constructor for " + className; throw e; } } @@ -738,8 +733,7 @@ class ServiceManagerI : ServiceManagerDisp_ } } - private void - stopAll() + private void stopAll() { _m.Lock(); try @@ -837,8 +831,7 @@ class ServiceManagerI : ServiceManagerDisp_ } } - private void - servicesStarted(List<String> services, Dictionary<ServiceObserverPrx, bool>.KeyCollection observers) + private void servicesStarted(List<String> services, Dictionary<ServiceObserverPrx, bool>.KeyCollection observers) { // // Must be called with 'this' unlocked @@ -855,8 +848,7 @@ class ServiceManagerI : ServiceManagerDisp_ } } - private void - servicesStopped(List<string> services, Dictionary<ServiceObserverPrx, bool>.KeyCollection observers) + private void servicesStopped(List<string> services, Dictionary<ServiceObserverPrx, bool>.KeyCollection observers) { // // Must be called with 'this' unlocked @@ -898,8 +890,7 @@ class ServiceManagerI : ServiceManagerDisp_ } } - private void - observerRemoved(ServiceObserverPrx observer, System.Exception ex) + private void observerRemoved(ServiceObserverPrx observer, System.Exception ex) { if(_traceServiceObserver >= 1) { @@ -942,51 +933,29 @@ class ServiceManagerI : ServiceManagerDisp_ // Separate the entry point from the arguments. // name = service; - entryPoint = value; - args = new string[0]; - int start = value.IndexOf(':'); - if(start != -1) + try { - if(value.Length > 3 && - start == 1 && - System.Char.IsLetter(value[0]) && - (value[2] == '\\' || value[2] == '/')) - { - start = value.IndexOf(':', 3); - } + args = IceUtilInternal.Options.split(value); } - - if(start != -1) + catch(IceUtilInternal.Options.BadQuote ex) { - // - // Find the whitespace. - // - int pos = value.IndexOf(' ', start); - if(pos == -1) - { - pos = value.IndexOf('\t', start); - } - if(pos == -1) - { - pos = value.IndexOf('\n', start); - } - if(pos != -1) - { - entryPoint = value.Substring(0, pos); - try - { - args = IceUtilInternal.Options.split(value.Substring(pos)); - } - catch(IceUtilInternal.Options.BadQuote ex) - { - FailureException e = new FailureException(ex); - e.reason = "ServiceManager: invalid arguments for service `" + name + "'"; - throw e; - } - } + FailureException e = new FailureException(); + e.reason = "ServiceManager: invalid arguments for service `" + name + "':\n" + ex.Message; + throw e; } + Debug.Assert(args.Length > 0); + + entryPoint = args[0]; + + // + // Shift the arguments. + // + string[] tmp = new string[args.Length - 1]; + Array.Copy(args, 1, tmp, 0, args.Length - 1); + args = tmp; + if(serverArgs.Length > 0) { ArrayList l = new ArrayList(); @@ -1017,14 +986,12 @@ class ServiceManagerI : ServiceManagerDisp_ _properties = properties; } - public override string - getProperty(string name, Ice.Current current) + public override string getProperty(string name, Ice.Current current) { return _properties.getProperty(name); } - public override Dictionary<string, string> - getPropertiesForPrefix(string name, Ice.Current current) + public override Dictionary<string, string> getPropertiesForPrefix(string name, Ice.Current current) { return _properties.getPropertiesForPrefix(name); } @@ -1032,8 +999,7 @@ class ServiceManagerI : ServiceManagerDisp_ private Ice.Properties _properties; } - private Ice.Properties - createServiceProperties(String service) + private Ice.Properties createServiceProperties(String service) { Ice.Properties properties; Ice.Properties communicatorProperties = _communicator.getProperties(); diff --git a/cs/test/Ice/Makefile b/cs/test/Ice/Makefile index 0fc71beeb86..c1ae0863dba 100644 --- a/cs/test/Ice/Makefile +++ b/cs/test/Ice/Makefile @@ -42,7 +42,8 @@ SUBDIRS = application \ udp \ defaultServant \ defaultValue \ - threadPoolPriority + threadPoolPriority \ + plugin $(EVERYTHING):: @for subdir in $(SUBDIRS); \ diff --git a/cs/test/Ice/Makefile.mak b/cs/test/Ice/Makefile.mak index 7d731d91ef2..2aa6588521f 100644 --- a/cs/test/Ice/Makefile.mak +++ b/cs/test/Ice/Makefile.mak @@ -42,7 +42,8 @@ SUBDIRS = application \ udp \
defaultServant \
defaultValue \
- threadPoolPriority
+ threadPoolPriority \
+ plugin
$(EVERYTHING)::
@for %i in ( $(SUBDIRS) ) do \
diff --git a/cs/test/Ice/plugin/.depend b/cs/test/Ice/plugin/.depend new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/cs/test/Ice/plugin/.depend diff --git a/cs/test/Ice/plugin/.depend.mak b/cs/test/Ice/plugin/.depend.mak new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/cs/test/Ice/plugin/.depend.mak diff --git a/cs/test/Ice/plugin/BasePlugin.cs b/cs/test/Ice/plugin/BasePlugin.cs new file mode 100644 index 00000000000..63e3ea9f1af --- /dev/null +++ b/cs/test/Ice/plugin/BasePlugin.cs @@ -0,0 +1,44 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +using Ice; + +public abstract class BasePlugin : Ice.Plugin +{ + public BasePlugin(Ice.Communicator communicator) + { + _communicator = communicator; + } + + public bool isInitialized() + { + return _initialized; + } + + public bool isDestroyed() + { + return _destroyed; + } + + protected static void test(bool b) + { + if(!b) + { + throw new System.Exception(); + } + } + + public abstract void initialize(); + public abstract void destroy(); + + protected Ice.Communicator _communicator; + protected bool _initialized = false; + protected bool _destroyed = false; + protected BasePlugin _other = null; +} diff --git a/cs/test/Ice/plugin/BasePluginFail.cs b/cs/test/Ice/plugin/BasePluginFail.cs new file mode 100644 index 00000000000..1188914f23d --- /dev/null +++ b/cs/test/Ice/plugin/BasePluginFail.cs @@ -0,0 +1,48 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +using Ice; + +public abstract class BasePluginFail : Ice.Plugin +{ + public BasePluginFail(Ice.Communicator communicator) + { + _communicator = communicator; + _initialized = false; + _destroyed = false; + } + + public bool isInitialized() + { + return _initialized; + } + + public bool isDestroyed() + { + return _destroyed; + } + + protected static void test(bool b) + { + if(!b) + { + throw new System.Exception(); + } + } + + public abstract void initialize(); + public abstract void destroy(); + + protected Ice.Communicator _communicator; + protected bool _initialized; + protected bool _destroyed; + protected BasePluginFail _one; + protected BasePluginFail _two; + protected BasePluginFail _three; +} diff --git a/cs/test/Ice/plugin/Client.cs b/cs/test/Ice/plugin/Client.cs new file mode 100644 index 00000000000..c4628cb600e --- /dev/null +++ b/cs/test/Ice/plugin/Client.cs @@ -0,0 +1,179 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +using System; +using System.Diagnostics; +using System.Reflection; +using Ice; + +[assembly: CLSCompliant(true)] + +[assembly: AssemblyTitle("IceTest")] +[assembly: AssemblyDescription("Ice test")] +[assembly: AssemblyCompany("ZeroC, Inc.")] + +public class Client +{ + private static void test(bool b) + { + if(!b) + { + throw new System.Exception(); + } + } + + public static int Main(string[] args) + { + Ice.Communicator communicator = null; + Console.Write("testing a simple plug-in... "); + Console.Out.Flush(); + try + { + Ice.InitializationData initData = new Ice.InitializationData(); + initData.properties = Ice.Util.createProperties(); + initData.properties.setProperty("Ice.Plugin.Test", + "plugins/Plugin.dll:PluginFactory 'C:\\Program Files\\' --DatabasePath " + + "'C:\\Program Files\\Application\\db'"); + communicator = Ice.Util.initialize(ref args, initData); + communicator.destroy(); + } + catch(Ice.LocalException ex) + { + Console.WriteLine(ex.ToString());; + test(false); + } + Console.WriteLine("ok"); + + Console.Write("testing a simple plug-in that fails to initialize... "); + Console.Out.Flush(); + communicator = null; + try + { + Ice.InitializationData initData = new Ice.InitializationData(); + initData.properties = Ice.Util.createProperties(); + initData.properties.setProperty("Ice.Plugin.Test", "plugins/Plugin.dll:PluginInitializeFailFactory"); + communicator = Ice.Util.initialize(ref args, initData); + test(false); + } + catch(System.Exception ex) + { + test(ex.Message.Equals("PluginInitializeFailException")); + } + test(communicator == null); + Console.WriteLine("ok"); + + Console.Write("testing plug-in load order... "); + Console.Out.Flush(); + try + { + Ice.InitializationData initData = new Ice.InitializationData(); + initData.properties = Ice.Util.createProperties(); + initData.properties.setProperty("Ice.Plugin.PluginOne", "plugins/Plugin.dll:PluginOneFactory"); + initData.properties.setProperty("Ice.Plugin.PluginTwo", "plugins/Plugin.dll:PluginTwoFactory"); + initData.properties.setProperty("Ice.Plugin.PluginThree", "plugins/Plugin.dll:PluginThreeFactory"); + initData.properties.setProperty("Ice.PluginLoadOrder", "PluginOne, PluginTwo"); // Exclude PluginThree + communicator = Ice.Util.initialize(ref args, initData); + communicator.destroy(); + } + catch(Ice.LocalException ex) + { + Console.WriteLine(ex.ToString());; + test(false); + } + Console.WriteLine("ok"); + + Console.Write("testing plug-in manager... "); + Console.Out.Flush(); + try + { + Ice.InitializationData initData = new Ice.InitializationData(); + initData.properties = Ice.Util.createProperties(); + initData.properties.setProperty("Ice.Plugin.PluginOne", "plugins/Plugin.dll:PluginOneFactory"); + initData.properties.setProperty("Ice.Plugin.PluginTwo", "plugins/Plugin.dll:PluginTwoFactory"); + initData.properties.setProperty("Ice.Plugin.PluginThree", "plugins/Plugin.dll:PluginThreeFactory"); + initData.properties.setProperty("Ice.Plugin.PluginThree", "plugins/Plugin.dll:PluginThreeFactory"); + initData.properties.setProperty("Ice.InitPlugins", "0"); + communicator = Ice.Util.initialize(ref args, initData); + + Ice.PluginManager pm = communicator.getPluginManager(); + test(pm.getPlugin("PluginOne") != null); + test(pm.getPlugin("PluginTwo") != null); + test(pm.getPlugin("PluginThree") != null); + + MyPlugin p4 = new MyPlugin(); + pm.addPlugin("PluginFour", p4); + test(pm.getPlugin("PluginFour") != null); + + pm.initializePlugins(); + + test(p4.isInitialized()); + + communicator.destroy(); + + test(p4.isDestroyed()); + } + catch(Ice.LocalException ex) + { + Console.WriteLine(ex.ToString());; + test(false); + } + Console.WriteLine("ok"); + + Console.Write("testing destroy when a plug-in fails to initialize... "); + Console.Out.Flush(); + communicator = null; + try + { + Ice.InitializationData initData = new Ice.InitializationData(); + initData.properties = Ice.Util.createProperties(); + initData.properties.setProperty("Ice.Plugin.PluginOneFail", + "plugins/Plugin.dll:PluginOneFailFactory"); + initData.properties.setProperty("Ice.Plugin.PluginTwoFail", + "plugins/Plugin.dll:PluginTwoFailFactory"); + initData.properties.setProperty("Ice.Plugin.PluginThreeFail", + "plugins/Plugin.dll:PluginThreeFailFactory"); + initData.properties.setProperty("Ice.PluginLoadOrder", "PluginOneFail, PluginTwoFail, PluginThreeFail"); + communicator = Ice.Util.initialize(ref args, initData); + } + catch(System.Exception ex) + { + test(ex.Message.Equals("PluginInitializeFailException")); + } + test(communicator == null); + Console.WriteLine("ok"); + + return 0; + } + + internal class MyPlugin : Ice.Plugin + { + public bool isInitialized() + { + return _initialized; + } + + public bool isDestroyed() + { + return _destroyed; + } + + public void initialize() + { + _initialized = true; + } + + public void destroy() + { + _destroyed = true; + } + + private bool _initialized = false; + private bool _destroyed = false; + } +} diff --git a/cs/test/Ice/plugin/Makefile b/cs/test/Ice/plugin/Makefile new file mode 100644 index 00000000000..3738ee553dc --- /dev/null +++ b/cs/test/Ice/plugin/Makefile @@ -0,0 +1,41 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +top_srcdir = ../../.. + +TARGETS = client.exe plugins/Plugin.dll + +C_SRCS = Client.cs + +P_SRCS = BasePlugin.cs \ + PluginFactory.cs \ + PluginInitializeFailException.cs \ + BasePluginFail.cs \ + PluginInitializeFailFactory.cs \ + PluginOneFactory.cs \ + PluginOneFailFactory.cs \ + PluginThreeFactory.cs \ + PluginThreeFailFactory.cs \ + PluginTwoFactory.cs \ + PluginTwoFailFactory.cs + +SDIR = . + +include $(top_srcdir)/config/Make.rules.cs + +client.exe: $(C_SRCS) + $(MCS) $(MCSFLAGS) -target:exe -out:$@ $(call ref,Ice) $(C_SRCS) + +plugins/Plugin.dll: $(P_SRCS) + $(MCS) $(MCSFLAGS) -target:library -out:plugins/Plugin.dll $(call ref,Ice) /keyfile:$(KEYFILE) $(P_SRCS) + +clean:: + rm -f plugins/Plugin.dll + +include .depend diff --git a/cs/test/Ice/plugin/Makefile.mak b/cs/test/Ice/plugin/Makefile.mak new file mode 100644 index 00000000000..f8615231af6 --- /dev/null +++ b/cs/test/Ice/plugin/Makefile.mak @@ -0,0 +1,38 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+TARGETS = client.exe plugins\Plugin.dll
+
+C_SRCS = Client.cs
+
+P_SRCS = BasePlugin.cs \
+ PluginFactory.cs \
+ PluginInitializeFailException.cs \
+ BasePluginFail.cs \
+ PluginInitializeFailFactory.cs \
+ PluginOneFactory.cs \
+ PluginOneFailFactory.cs \
+ PluginThreeFactory.cs \
+ PluginThreeFailFactory.cs \
+ PluginTwoFactory.cs \
+ PluginTwoFailFactory.cs
+
+SDIR = .
+
+!include $(top_srcdir)\config\Make.rules.mak.cs
+
+client.exe: $(C_SRCS)
+ $(MCS) $(MCSFLAGS) -target:exe -out:$@ -r:"$(refdir)\Ice.dll" $(C_SRCS)
+
+plugins\Plugin.dll: $(P_SRCS)
+ $(MCS) $(MCSFLAGS) -target:library -out:plugins\Plugin.dll -r:"$(refdir)\Ice.dll" /keyfile:$(KEYFILE) $(P_SRCS)
+
+!include .depend.mak
diff --git a/cs/test/Ice/plugin/PluginFactory.cs b/cs/test/Ice/plugin/PluginFactory.cs new file mode 100644 index 00000000000..3ac781eeec5 --- /dev/null +++ b/cs/test/Ice/plugin/PluginFactory.cs @@ -0,0 +1,64 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +using System; + +public class PluginFactory : Ice.PluginFactory +{ + public Ice.Plugin create(Ice.Communicator communicator, string name, string[] args) + { + return new Plugin(communicator, args); + } + + internal class Plugin : Ice.Plugin + { + public Plugin(Ice.Communicator communicator, string[] args) + { + _args = args; + } + + public void initialize() + { + _initialized = true; + test(_args.Length == 3); + test(_args[0] == "C:\\Program Files\\"); + test(_args[1] == "--DatabasePath"); + test(_args[2] == "C:\\Program Files\\Application\\db"); + } + + public void destroy() + { + _destroyed = true; + } + + ~Plugin() + { + if(!_initialized) + { + Console.WriteLine("Plugin not initialized"); + } + if(!_destroyed) + { + Console.WriteLine("Plugin not destroyed"); + } + } + + private static void test(bool b) + { + if(!b) + { + throw new System.Exception(); + } + } + + private bool _initialized = false; + private bool _destroyed = false; + private string[] _args; + } +} diff --git a/cs/test/Ice/plugin/PluginInitializeFailException.cs b/cs/test/Ice/plugin/PluginInitializeFailException.cs new file mode 100644 index 00000000000..2fec6a604a1 --- /dev/null +++ b/cs/test/Ice/plugin/PluginInitializeFailException.cs @@ -0,0 +1,15 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +public class PluginInitializeFailException : System.Exception +{ + public PluginInitializeFailException() : base("PluginInitializeFailException") + { + } +} diff --git a/cs/test/Ice/plugin/PluginInitializeFailFactory.cs b/cs/test/Ice/plugin/PluginInitializeFailFactory.cs new file mode 100644 index 00000000000..fcd47db9244 --- /dev/null +++ b/cs/test/Ice/plugin/PluginInitializeFailFactory.cs @@ -0,0 +1,37 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +public class PluginInitializeFailFactory : Ice.PluginFactory +{ + public Ice.Plugin create(Ice.Communicator communicator, string name, string[] args) + { + return new PluginInitializeFail(); + } + + internal class PluginInitializeFail : Ice.Plugin + { + public void initialize() + { + throw new PluginInitializeFailException(); + } + + public void destroy() + { + test(false); + } + + private static void test(bool b) + { + if(!b) + { + throw new System.Exception(); + } + } + } +} diff --git a/cs/test/Ice/plugin/PluginOneFactory.cs b/cs/test/Ice/plugin/PluginOneFactory.cs new file mode 100644 index 00000000000..f95e60718e3 --- /dev/null +++ b/cs/test/Ice/plugin/PluginOneFactory.cs @@ -0,0 +1,36 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +public class PluginOneFactory : Ice.PluginFactory +{ + public Ice.Plugin create(Ice.Communicator communicator, string name, string[] args) + { + return new PluginOne(communicator); + } + + internal class PluginOne : BasePlugin + { + public PluginOne(Ice.Communicator communicator) : base(communicator) + { + } + + public override void initialize() + { + _other = (BasePlugin)_communicator.getPluginManager().getPlugin("PluginTwo"); + test(!_other.isInitialized()); + _initialized = true; + } + + public override void destroy() + { + _destroyed = true; + test(_other.isDestroyed()); + } + } +} diff --git a/cs/test/Ice/plugin/PluginOneFailFactory.cs b/cs/test/Ice/plugin/PluginOneFailFactory.cs new file mode 100644 index 00000000000..ef4a2165123 --- /dev/null +++ b/cs/test/Ice/plugin/PluginOneFailFactory.cs @@ -0,0 +1,56 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +using System; + +public class PluginOneFailFactory : Ice.PluginFactory +{ + public Ice.Plugin create(Ice.Communicator communicator, string name, string[] args) + { + return new PluginOneFail(communicator); + } + + internal class PluginOneFail : BasePluginFail + { + public PluginOneFail(Ice.Communicator communicator) : base(communicator) + { + } + + public override void initialize() + { + _two = (BasePluginFail)_communicator.getPluginManager().getPlugin("PluginTwoFail"); + test(!_two.isInitialized()); + _three = (BasePluginFail)_communicator.getPluginManager().getPlugin("PluginThreeFail"); + test(!_three.isInitialized()); + _initialized = true; + } + + public override void destroy() + { + test(_two.isDestroyed()); + // + // Not destroyed because initialize fails. + // + test(!_three.isDestroyed()); + _destroyed = true; + } + + ~PluginOneFail() + { + if(!_initialized) + { + Console.WriteLine("PluginOneFail not initialized"); + } + if(!_destroyed) + { + Console.WriteLine("PluginOneFail not destroyed"); + } + } + } +} diff --git a/cs/test/Ice/plugin/PluginThreeFactory.cs b/cs/test/Ice/plugin/PluginThreeFactory.cs new file mode 100644 index 00000000000..a51b627ce0b --- /dev/null +++ b/cs/test/Ice/plugin/PluginThreeFactory.cs @@ -0,0 +1,36 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +public class PluginThreeFactory : Ice.PluginFactory +{ + public Ice.Plugin create(Ice.Communicator communicator, string name, string[] args) + { + return new PluginThree(communicator); + } + + internal class PluginThree : BasePlugin + { + public PluginThree(Ice.Communicator communicator) : base(communicator) + { + } + + public override void initialize() + { + _other = (BasePlugin)_communicator.getPluginManager().getPlugin("PluginTwo"); + test(_other.isInitialized()); + _initialized = true; + } + + public override void destroy() + { + _destroyed = true; + test(!_other.isDestroyed()); + } + } +} diff --git a/cs/test/Ice/plugin/PluginThreeFailFactory.cs b/cs/test/Ice/plugin/PluginThreeFailFactory.cs new file mode 100644 index 00000000000..6b708fefd3a --- /dev/null +++ b/cs/test/Ice/plugin/PluginThreeFailFactory.cs @@ -0,0 +1,47 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +using System; + +public class PluginThreeFailFactory : Ice.PluginFactory +{ + public Ice.Plugin create(Ice.Communicator communicator, string name, string[] args) + { + return new PluginThreeFail(communicator); + } + + internal class PluginThreeFail : BasePluginFail + { + public PluginThreeFail(Ice.Communicator communicator) : base(communicator) + { + } + + public override void initialize() + { + throw new PluginInitializeFailException(); + } + + public override void destroy() + { + test(false); + } + + ~PluginThreeFail() + { + if(_initialized) + { + Console.WriteLine("PluginThreeFail was initialized"); + } + if(_destroyed) + { + Console.WriteLine("PluginThreeFail was destroyed"); + } + } + } +} diff --git a/cs/test/Ice/plugin/PluginTwoFactory.cs b/cs/test/Ice/plugin/PluginTwoFactory.cs new file mode 100644 index 00000000000..5981490e825 --- /dev/null +++ b/cs/test/Ice/plugin/PluginTwoFactory.cs @@ -0,0 +1,36 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +public class PluginTwoFactory : Ice.PluginFactory +{ + public Ice.Plugin create(Ice.Communicator communicator, string name, string[] args) + { + return new PluginTwo(communicator); + } + + internal class PluginTwo : BasePlugin + { + public PluginTwo(Ice.Communicator communicator) : base(communicator) + { + } + + public override void initialize() + { + _other = (BasePlugin)_communicator.getPluginManager().getPlugin("PluginOne"); + test(_other.isInitialized()); + _initialized = true; + } + + public override void destroy() + { + _destroyed = true; + test(!_other.isDestroyed()); + } + } +} diff --git a/cs/test/Ice/plugin/PluginTwoFailFactory.cs b/cs/test/Ice/plugin/PluginTwoFailFactory.cs new file mode 100644 index 00000000000..1d6e97ec085 --- /dev/null +++ b/cs/test/Ice/plugin/PluginTwoFailFactory.cs @@ -0,0 +1,56 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +using System; + +public class PluginTwoFailFactory : Ice.PluginFactory +{ + public Ice.Plugin create(Ice.Communicator communicator, string name, string[] args) + { + return new PluginTwoFail(communicator); + } + + internal class PluginTwoFail : BasePluginFail + { + public PluginTwoFail(Ice.Communicator communicator) : base(communicator) + { + } + + public override void initialize() + { + _one = (BasePluginFail)_communicator.getPluginManager().getPlugin("PluginOneFail"); + test(_one.isInitialized()); + _three = (BasePluginFail)_communicator.getPluginManager().getPlugin("PluginThreeFail"); + test(!_three.isInitialized()); + _initialized = true; + } + + public override void destroy() + { + test(!_one.isDestroyed()); + // + // Not destroyed because initialize fails. + // + test(!_three.isDestroyed()); + _destroyed = true; + } + + ~PluginTwoFail() + { + if(!_initialized) + { + Console.WriteLine("PluginTwoFail not initialized"); + } + if(!_destroyed) + { + Console.WriteLine("PluginTwoFail not destroyed"); + } + } + } +} diff --git a/cs/test/Ice/plugin/client.exe.config b/cs/test/Ice/plugin/client.exe.config new file mode 100755 index 00000000000..cf795ac3756 --- /dev/null +++ b/cs/test/Ice/plugin/client.exe.config @@ -0,0 +1,6 @@ +<?xml version="1.0"?>
+<configuration>
+ <runtime>
+ <developmentMode developerInstallation="true"/>
+ </runtime>
+</configuration>
diff --git a/cs/test/Ice/plugin/plugins/.gitignore b/cs/test/Ice/plugin/plugins/.gitignore new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/cs/test/Ice/plugin/plugins/.gitignore diff --git a/cs/test/Ice/plugin/run.py b/cs/test/Ice/plugin/run.py new file mode 100755 index 00000000000..20e51607f28 --- /dev/null +++ b/cs/test/Ice/plugin/run.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, getopt + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise "can't find toplevel directory!" +sys.path.append(os.path.join(path[0])) +from scripts import * + +client = os.path.join(os.getcwd(), "client") + +print "starting client...", +clientProc = TestUtil.startClient(client, " --Ice.Warn.Dispatch=0 2>&1", startReader = False) +print "ok" +clientProc.startReader() +clientProc.waitTestSuccess() + diff --git a/java/allTests.py b/java/allTests.py index ce7ac3ac3c4..525fd7fc4f3 100755 --- a/java/allTests.py +++ b/java/allTests.py @@ -64,6 +64,7 @@ tests = [ ("Ice/classLoader", ["core"]), ("Ice/invoke", ["core"]), ("Ice/properties", ["once"]), + ("Ice/plugin", ["core"]), ("Ice/hash", ["once"]), ("Ice/optional", ["once"]), ("IceBox/configuration", ["core", "noipv6"]), diff --git a/java/build.xml b/java/build.xml index 0c59f90231e..39a2311ca90 100644 --- a/java/build.xml +++ b/java/build.xml @@ -640,10 +640,20 @@ <compilerarg value="${javac.lint}"/> </javac> </target> + + <target name="test-plugins-jar" depends="test-compile,freeze-jar"> + <jar jarfile="${lib.dir}/IceTestPlugins.jar" basedir="${lib.dir}"> + <include name="test/Ice/plugin/plugins/**"/> + <manifest> + <attribute name="Built-By" value="ZeroC, Inc."/> + </manifest> + </jar> + </target> <target name="test-jar" depends="test-compile, ice-jar, freeze-jar, glacier2-jar, icebox-jar, icestorm-jar, icegrid-jar"> <jar jarfile="${lib.dir}/IceTest.jar" basedir="${lib.dir}"> <include name="test/**"/> + <exclude name="test/Ice/plugin/plugins/**"/> <manifest> <attribute name="Built-By" value="ZeroC, Inc."/> <attribute name="Class-Path" value="Ice.jar"/> diff --git a/java/src/Ice/PluginManagerI.java b/java/src/Ice/PluginManagerI.java index e3c569f5f75..8445fb8e55f 100644 --- a/java/src/Ice/PluginManagerI.java +++ b/java/src/Ice/PluginManagerI.java @@ -29,10 +29,10 @@ public final class PluginManagerI implements PluginManager java.util.List<Plugin> initializedPlugins = new java.util.ArrayList<Plugin>(); try { - for(Plugin p : _initOrder) + for(PluginInfo p : _plugins) { - p.initialize(); - initializedPlugins.add(p); + p.plugin.initialize(); + initializedPlugins.add(p.plugin); } } catch(RuntimeException ex) @@ -64,9 +64,9 @@ public final class PluginManagerI implements PluginManager getPlugins() { java.util.ArrayList<String> names = new java.util.ArrayList<String>(); - for(java.util.Map.Entry<String, Plugin> p : _plugins.entrySet()) + for(PluginInfo p : _plugins) { - names.add(p.getKey()); + names.add(p.name); } return names.toArray(new String[0]); } @@ -79,11 +79,12 @@ public final class PluginManagerI implements PluginManager throw new CommunicatorDestroyedException(); } - Plugin p = _plugins.get(name); + Plugin p = findPlugin(name); if(p != null) { return p; } + NotRegisteredException ex = new NotRegisteredException(); ex.id = name; ex.kindOfObject = _kindOfObject; @@ -98,14 +99,18 @@ public final class PluginManagerI implements PluginManager throw new CommunicatorDestroyedException(); } - if(_plugins.containsKey(name)) + if(findPlugin(name) != null) { AlreadyRegisteredException ex = new AlreadyRegisteredException(); ex.id = name; ex.kindOfObject = _kindOfObject; throw ex; } - _plugins.put(name, plugin); + + PluginInfo info = new PluginInfo(); + info.name = name; + info.plugin = plugin; + _plugins.add(info); } public synchronized void @@ -115,28 +120,38 @@ public final class PluginManagerI implements PluginManager { if(_initialized) { - for(java.util.Map.Entry<String, Plugin> p : _plugins.entrySet()) + java.util.ListIterator<PluginInfo> i = _plugins.listIterator(_plugins.size()); + while(i.hasPrevious()) { + PluginInfo p = i.previous(); try { - p.getValue().destroy(); + p.plugin.destroy(); } catch(RuntimeException ex) { - Ice.Util.getProcessLogger().warning("unexpected exception raised by plug-in `" + p.getKey() + - "' destruction:\n" + ex.toString()); + Ice.Util.getProcessLogger().warning("unexpected exception raised by plug-in `" + + p.name + "' destruction:\n" + ex.toString()); } } } _communicator = null; } + + _plugins.clear(); + + if(_classLoaders != null) + { + _classLoaders.clear(); + } } public - PluginManagerI(Communicator communicator) + PluginManagerI(Communicator communicator, IceInternal.Instance instance) { _communicator = communicator; + _instance = instance; _initialized = false; } @@ -163,7 +178,7 @@ public final class PluginManagerI implements PluginManager final String[] loadOrder = properties.getPropertyAsList("Ice.PluginLoadOrder"); for(String name : loadOrder) { - if(_plugins.containsKey(name)) + if(findPlugin(name) != null) { PluginInitializationException ex = new PluginInitializationException(); ex.reason = "plug-in `" + name + "' already loaded"; @@ -181,7 +196,7 @@ public final class PluginManagerI implements PluginManager key = "Ice.Plugin." + name; hasKey = plugins.containsKey(key); } - + if(hasKey) { final String value = plugins.get(key); @@ -222,10 +237,10 @@ public final class PluginManagerI implements PluginManager name = name.substring(0, dotPos); loadPlugin(name, entry.getValue(), cmdArgs); p.remove(); - + // // Don't want to load this one if it's there! - // + // plugins.remove("Ice.Plugin." + name); } else @@ -236,7 +251,7 @@ public final class PluginManagerI implements PluginManager dotPos = -1; } } - + if(dotPos == -1) { // @@ -250,7 +265,7 @@ public final class PluginManagerI implements PluginManager { value = javaValue; } - + loadPlugin(name, value, cmdArgs); } } @@ -262,31 +277,88 @@ public final class PluginManagerI implements PluginManager assert(_communicator != null); // - // Separate the entry point from the arguments. + // We support the following formats: // - String className; + // <class-name> [args] + // <jar-file>:<class-name> [args] + // <class-dir>:<class-name> [args] + // "<path with spaces>":<class-name> [args] + // "<path with spaces>:<class-name>" [args] + // + String[] args; - int pos = pluginSpec.indexOf(' '); - if(pos == -1) + try { - pos = pluginSpec.indexOf('\t'); + args = IceUtilInternal.Options.split(pluginSpec); } - if(pos == -1) + catch(IceUtilInternal.Options.BadQuote ex) + { + throw new PluginInitializationException("invalid arguments for plug-in `" + name + "':\n" + + ex.getMessage()); + } + + assert(args.length > 0); + + final String entryPoint = args[0]; + + final boolean isWindows = System.getProperty("os.name").startsWith("Windows"); + boolean absolutePath = false; + + // + // Find first ':' that isn't part of the file path. + // + int pos = entryPoint.indexOf(':'); + if(isWindows) + { + final String driveLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + if(pos == 1 && entryPoint.length() > 2 && driveLetters.indexOf(entryPoint.charAt(0)) != -1 && + (entryPoint.charAt(2) == '\\' || entryPoint.charAt(2) == '/')) + { + absolutePath = true; + pos = entryPoint.indexOf(':', pos + 1); + } + if(!absolutePath) + { + absolutePath = entryPoint.startsWith("\\\\"); + } + } + else + { + absolutePath = entryPoint.startsWith("/"); + } + + if((pos == -1 && absolutePath) || (pos != -1 && entryPoint.length() <= pos + 1)) { - pos = pluginSpec.indexOf('\n'); + // + // Class name is missing. + // + throw new PluginInitializationException("invalid entry point for plug-in `" + name + "':\n" + entryPoint); } + + // + // Extract the JAR file or subdirectory, if any. + // + String classDir = null; // Path name of JAR file or subdirectory. + String className; + if(pos == -1) { - className = pluginSpec; - args = new String[0]; + className = entryPoint; } else { - className = pluginSpec.substring(0, pos); - args = pluginSpec.substring(pos).trim().split("[ \t\n]+", pos); + classDir = entryPoint.substring(0, pos).trim(); + className = entryPoint.substring(pos + 1).trim(); } // + // Shift the arguments. + // + String[] tmp = new String[args.length - 1]; + System.arraycopy(args, 1, tmp, 0, args.length - 1); + args = tmp; + + // // Convert command-line options into properties. First we // convert the options from the plug-in configuration, then // we convert the options from the application command-line. @@ -301,13 +373,85 @@ public final class PluginManagerI implements PluginManager PluginFactory pluginFactory = null; try { - Class<?> c = IceInternal.Util.getInstance(_communicator).findClass(className); + Class<?> c = null; + + // + // Use a class loader if the user specified a JAR file or class directory. + // + if(classDir != null) + { + try + { + if(!absolutePath) + { + classDir = new java.io.File(System.getProperty("user.dir") + java.io.File.separator + + classDir).getCanonicalPath(); + } + + if(!classDir.endsWith(java.io.File.separator) && !classDir.toLowerCase().endsWith(".jar")) + { + classDir += java.io.File.separator; + } + + // + // Reuse an existing class loader if we have already loaded a plug-in with + // the same value for classDir, otherwise create a new one. + // + ClassLoader cl = null; + + if(_classLoaders == null) + { + _classLoaders = new java.util.HashMap<String, ClassLoader>(); + } + else + { + cl = _classLoaders.get(classDir); + } + + if(cl == null) + { + final java.net.URL[] url = new java.net.URL[] { new java.net.URL("file:///" + classDir) }; + + // + // Use the custom class loader (if any) as the parent. + // + if(_instance.initializationData().classLoader != null) + { + cl = new java.net.URLClassLoader(url, _instance.initializationData().classLoader); + } + else + { + cl = new java.net.URLClassLoader(url); + } + + _classLoaders.put(classDir, cl); + } + + c = cl.loadClass(className); + } + catch(java.net.MalformedURLException ex) + { + throw new PluginInitializationException("invalid entry point format `" + pluginSpec + "'", ex); + } + catch(java.io.IOException ex) + { + throw new PluginInitializationException("invalid path in entry point `" + pluginSpec + "'", ex); + } + catch(java.lang.ClassNotFoundException ex) + { + // Ignored + } + } + else + { + c = IceInternal.Util.getInstance(_communicator).findClass(className); + } + if(c == null) { - PluginInitializationException e = new PluginInitializationException(); - e.reason = "class " + className + " not found"; - throw e; + throw new PluginInitializationException("class " + className + " not found"); } + java.lang.Object obj = c.newInstance(); try { @@ -315,8 +459,8 @@ public final class PluginManagerI implements PluginManager } catch(ClassCastException ex) { - throw new PluginInitializationException( - "class " + className + " does not implement Ice.PluginFactory", ex); + throw new PluginInitializationException("class " + className + " does not implement Ice.PluginFactory", + ex); } } catch(IllegalAccessException ex) @@ -344,18 +488,40 @@ public final class PluginManagerI implements PluginManager { throw new PluginInitializationException("exception in factory " + className, ex); } - + if(plugin == null) { throw new PluginInitializationException("failure in factory " + className); } - _plugins.put(name, plugin); - _initOrder.add(plugin); + PluginInfo info = new PluginInfo(); + info.name = name; + info.plugin = plugin; + _plugins.add(info); + } + + private Plugin + findPlugin(String name) + { + for(PluginInfo p : _plugins) + { + if(name.equals(p.name)) + { + return p.plugin; + } + } + return null; + } + + static class PluginInfo + { + String name; + Plugin plugin; } private Communicator _communicator; - private java.util.Map<String, Plugin> _plugins = new java.util.HashMap<String, Plugin>(); - private java.util.List<Plugin> _initOrder = new java.util.ArrayList<Plugin>(); + private IceInternal.Instance _instance; + private java.util.List<PluginInfo> _plugins = new java.util.ArrayList<PluginInfo>(); private boolean _initialized; + private java.util.Map<String, ClassLoader> _classLoaders; } diff --git a/java/src/IceBox/ServiceManagerI.java b/java/src/IceBox/ServiceManagerI.java index 8811bb84932..aa066fb2e7e 100644 --- a/java/src/IceBox/ServiceManagerI.java +++ b/java/src/IceBox/ServiceManagerI.java @@ -214,7 +214,6 @@ public class ServiceManagerI extends _ServiceManagerDisp "Added service observer " + _communicator.proxyToString(observer)); } - for(ServiceInfo info: _services) { if(info.status == StatusStarted) @@ -222,7 +221,6 @@ public class ServiceManagerI extends _ServiceManagerDisp activeServices.add(info.name); } } - } } @@ -355,7 +353,7 @@ public class ServiceManagerI extends _ServiceManagerDisp for(StartServiceInfo s : servicesInfo) { - start(s.name, s.className, s.args); + start(s.name, s.className, s.classDir, s.absolutePath, s.args); } // @@ -462,7 +460,7 @@ public class ServiceManagerI extends _ServiceManagerDisp } synchronized private void - start(String service, String className, String[] args) + start(String service, String className, String classDir, boolean absolutePath, String[] args) throws FailureException { // @@ -475,12 +473,74 @@ public class ServiceManagerI extends _ServiceManagerDisp try { - Class<?> c = IceInternal.Util.findClass(className, null); + Class<?> c = null; + + // + // Use a class loader if the user specified a JAR file or class directory. + // + if(classDir != null) + { + try + { + if(!absolutePath) + { + classDir = new java.io.File(System.getProperty("user.dir") + java.io.File.separator + + classDir).getCanonicalPath(); + } + + if(!classDir.endsWith(java.io.File.separator) && !classDir.endsWith(".jar")) + { + classDir += java.io.File.separator; + } + + // + // Reuse an existing class loader if we have already loaded a plug-in with + // the same value for classDir, otherwise create a new one. + // + ClassLoader cl = null; + + if(_classLoaders == null) + { + _classLoaders = new java.util.HashMap<String, ClassLoader>(); + } + else + { + cl = _classLoaders.get(classDir); + } + + if(cl == null) + { + final java.net.URL[] url = new java.net.URL[] { new java.net.URL("file:///" + classDir) }; + + cl = new java.net.URLClassLoader(url); + + _classLoaders.put(classDir, cl); + } + + c = cl.loadClass(className); + } + catch(java.net.MalformedURLException ex) + { + throw new FailureException("ServiceManager: invalid entry point format `" + classDir + "'", ex); + } + catch(java.io.IOException ex) + { + throw new FailureException("ServiceManager: invalid path in plug-in entry point `" + classDir + + "'", ex); + } + catch(java.lang.ClassNotFoundException ex) + { + // Ignored + } + } + else + { + c = IceInternal.Util.findClass(className, null); + } + if(c == null) { - FailureException e = new FailureException(); - e.reason = "ServiceManager: class " + className + " not found"; - throw e; + throw new FailureException("ServiceManager: class " + className + " not found"); } // @@ -893,28 +953,85 @@ public class ServiceManagerI extends _ServiceManagerDisp name = service; // - // Separate the entry point from the arguments. + // We support the following formats: // - int pos = IceUtilInternal.StringUtil.findFirstOf(value, " \t\n"); - if(pos == -1) + // <class-name> [args] + // <jar-file>:<class-name> [args] + // <class-dir>:<class-name> [args] + // "<path with spaces>":<class-name> [args] + // "<path with spaces>:<class-name>" [args] + // + + try { - className = value; - args = new String[0]; + args = IceUtilInternal.Options.split(value); } - else + catch(IceUtilInternal.Options.BadQuote ex) { - className = value.substring(0, pos); - try + throw new FailureException("ServiceManager: invalid arguments for service `" + name + "':\n" + + ex.getMessage()); + } + + assert(args.length > 0); + + final String entryPoint = args[0]; + + final boolean isWindows = System.getProperty("os.name").startsWith("Windows"); + absolutePath = false; + + // + // Find first ':' that isn't part of the file path. + // + int pos = entryPoint.indexOf(':'); + if(isWindows) + { + final String driveLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + if(pos == 1 && entryPoint.length() > 2 && driveLetters.indexOf(entryPoint.charAt(0)) != -1 && + (entryPoint.charAt(2) == '\\' || entryPoint.charAt(2) == '/')) { - args = IceUtilInternal.Options.split(value.substring(pos)); + absolutePath = true; + pos = entryPoint.indexOf(':', pos + 1); } - catch(IceUtilInternal.Options.BadQuote ex) + if(!absolutePath) { - FailureException e = new FailureException(); - e.reason = "ServiceManager: invalid arguments for service `" + name + "':\n" + ex.toString(); - throw e; + absolutePath = entryPoint.startsWith("\\\\"); } } + else + { + absolutePath = entryPoint.startsWith("/"); + } + + if((pos == -1 && absolutePath) || (pos != -1 && entryPoint.length() <= pos + 1)) + { + // + // Class name is missing. + // + throw new FailureException("ServiceManager: invalid entry point for service `" + name + "':\n" + + entryPoint); + } + + // + // Extract the JAR file or subdirectory, if any. + // + classDir = null; // Path name of JAR file or subdirectory. + + if(pos == -1) + { + className = entryPoint; + } + else + { + classDir = entryPoint.substring(0, pos).trim(); + className = entryPoint.substring(pos + 1).trim(); + } + + // + // Shift the arguments. + // + String[] tmp = new String[args.length - 1]; + System.arraycopy(args, 1, tmp, 0, args.length - 1); + args = tmp; if(serverArgs.length > 0) { @@ -933,6 +1050,8 @@ public class ServiceManagerI extends _ServiceManagerDisp String name; String[] args; String className; + String classDir; + boolean absolutePath; } private Ice.Properties @@ -969,6 +1088,7 @@ public class ServiceManagerI extends _ServiceManagerDisp private java.util.List<ServiceInfo> _services = new java.util.LinkedList<ServiceInfo>(); private boolean _pendingStatusChanges = false; private Ice.Callback _observerCompletedCB; - java.util.HashSet<ServiceObserverPrx> _observers = new java.util.HashSet<ServiceObserverPrx>(); - int _traceServiceObserver = 0; + private java.util.HashSet<ServiceObserverPrx> _observers = new java.util.HashSet<ServiceObserverPrx>(); + private int _traceServiceObserver = 0; + private java.util.Map<String, ClassLoader> _classLoaders; } diff --git a/java/src/IceInternal/Instance.java b/java/src/IceInternal/Instance.java index 7ca90d82144..4f1334be0b8 100644 --- a/java/src/IceInternal/Instance.java +++ b/java/src/IceInternal/Instance.java @@ -684,7 +684,7 @@ public final class Instance EndpointFactory udpEndpointFactory = new UdpEndpointFactory(this); _endpointFactoryManager.add(udpEndpointFactory); - _pluginManager = new Ice.PluginManagerI(communicator); + _pluginManager = new Ice.PluginManagerI(communicator, this); _outgoingConnectionFactory = new OutgoingConnectionFactory(communicator, this); diff --git a/java/src/IceInternal/Util.java b/java/src/IceInternal/Util.java index 6ecc0505a89..f4c383e6388 100644 --- a/java/src/IceInternal/Util.java +++ b/java/src/IceInternal/Util.java @@ -151,7 +151,6 @@ public final class Util private static Class<?> loadClass(String className, ClassLoader cl) - throws LinkageError { if(cl != null) { diff --git a/java/test/Ice/plugin/Client.java b/java/test/Ice/plugin/Client.java new file mode 100644 index 00000000000..db43197209c --- /dev/null +++ b/java/test/Ice/plugin/Client.java @@ -0,0 +1,197 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +package test.Ice.plugin; + +import java.io.PrintWriter; + +public class Client extends test.Util.Application +{ + public int run(String[] args) + { + Ice.Communicator communicator = communicator(); + PrintWriter printWriter = getWriter(); + printWriter.print("testing a simple plug-in... "); + printWriter.flush(); + try + { + Ice.InitializationData initData = new Ice.InitializationData(); + initData.properties = Ice.Util.createProperties(); + initData.properties.setProperty("Ice.Plugin.Test", + "../../../lib/IceTestPlugins.jar:test.Ice.plugin.plugins.PluginFactory " + + "'C:\\Program Files\\' --DatabasePath 'C:\\Program Files\\Application\\db'"); + communicator = Ice.Util.initialize(args, initData); + communicator.destroy(); + } + catch(Ice.LocalException ex) + { + ex.printStackTrace(); + test(false); + } + printWriter.println("ok"); + + printWriter.print("testing a simple plug-in that fails to initialize... "); + printWriter.flush(); + communicator = null; + try + { + Ice.InitializationData initData = new Ice.InitializationData(); + initData.properties = Ice.Util.createProperties(); + initData.properties.setProperty("Ice.Plugin.Test", + "../../../lib/:test.Ice.plugin.plugins.PluginInitializeFailFactory"); + communicator = Ice.Util.initialize(args, initData); + test(false); + } + catch(RuntimeException ex) + { + test(ex.getMessage().equals("PluginInitializeFailException")); + } + test(communicator == null); + printWriter.println("ok"); + + printWriter.print("testing plug-in load order... "); + printWriter.flush(); + try + { + Ice.InitializationData initData = new Ice.InitializationData(); + initData.properties = Ice.Util.createProperties(); + initData.properties.setProperty("Ice.Plugin.PluginOne", + "../../../lib/:test.Ice.plugin.plugins.PluginOneFactory"); + initData.properties.setProperty("Ice.Plugin.PluginTwo", + "../../../lib/:test.Ice.plugin.plugins.PluginTwoFactory"); + initData.properties.setProperty("Ice.Plugin.PluginThree", + "../../../lib/:test.Ice.plugin.plugins.PluginThreeFactory"); + initData.properties.setProperty("Ice.PluginLoadOrder", "PluginOne, PluginTwo"); // Exclude PluginThree + communicator = Ice.Util.initialize(args, initData); + communicator.destroy(); + } + catch(Ice.LocalException ex) + { + ex.printStackTrace(); + test(false); + } + printWriter.println("ok"); + + printWriter.print("testing plug-in manager... "); + printWriter.flush(); + try + { + Ice.InitializationData initData = new Ice.InitializationData(); + initData.properties = Ice.Util.createProperties(); + initData.properties.setProperty("Ice.Plugin.PluginOne", + "../../../lib/:test.Ice.plugin.plugins.PluginOneFactory"); + initData.properties.setProperty("Ice.Plugin.PluginTwo", + "../../../lib/:test.Ice.plugin.plugins.PluginTwoFactory"); + initData.properties.setProperty("Ice.Plugin.PluginThree", + "../../../lib/:test.Ice.plugin.plugins.PluginThreeFactory"); + initData.properties.setProperty("Ice.PluginLoadOrder", "PluginOne, PluginTwo"); + initData.properties.setProperty("Ice.InitPlugins", "0"); + communicator = Ice.Util.initialize(args, initData); + + Ice.PluginManager pm = communicator.getPluginManager(); + test(pm.getPlugin("PluginOne") != null); + test(pm.getPlugin("PluginTwo") != null); + test(pm.getPlugin("PluginThree") != null); + + MyPlugin p4 = new MyPlugin(); + pm.addPlugin("PluginFour", p4); + test(pm.getPlugin("PluginFour") != null); + + pm.initializePlugins(); + + test(p4.isInitialized()); + + communicator.destroy(); + + test(p4.isDestroyed()); + } + catch(Ice.LocalException ex) + { + ex.printStackTrace(); + test(false); + } + printWriter.println("ok"); + + printWriter.print("testing destroy when a plug-in fails to initialize... "); + printWriter.flush(); + communicator = null; + try + { + Ice.InitializationData initData = new Ice.InitializationData(); + initData.properties = Ice.Util.createProperties(); + initData.properties.setProperty("Ice.Plugin.PluginOneFail", + "../../../lib/:test.Ice.plugin.plugins.PluginOneFailFactory"); + initData.properties.setProperty("Ice.Plugin.PluginTwoFail", + "../../../lib/:test.Ice.plugin.plugins.PluginTwoFailFactory"); + initData.properties.setProperty("Ice.Plugin.PluginThreeFail", + "../../../lib/:test.Ice.plugin.plugins.PluginThreeFailFactory"); + initData.properties.setProperty("Ice.PluginLoadOrder", "PluginOneFail, PluginTwoFail, PluginThreeFail"); + communicator = Ice.Util.initialize(args, initData); + } + catch(RuntimeException ex) + { + test(ex.getMessage().equals("PluginInitializeFailException")); + } + test(communicator == null); + printWriter.println("ok"); + + System.gc(); + System.runFinalization(); + return 0; + } + + protected Ice.InitializationData getInitData(Ice.StringSeqHolder argsH) + { + Ice.InitializationData initData = new Ice.InitializationData(); + initData.properties = Ice.Util.createProperties(argsH); + return initData; + } + + private static void test(boolean b) + { + if(!b) + { + throw new RuntimeException(); + } + } + + public static void main(String[] args) + { + Client app = new Client(); + int result = app.main("Client", args); + System.gc(); + System.exit(result); + } + + static class MyPlugin implements Ice.Plugin + { + public boolean isInitialized() + { + return _initialized; + } + + public boolean isDestroyed() + { + return _destroyed; + } + + public void initialize() + { + _initialized = true; + } + + public void destroy() + { + _destroyed = true; + } + + private boolean _initialized = false; + private boolean _destroyed = false; + } +} diff --git a/java/test/Ice/plugin/plugins/BasePlugin.java b/java/test/Ice/plugin/plugins/BasePlugin.java new file mode 100644 index 00000000000..da0d7000ca6 --- /dev/null +++ b/java/test/Ice/plugin/plugins/BasePlugin.java @@ -0,0 +1,41 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +package test.Ice.plugin.plugins; + +public abstract class BasePlugin implements Ice.Plugin +{ + public BasePlugin(Ice.Communicator communicator) + { + _communicator = communicator; + } + + public boolean isInitialized() + { + return _initialized; + } + + public boolean isDestroyed() + { + return _destroyed; + } + + protected static void test(boolean b) + { + if(!b) + { + throw new RuntimeException(); + } + } + + protected Ice.Communicator _communicator; + protected boolean _initialized = false; + protected boolean _destroyed = false; + protected BasePlugin _other = null; +} diff --git a/java/test/Ice/plugin/plugins/BasePluginFail.java b/java/test/Ice/plugin/plugins/BasePluginFail.java new file mode 100644 index 00000000000..bba0cc21760 --- /dev/null +++ b/java/test/Ice/plugin/plugins/BasePluginFail.java @@ -0,0 +1,45 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +package test.Ice.plugin.plugins; + +public abstract class BasePluginFail implements Ice.Plugin +{ + public BasePluginFail(Ice.Communicator communicator) + { + _communicator = communicator; + _initialized = false; + _destroyed = false; + } + + public boolean isInitialized() + { + return _initialized; + } + + public boolean isDestroyed() + { + return _destroyed; + } + + protected static void test(boolean b) + { + if(!b) + { + throw new RuntimeException(); + } + } + + protected Ice.Communicator _communicator; + protected boolean _initialized; + protected boolean _destroyed; + protected BasePluginFail _one; + protected BasePluginFail _two; + protected BasePluginFail _three; +} diff --git a/java/test/Ice/plugin/plugins/PluginFactory.java b/java/test/Ice/plugin/plugins/PluginFactory.java new file mode 100644 index 00000000000..dff16aa61f8 --- /dev/null +++ b/java/test/Ice/plugin/plugins/PluginFactory.java @@ -0,0 +1,73 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +package test.Ice.plugin.plugins; + +public class PluginFactory implements Ice.PluginFactory +{ + public Ice.Plugin create(Ice.Communicator communicator, String name, String[] args) + { + return new Plugin(communicator, args); + } + + static class Plugin implements Ice.Plugin + { + public Plugin(Ice.Communicator communicator, String[] args) + { + _communicator = communicator; + _args = args; + } + + public void initialize() + { + _initialized = true; + test(_args.length == 3); + test(_args[0].equals("C:\\Program Files\\")); + test(_args[1].equals("--DatabasePath")); + test(_args[2].equals("C:\\Program Files\\Application\\db")); + } + + public void destroy() + { + _destroyed = true; + } + + protected void finalize() throws Throwable + { + try + { + if(!_initialized) + { + System.out.println("test.Ice.plugin.plugins.Plugin not initialized"); + } + if(!_destroyed) + { + System.out.println("test.Ice.plugin.plugins.Plugin not destroyed"); + } + } + finally + { + super.finalize(); + } + } + + private static void test(boolean b) + { + if(!b) + { + throw new RuntimeException(); + } + } + + private Ice.Communicator _communicator; + private String[] _args; + private boolean _initialized = false; + private boolean _destroyed = false; + } +} diff --git a/java/test/Ice/plugin/plugins/PluginInitializeFailException.java b/java/test/Ice/plugin/plugins/PluginInitializeFailException.java new file mode 100644 index 00000000000..ed1700bc4e5 --- /dev/null +++ b/java/test/Ice/plugin/plugins/PluginInitializeFailException.java @@ -0,0 +1,18 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +package test.Ice.plugin.plugins; + +public class PluginInitializeFailException extends java.lang.RuntimeException +{ + public PluginInitializeFailException() + { + super("PluginInitializeFailException"); + } +} diff --git a/java/test/Ice/plugin/plugins/PluginInitializeFailFactory.java b/java/test/Ice/plugin/plugins/PluginInitializeFailFactory.java new file mode 100644 index 00000000000..a2e00176ed0 --- /dev/null +++ b/java/test/Ice/plugin/plugins/PluginInitializeFailFactory.java @@ -0,0 +1,39 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +package test.Ice.plugin.plugins; + +public class PluginInitializeFailFactory implements Ice.PluginFactory +{ + public Ice.Plugin create(Ice.Communicator communicator, String name, String[] args) + { + return new PluginInitializeFail(); + } + + static class PluginInitializeFail implements Ice.Plugin + { + public void initialize() + { + throw new PluginInitializeFailException(); + } + + public void destroy() + { + test(false); + } + + private static void test(boolean b) + { + if(!b) + { + throw new RuntimeException(); + } + } + } +} diff --git a/java/test/Ice/plugin/plugins/PluginOneFactory.java b/java/test/Ice/plugin/plugins/PluginOneFactory.java new file mode 100644 index 00000000000..1101ae22f4f --- /dev/null +++ b/java/test/Ice/plugin/plugins/PluginOneFactory.java @@ -0,0 +1,39 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +package test.Ice.plugin.plugins; + +public class PluginOneFactory implements Ice.PluginFactory +{ + public Ice.Plugin create(Ice.Communicator communicator, String name, String[] args) + { + return new PluginOne(communicator); + } + + static class PluginOne extends BasePlugin + { + public PluginOne(Ice.Communicator communicator) + { + super(communicator); + } + + public void initialize() + { + _other = (BasePlugin)_communicator.getPluginManager().getPlugin("PluginTwo"); + test(!_other.isInitialized()); + _initialized = true; + } + + public void destroy() + { + _destroyed = true; + test(_other.isDestroyed()); + } + } +} diff --git a/java/test/Ice/plugin/plugins/PluginOneFailFactory.java b/java/test/Ice/plugin/plugins/PluginOneFailFactory.java new file mode 100644 index 00000000000..84a2db46af2 --- /dev/null +++ b/java/test/Ice/plugin/plugins/PluginOneFailFactory.java @@ -0,0 +1,64 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +package test.Ice.plugin.plugins; + +public class PluginOneFailFactory implements Ice.PluginFactory +{ + public Ice.Plugin create(Ice.Communicator communicator, String name, String[] args) + { + return new PluginOneFail(communicator); + } + + static class PluginOneFail extends BasePluginFail + { + public PluginOneFail(Ice.Communicator communicator) + { + super(communicator); + } + + public void initialize() + { + _two = (BasePluginFail)_communicator.getPluginManager().getPlugin("PluginTwoFail"); + test(!_two.isInitialized()); + _three = (BasePluginFail)_communicator.getPluginManager().getPlugin("PluginThreeFail"); + test(!_three.isInitialized()); + _initialized = true; + } + + public void destroy() + { + test(_two.isDestroyed()); + // + // Not destroyed because initialize fails. + // + test(!_three.isDestroyed()); + _destroyed = true; + } + + protected void finalize() throws Throwable + { + try + { + if(!_initialized) + { + System.out.println(getClass().getName() + " not initialized"); + } + if(!_destroyed) + { + System.out.println(getClass().getName() + " not destroyed"); + } + } + finally + { + super.finalize(); + } + } + } +} diff --git a/java/test/Ice/plugin/plugins/PluginThreeFactory.java b/java/test/Ice/plugin/plugins/PluginThreeFactory.java new file mode 100644 index 00000000000..73eeccabd44 --- /dev/null +++ b/java/test/Ice/plugin/plugins/PluginThreeFactory.java @@ -0,0 +1,39 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +package test.Ice.plugin.plugins; + +public class PluginThreeFactory implements Ice.PluginFactory +{ + public Ice.Plugin create(Ice.Communicator communicator, String name, String[] args) + { + return new PluginThree(communicator); + } + + static class PluginThree extends BasePlugin + { + public PluginThree(Ice.Communicator communicator) + { + super(communicator); + } + + public void initialize() + { + _other = (BasePlugin)_communicator.getPluginManager().getPlugin("PluginTwo"); + test(_other.isInitialized()); + _initialized = true; + } + + public void destroy() + { + _destroyed = true; + test(!_other.isDestroyed()); + } + } +} diff --git a/java/test/Ice/plugin/plugins/PluginThreeFailFactory.java b/java/test/Ice/plugin/plugins/PluginThreeFailFactory.java new file mode 100644 index 00000000000..846675fea12 --- /dev/null +++ b/java/test/Ice/plugin/plugins/PluginThreeFailFactory.java @@ -0,0 +1,55 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +package test.Ice.plugin.plugins; + +public class PluginThreeFailFactory implements Ice.PluginFactory +{ + public Ice.Plugin create(Ice.Communicator communicator, String name, String[] args) + { + return new PluginThreeFail(communicator); + } + + public class PluginThreeFail extends BasePluginFail + { + public PluginThreeFail(Ice.Communicator communicator) + { + super(communicator); + } + + public void initialize() + { + throw new PluginInitializeFailException(); + } + + public void destroy() + { + test(false); + } + + protected void finalize() throws Throwable + { + try + { + if(_initialized) + { + System.out.println(getClass().getName() + " was initialized"); + } + if(_destroyed) + { + System.out.println(getClass().getName() + " was destroyed"); + } + } + finally + { + super.finalize(); + } + } + } +} diff --git a/java/test/Ice/plugin/plugins/PluginTwoFactory.java b/java/test/Ice/plugin/plugins/PluginTwoFactory.java new file mode 100644 index 00000000000..7b8e970f07c --- /dev/null +++ b/java/test/Ice/plugin/plugins/PluginTwoFactory.java @@ -0,0 +1,39 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +package test.Ice.plugin.plugins; + +public class PluginTwoFactory implements Ice.PluginFactory +{ + public Ice.Plugin create(Ice.Communicator communicator, String name, String[] args) + { + return new PluginTwo(communicator); + } + + static class PluginTwo extends BasePlugin + { + public PluginTwo(Ice.Communicator communicator) + { + super(communicator); + } + + public void initialize() + { + _other = (BasePlugin)_communicator.getPluginManager().getPlugin("PluginOne"); + test(_other.isInitialized()); + _initialized = true; + } + + public void destroy() + { + _destroyed = true; + test(!_other.isDestroyed()); + } + } +} diff --git a/java/test/Ice/plugin/plugins/PluginTwoFailFactory.java b/java/test/Ice/plugin/plugins/PluginTwoFailFactory.java new file mode 100644 index 00000000000..80dd2fdf2f2 --- /dev/null +++ b/java/test/Ice/plugin/plugins/PluginTwoFailFactory.java @@ -0,0 +1,64 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +package test.Ice.plugin.plugins; + +public class PluginTwoFailFactory implements Ice.PluginFactory +{ + public Ice.Plugin create(Ice.Communicator communicator, String name, String[] args) + { + return new PluginTwoFail(communicator); + } + + static class PluginTwoFail extends BasePluginFail + { + public PluginTwoFail(Ice.Communicator communicator) + { + super(communicator); + } + + public void initialize() + { + _one = (BasePluginFail)_communicator.getPluginManager().getPlugin("PluginOneFail"); + test(_one.isInitialized()); + _three = (BasePluginFail)_communicator.getPluginManager().getPlugin("PluginThreeFail"); + test(!_three.isInitialized()); + _initialized = true; + } + + public void destroy() + { + test(!_one.isDestroyed()); + // + // Not destroyed because initialize fails. + // + test(!_three.isDestroyed()); + _destroyed = true; + } + + protected void finalize() throws Throwable + { + try + { + if(!_initialized) + { + System.out.println(getClass().getName() + " not initialized"); + } + if(!_destroyed) + { + System.out.println(getClass().getName() + " not destroyed"); + } + } + finally + { + super.finalize(); + } + } + } +} diff --git a/java/test/Ice/plugin/run.py b/java/test/Ice/plugin/run.py new file mode 100755 index 00000000000..e4b27ab1226 --- /dev/null +++ b/java/test/Ice/plugin/run.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise "can't find toplevel directory!" +sys.path.append(os.path.join(path[0])) +from scripts import * + +print "starting test...", +clientProc = TestUtil.startClient("test.Ice.plugin.Client",startReader=False) +print "ok" +clientProc.startReader() + +clientProc.waitTestSuccess() + |