diff options
author | Jose <jose@zeroc.com> | 2012-08-16 15:58:01 +0200 |
---|---|---|
committer | Jose <jose@zeroc.com> | 2012-08-16 15:58:01 +0200 |
commit | 0b82edbd44b61ab36592f73728e76d1fd11a3aa2 (patch) | |
tree | 8f8a0b6d5cb22a95dfc4b2c257d0eb7c0fe62c9b /java/src/IceBox/ServiceManagerI.java | |
parent | ICE-4820 - Service class public API (diff) | |
download | ice-0b82edbd44b61ab36592f73728e76d1fd11a3aa2.tar.bz2 ice-0b82edbd44b61ab36592f73728e76d1fd11a3aa2.tar.xz ice-0b82edbd44b61ab36592f73728e76d1fd11a3aa2.zip |
ICE-4609 - Add ability to load shared library with full path
- C++/Java now also support to load Services and Plugins from
a full path, this was already supported by .NET
- Fixed the parsing of plug-in arguments to correct split the
arguments
- Fixed Plugin manager destroy C++/Java/C#, the plugin must
are now destroyed in initialization reverse order as documented.
Diffstat (limited to 'java/src/IceBox/ServiceManagerI.java')
-rw-r--r-- | java/src/IceBox/ServiceManagerI.java | 166 |
1 files changed, 143 insertions, 23 deletions
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; } |