private String[] loadPlugin(String name, String pluginSpec, String[] cmdArgs) { assert (_communicator != null); // // We support the following formats: // // <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; try { args = com.zeroc.IceUtilInternal.Options.split(pluginSpec); } catch (com.zeroc.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)) { // // 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 = 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; // // 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. // Properties properties = _communicator.getProperties(); args = properties.parseCommandLineOptions(name, args); cmdArgs = properties.parseCommandLineOptions(name, cmdArgs); // // Instantiate the class. // PluginFactory pluginFactory = null; try { 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; } classDir = URLEncoder.encode(classDir, "UTF-8"); // // 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<>(); } else { cl = _classLoaders.get(classDir); } if (cl == null) { final java.net.URL[] url = new java.net.URL[] {new java.net.URL("file", null, 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 = com.zeroc.IceInternal.Util.getInstance(_communicator).findClass(className); } if (c == null) { throw new PluginInitializationException("class " + className + " not found"); } java.lang.Object obj = c.newInstance(); try { pluginFactory = (PluginFactory) obj; } catch (ClassCastException ex) { throw new PluginInitializationException( "class " + className + " does not implement PluginFactory", ex); } } catch (IllegalAccessException ex) { throw new PluginInitializationException( "unable to access default constructor in class " + className, ex); } catch (InstantiationException ex) { throw new PluginInitializationException("unable to instantiate class " + className, ex); } // // Invoke the factory. // Plugin plugin = null; try { plugin = pluginFactory.create(_communicator, name, args); } catch (PluginInitializationException ex) { throw ex; } catch (Throwable ex) { throw new PluginInitializationException("exception in factory " + className, ex); } if (plugin == null) { throw new PluginInitializationException("failure in factory " + className); } PluginInfo info = new PluginInfo(); info.name = name; info.plugin = plugin; _plugins.add(info); return cmdArgs; }