diff --git a/bundles/org.eclipse.equinox.servletbridge/src/org/eclipse/equinox/servletbridge/BridgeServlet.java b/bundles/org.eclipse.equinox.servletbridge/src/org/eclipse/equinox/servletbridge/BridgeServlet.java index 21159ba5ac2..baa3365f918 100644 --- a/bundles/org.eclipse.equinox.servletbridge/src/org/eclipse/equinox/servletbridge/BridgeServlet.java +++ b/bundles/org.eclipse.equinox.servletbridge/src/org/eclipse/equinox/servletbridge/BridgeServlet.java @@ -22,11 +22,12 @@ import javax.servlet.http.*; /** - * The BridgeServlet provides a means to bridge the servlet and OSGi - * runtimes. This class has 3 main responsibilities: - * 1) Control the lifecycle of the associated FrameworkLauncher in line with its own lifecycle - * 2) Provide a servlet "hook" that allows all servlet requests to be delegated to the registered servlet - * 3) Provide means to manually control the framework lifecycle + * The BridgeServlet provides a means to bridge the servlet and OSGi runtimes. + * This class has 3 main responsibilities: 1) Control the lifecycle of the + * associated FrameworkLauncher in line with its own lifecycle 2) Provide a + * servlet "hook" that allows all servlet requests to be delegated to the + * registered servlet 3) Provide means to manually control the framework + * lifecycle */ public class BridgeServlet extends HttpServlet { @@ -42,8 +43,9 @@ public class BridgeServlet extends HttpServlet { private boolean enableFrameworkControls; /** - * init() is called by the Servlet Container and used to instantiate the frameworkLauncher which MUST be an instance of FrameworkLauncher. - * After instantiating the framework init, deploy, and start are called. + * init() is called by the Servlet Container and used to instantiate the + * frameworkLauncher which MUST be an instance of FrameworkLauncher. After + * instantiating the framework init, deploy, and start are called. */ @Override public void init() throws ServletException { @@ -51,7 +53,8 @@ public void init() throws ServletException { enableFrameworkControls = Boolean.valueOf(getServletConfig().getInitParameter("enableFrameworkControls")); //$NON-NLS-1$ - // Use with caution!! Some classes MUST be initialized with the web-app class loader + // Use with caution!! Some classes MUST be initialized with the web-app class + // loader String frameworkPreloads = getServletConfig().getInitParameter("_contextPreloads"); //$NON-NLS-1$ if (frameworkPreloads != null) { StringTokenizer st = new StringTokenizer(frameworkPreloads, ","); //$NON-NLS-1$ @@ -69,7 +72,8 @@ public void init() throws ServletException { } // Forces load of the SSLSocketFactory on the web-app context class loader - boolean initSSLSocketFactory = Optional.ofNullable(getServletConfig().getInitParameter("_initSSLSocketFactory")).map(Boolean::valueOf).orElse(true); //$NON-NLS-1$ + boolean initSSLSocketFactory = Optional.ofNullable(getServletConfig().getInitParameter("_initSSLSocketFactory")) //$NON-NLS-1$ + .map(Boolean::valueOf).orElse(true); if (initSSLSocketFactory) { try { Class clazz = this.getClass().getClassLoader().loadClass("javax.net.ssl.SSLSocketFactory"); //$NON-NLS-1$ @@ -84,7 +88,8 @@ public void init() throws ServletException { String frameworkLauncherClassParameter = getServletConfig().getInitParameter("frameworkLauncherClass"); //$NON-NLS-1$ if (frameworkLauncherClassParameter != null) { try { - Class frameworkLauncherClass = this.getClass().getClassLoader().loadClass(frameworkLauncherClassParameter); + Class frameworkLauncherClass = this.getClass().getClassLoader() + .loadClass(frameworkLauncherClassParameter); framework = (FrameworkLauncher) frameworkLauncherClass.getDeclaredConstructor().newInstance(); } catch (Exception e) { throw new ServletException(e); @@ -107,7 +112,8 @@ public void init() throws ServletException { } /** - * destroy() is called by the Servlet Container and used to first stop and then destroy the framework. + * destroy() is called by the Servlet Container and used to first stop and then + * destroy the framework. */ @Override public void destroy() { @@ -118,9 +124,10 @@ public void destroy() { } /** - * service is called by the Servlet Container and will first determine if the request is a - * framework control and will otherwise try to delegate to the registered servlet delegate - * + * service is called by the Servlet Container and will first determine if the + * request is a framework control and will otherwise try to delegate to the + * registered servlet delegate + * */ @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { @@ -175,12 +182,12 @@ private boolean isExtensionMapping(String servletPath) { } /** - * serviceFrameworkControls currently supports the following commands (identified by the request's pathinfo) - * sp_deploy - Copies the contents of the Equinox application to the install area - * sp_undeploy - Removes the copy of the Equinox application from the install area - * sp_redeploy - Resets the platform (e.g. stops, undeploys, deploys, starts) - * sp_start - Starts a deployed platform - * sp_stop - Stops the platform + * serviceFrameworkControls currently supports the following commands + * (identified by the request's pathinfo) sp_deploy - Copies the contents of the + * Equinox application to the install area sp_undeploy - Removes the copy of the + * Equinox application from the install area sp_redeploy - Resets the platform + * (e.g. stops, undeploys, deploys, starts) sp_start - Starts a deployed + * platform sp_stop - Stops the platform */ @SuppressWarnings("resource") private boolean serviceFrameworkControls(HttpServletRequest req, HttpServletResponse resp) throws IOException { @@ -241,10 +248,11 @@ private synchronized HttpServlet acquireDelegateReference() { } /** - * registerServletDelegate is the hook method called from inside the OSGi runtime to register - * a servlet for which all future servlet calls will be delegated. If not null and no delegate - * is currently registered, init(ServletConfig) will be called on the servletDelegate before - * returning. + * registerServletDelegate is the hook method called from inside the OSGi + * runtime to register a servlet for which all future servlet calls will be + * delegated. If not null and no delegate is currently registered, + * init(ServletConfig) will be called on the servletDelegate before returning. + * * @param servletDelegate - the servlet to register for delegation */ public static synchronized void registerServletDelegate(HttpServlet servletDelegate) { @@ -271,9 +279,12 @@ public static synchronized void registerServletDelegate(HttpServlet servletDeleg } /** - * unregisterServletDelegate is the hook method called from inside the OSGi runtime to unregister a delegate. - * If the servletDelegate matches the current registered delegate destroy() is called on the servletDelegate. - * destroy() will not be called until the delegate is finished servicing any previous requests. + * unregisterServletDelegate is the hook method called from inside the OSGi + * runtime to unregister a delegate. If the servletDelegate matches the current + * registered delegate destroy() is called on the servletDelegate. destroy() + * will not be called until the delegate is finished servicing any previous + * requests. + * * @param servletDelegate - the servlet to unregister */ public static synchronized void unregisterServletDelegate(HttpServlet servletDelegate) { diff --git a/bundles/org.eclipse.equinox.servletbridge/src/org/eclipse/equinox/servletbridge/CloseableURLClassLoader.java b/bundles/org.eclipse.equinox.servletbridge/src/org/eclipse/equinox/servletbridge/CloseableURLClassLoader.java index 464e1d68981..410d649050a 100644 --- a/bundles/org.eclipse.equinox.servletbridge/src/org/eclipse/equinox/servletbridge/CloseableURLClassLoader.java +++ b/bundles/org.eclipse.equinox.servletbridge/src/org/eclipse/equinox/servletbridge/CloseableURLClassLoader.java @@ -40,7 +40,8 @@ public class CloseableURLClassLoader extends URLClassLoader { static { boolean registeredAsParallel; try { - Method parallelCapableMetod = ClassLoader.class.getDeclaredMethod("registerAsParallelCapable", (Class[]) null); //$NON-NLS-1$ + Method parallelCapableMetod = ClassLoader.class.getDeclaredMethod("registerAsParallelCapable", //$NON-NLS-1$ + (Class[]) null); parallelCapableMetod.setAccessible(true); registeredAsParallel = ((Boolean) parallelCapableMetod.invoke(null, (Object[]) null)).booleanValue(); } catch (Throwable e) { @@ -96,8 +97,7 @@ public InputStream getInputStream() throws IOException { } /** - * @throws IOException - * Documented to avoid warning + * @throws IOException Documented to avoid warning */ @Override public JarFile getJarFile() throws IOException { @@ -173,7 +173,7 @@ public CloseableURLClassLoader(URL[] urls) { } /** - * @param urls the URLs from which to load classes and resources + * @param urls the URLs from which to load classes and resources * @param parent the parent class loader used for delegation * @see URLClassLoader */ @@ -182,14 +182,16 @@ public CloseableURLClassLoader(URL[] urls, ClassLoader parent) { } /** - * @param urls the URLs from which to load classes and resources - * @param parent the parent class loader used for delegation - * @param verifyJars flag to determine if jar file verification should be performed + * @param urls the URLs from which to load classes and resources + * @param parent the parent class loader used for delegation + * @param verifyJars flag to determine if jar file verification should be + * performed * @see URLClassLoader */ public CloseableURLClassLoader(URL[] urls, ClassLoader parent, boolean verifyJars) { super(excludeFileJarURLS(urls), parent); - this.registeredAsParallel = CLOSEABLE_REGISTERED_AS_PARALLEL && this.getClass() == CloseableURLClassLoader.class; + this.registeredAsParallel = CLOSEABLE_REGISTERED_AS_PARALLEL + && this.getClass() == CloseableURLClassLoader.class; this.context = AccessController.getContext(); this.verifyJars = verifyJars; for (URL url : urls) { @@ -202,7 +204,8 @@ public CloseableURLClassLoader(URL[] urls, ClassLoader parent, boolean verifyJar // @GuardedBy("loaders") private boolean safeAddLoader(URL url) { - //assume all illegal characters have been properly encoded, so use URI class to unencode + // assume all illegal characters have been properly encoded, so use URI class to + // unencode try { File file = new File(toURI(url)); if (file.exists()) { @@ -224,13 +227,15 @@ private static URI toURI(URL url) throws URISyntaxException { if (!SCHEME_FILE.equals(url.getProtocol())) { throw new IllegalArgumentException("bad prototcol: " + url.getProtocol()); //$NON-NLS-1$ } - //URL behaves differently across platforms so for file: URLs we parse from string form + // URL behaves differently across platforms so for file: URLs we parse from + // string form String pathString = url.toExternalForm().substring(5); - //ensure there is a leading slash to handle common malformed URLs such as file:c:/tmp + // ensure there is a leading slash to handle common malformed URLs such as + // file:c:/tmp if (pathString.indexOf('/') != 0) pathString = '/' + pathString; else if (pathString.startsWith(UNC_PREFIX) && !pathString.startsWith(UNC_PREFIX, 2)) { - //URL encodes UNC path with two slashes, but URI uses four (see bug 207103) + // URL encodes UNC path with two slashes, but URI uses four (see bug 207103) pathString = ensureUNCPath(pathString); } return new URI(SCHEME_FILE, null, pathString, null); @@ -243,7 +248,7 @@ private static String ensureUNCPath(String path) { int len = path.length(); StringBuilder result = new StringBuilder(len); for (int i = 0; i < 4; i++) { - // if we have hit the first non-slash character, add another leading slash + // if we have hit the first non-slash character, add another leading slash if (i >= len || result.length() > 0 || path.charAt(i) != '/') result.append('/'); } @@ -362,7 +367,8 @@ private void checkForSealedPackage(Package pkg, String packageName, Manifest man // previously sealed case if (!pkg.isSealed(jarFileURL)) { // this URL does not seal; ERROR - throw new SecurityException("The package '" + packageName + "' was previously loaded and is already sealed."); //$NON-NLS-1$ //$NON-NLS-2$ + throw new SecurityException( + "The package '" + packageName + "' was previously loaded and is already sealed."); //$NON-NLS-1$ //$NON-NLS-2$ } } else { // previously unsealed case @@ -378,8 +384,10 @@ private void checkForSealedPackage(Package pkg, String packageName, Manifest man sealed = mainAttributes.getValue(Name.SEALED); } if (Boolean.valueOf(sealed).booleanValue()) { - // this manifest attempts to seal when package defined previously unsealed; ERROR - throw new SecurityException("The package '" + packageName + "' was previously loaded unsealed. Cannot seal package."); //$NON-NLS-1$ //$NON-NLS-2$ + // this manifest attempts to seal when package defined previously unsealed; + // ERROR + throw new SecurityException( + "The package '" + packageName + "' was previously loaded unsealed. Cannot seal package."); //$NON-NLS-1$ //$NON-NLS-2$ } } } @@ -432,8 +440,9 @@ public Object run() { } /** - * The "close" method is called when the class loader is no longer needed and we should close any open resources. - * In particular this method will close the jar files associated with this class loader. + * The "close" method is called when the class loader is no longer needed and we + * should close any open resources. In particular this method will close the jar + * files associated with this class loader. */ @Override public void close() { diff --git a/bundles/org.eclipse.equinox.servletbridge/src/org/eclipse/equinox/servletbridge/FrameworkLauncher.java b/bundles/org.eclipse.equinox.servletbridge/src/org/eclipse/equinox/servletbridge/FrameworkLauncher.java index e788291b623..521ad235283 100644 --- a/bundles/org.eclipse.equinox.servletbridge/src/org/eclipse/equinox/servletbridge/FrameworkLauncher.java +++ b/bundles/org.eclipse.equinox.servletbridge/src/org/eclipse/equinox/servletbridge/FrameworkLauncher.java @@ -29,17 +29,11 @@ import javax.servlet.ServletContext; /** - * The FrameworkLauncher provides the logic to: - * 1) init - * 2) deploy - * 3) start - * 4) stop - * 5) undeploy - * 6) destroy - * an instance of the OSGi framework. - * These 6 methods are provided to help manage the life-cycle and are called from outside this - * class by the BridgeServlet. To create an extended FrameworkLauncher over-ride these methods to allow - * custom behavior. + * The FrameworkLauncher provides the logic to: 1) init 2) deploy 3) start 4) + * stop 5) undeploy 6) destroy an instance of the OSGi framework. These 6 + * methods are provided to help manage the life-cycle and are called from + * outside this class by the BridgeServlet. To create an extended + * FrameworkLauncher over-ride these methods to allow custom behavior. */ public class FrameworkLauncher { @@ -98,7 +92,8 @@ public Enumeration elements() { }; static { - // We do this to ensure the anonymous Enumeration class in allPermissions is pre-loaded + // We do this to ensure the anonymous Enumeration class in allPermissions is + // pre-loaded if (allPermissions.elements() == null) throw new IllegalStateException(); } @@ -118,7 +113,8 @@ void init(ServletConfig servletConfig) { } /** - * try to find the resource base for this webapp by looking for the launcher initialization file. + * try to find the resource base for this webapp by looking for the launcher + * initialization file. */ protected void initResourceBase() { try { @@ -138,25 +134,25 @@ protected void initResourceBase() { } /** - * init is the first method called on the FrameworkLauncher and can be used for any initial setup. - * The default behavior is to do nothing. + * init is the first method called on the FrameworkLauncher and can be used for + * any initial setup. The default behavior is to do nothing. */ public void init() { // do nothing for now } /** - * destroy is the last method called on the FrameworkLauncher and can be used for any final cleanup. - * The default behavior is to do nothing. + * destroy is the last method called on the FrameworkLauncher and can be used + * for any final cleanup. The default behavior is to do nothing. */ public void destroy() { // do nothing for now } /** - * deploy is used to move the OSGi framework libraries into a location suitable for execution. - * The default behavior is to copy the contents of the webapp's WEB-INF/eclipse directory - * to the webapp's temp directory. + * deploy is used to move the OSGi framework libraries into a location suitable + * for execution. The default behavior is to copy the contents of the webapp's + * WEB-INF/eclipse directory to the webapp's temp directory. */ public synchronized void deploy() { if (platformDirectory != null) { @@ -180,9 +176,11 @@ public synchronized void deploy() { } /** - * deployExtensionBundle will generate the Servletbridge extensionbundle if it is not already present in the platform's - * plugin directory. By default it exports "org.eclipse.equinox.servletbridge" and a versioned export of the Servlet API. - * Additional exports can be added by using the "extendedFrameworkExports" initial-param in the ServletConfig + * deployExtensionBundle will generate the Servletbridge extensionbundle if it + * is not already present in the platform's plugin directory. By default it + * exports "org.eclipse.equinox.servletbridge" and a versioned export of the + * Servlet API. Additional exports can be added by using the + * "extendedFrameworkExports" initial-param in the ServletConfig */ private void deployExtensionBundle(File plugins) { // we might want to parameterize the extension bundle BSN in the future @@ -191,7 +189,8 @@ private void deployExtensionBundle(File plugins) { if (extensionBundleFile == null) generateExtensionBundle(plugins, extensionBundleBSN, EXTENSIONBUNDLE_DEFAULT_VERSION); - else if (Boolean.valueOf(config.getInitParameter(CONFIG_OVERRIDE_AND_REPLACE_EXTENSION_BUNDLE)).booleanValue()) { + else if (Boolean.valueOf(config.getInitParameter(CONFIG_OVERRIDE_AND_REPLACE_EXTENSION_BUNDLE)) + .booleanValue()) { String extensionBundleVersion = findExtensionBundleVersion(extensionBundleFile, extensionBundleBSN); if (extensionBundleFile.isDirectory()) { deleteDirectory(extensionBundleFile); @@ -247,7 +246,8 @@ private void generateExtensionBundle(File plugins, String extensionBundleBSN, St String packageExports = null; if (context.getMajorVersion() > 3) { - // we really have no idea what the packages or versions are, it all just a guess ... + // we really have no idea what the packages or versions are, it all just a guess + // ... String servletVersion = context.getMajorVersion() + "." + context.getMinorVersion(); //$NON-NLS-1$ packageExports = "org.eclipse.equinox.servletbridge; version=1.1" + //$NON-NLS-1$ ", javax.servlet; version=" + servletVersion + //$NON-NLS-1$ @@ -257,7 +257,8 @@ private void generateExtensionBundle(File plugins, String extensionBundleBSN, St ", javax.servlet.resources; version=" + servletVersion; //$NON-NLS-1$ } else if (context.getMajorVersion() == 3) { // We know spec version 3.0 corresponds to package version 2.6 - // we are guessing future 3.x spec versions will increment package versions minor, so ... + // we are guessing future 3.x spec versions will increment package versions + // minor, so ... String servletVersion = (context.getMajorVersion() - 1) + "." + (context.getMinorVersion() + 6); //$NON-NLS-1$ String specVersion = context.getMajorVersion() + "." + context.getMinorVersion(); //$NON-NLS-1$ packageExports = "org.eclipse.equinox.servletbridge; version=1.1" + //$NON-NLS-1$ @@ -324,10 +325,11 @@ private Manifest readJarFile(File jarFile) { return null; } - /** undeploy is the reverse operation of deploy and removes the OSGi framework libraries from their - * execution location. Typically this method will only be called if a manual undeploy is requested in the - * ServletBridge. - * By default, this method removes the OSGi install and also removes the workspace. + /** + * undeploy is the reverse operation of deploy and removes the OSGi framework + * libraries from their execution location. Typically this method will only be + * called if a manual undeploy is requested in the ServletBridge. By default, + * this method removes the OSGi install and also removes the workspace. */ public synchronized void undeploy() { if (platformDirectory == null) { @@ -349,10 +351,11 @@ public synchronized void undeploy() { platformDirectory = null; } - /** start is used to "start" a previously deployed OSGi framework - * The default behavior will read launcher.ini to create a set of initial properties and - * use the "commandline" configuration parameter to create the equivalent command line arguments - * available when starting Eclipse. + /** + * start is used to "start" a previously deployed OSGi framework The default + * behavior will read launcher.ini to create a set of initial properties and use + * the "commandline" configuration parameter to create the equivalent command + * line arguments available when starting Eclipse. */ public synchronized void start() { if (platformDirectory == null) @@ -490,14 +493,17 @@ private URL findExtensionURL(String extension, File osgiFrameworkFile) { try { return extensionFile.toURL(); } catch (MalformedURLException e) { - throw new RuntimeException("Could not find framework extension -- " + extensionFile.getAbsolutePath() + " : " + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$ + throw new RuntimeException("Could not find framework extension -- " + extensionFile.getAbsolutePath() //$NON-NLS-1$ + + " : " + e.getMessage()); //$NON-NLS-1$ } } - private void registerRestartHandler(Class starterClazz) throws IllegalAccessException, InvocationTargetException { + private void registerRestartHandler(Class starterClazz) + throws IllegalAccessException, InvocationTargetException { Method registerFrameworkShutdownHandler = null; try { - registerFrameworkShutdownHandler = starterClazz.getDeclaredMethod("internalAddFrameworkShutdownHandler", Runnable.class); //$NON-NLS-1$ + registerFrameworkShutdownHandler = starterClazz.getDeclaredMethod("internalAddFrameworkShutdownHandler", //$NON-NLS-1$ + Runnable.class); if (!registerFrameworkShutdownHandler.isAccessible()) { registerFrameworkShutdownHandler.setAccessible(true); } @@ -505,7 +511,8 @@ private void registerRestartHandler(Class starterClazz) throws IllegalAccessE registerFrameworkShutdownHandler.invoke(null, restartHandler); } catch (NoSuchMethodException e) { // Ok. However we will not support restart events. Log this as info - context.log(starterClazz.getName() + " does not support setting a shutdown handler. Restart handling is disabled."); //$NON-NLS-1$ + context.log(starterClazz.getName() + + " does not support setting a shutdown handler. Restart handling is disabled."); //$NON-NLS-1$ return; } @@ -538,9 +545,12 @@ public void run() { return restartHandler; } - /** buildInitialPropertyMap create the initial set of properties from the contents of launch.ini - * and for a few other properties necessary to launch defaults are supplied if not provided. - * The value '@null' will set the map value to null. + /** + * buildInitialPropertyMap create the initial set of properties from the + * contents of launch.ini and for a few other properties necessary to launch + * defaults are supplied if not provided. The value '@null' will set the map + * value to null. + * * @return a map containing the initial properties */ @SuppressWarnings("rawtypes") @@ -651,7 +661,8 @@ private Properties loadConfigurationFile(Map initialPropertyMap) } /** - * clearPrefixedSystemProperties clears System Properties by writing null properties in the targetPropertyMap that match a prefix + * clearPrefixedSystemProperties clears System Properties by writing null + * properties in the targetPropertyMap that match a prefix */ private static void clearPrefixedSystemProperties(String prefix, Map targetPropertyMap) { for (Object key : System.getProperties().keySet()) { @@ -663,7 +674,9 @@ private static void clearPrefixedSystemProperties(String prefix, Map than directory without version suffix + String version = ""; //$NON-NLS-1$ // Note: directory with version suffix is always > than directory + // without version suffix int index = name.indexOf('_'); if (index != -1) version = name.substring(index + 1); @@ -915,12 +939,11 @@ protected int findMax(String[] candidates) { /** * Compares version strings. + * * @param left * @param right - * @return result of comparison, as integer; - * <0 if left < right; - * 0 if left == right; - * >0 if left > right; + * @return result of comparison, as integer; <0 if left < right; + * 0 if left == right; >0 if left > right; */ private int compareVersion(Object[] left, Object[] right) { @@ -940,18 +963,20 @@ private int compareVersion(Object[] left, Object[] right) { } /** - * Do a quick parse of version identifier so its elements can be correctly compared. - * If we are unable to parse the full version, remaining elements are initialized - * with suitable defaults. + * Do a quick parse of version identifier so its elements can be correctly + * compared. If we are unable to parse the full version, remaining elements are + * initialized with suitable defaults. + * * @param version - * @return an array of size 4; first three elements are of type Integer (representing - * major, minor and service) and the fourth element is of type String (representing - * qualifier). Note, that returning anything else will cause exceptions in the caller. + * @return an array of size 4; first three elements are of type Integer + * (representing major, minor and service) and the fourth element is of + * type String (representing qualifier). Note, that returning anything + * else will cause exceptions in the caller. */ private Object[] getVersionElements(String version) { if (version.endsWith(DOT_JAR)) version = version.substring(0, version.length() - 4); - Object[] result = {Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0), ""}; //$NON-NLS-1$ + Object[] result = { Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0), "" }; //$NON-NLS-1$ StringTokenizer t = new StringTokenizer(version, "."); //$NON-NLS-1$ String token; int i = 0; @@ -974,9 +999,10 @@ private Object[] getVersionElements(String version) { } /** - * The ChildFirstURLClassLoader alters regular ClassLoader delegation and will check the URLs - * used in its initialization for matching classes before delegating to it's parent. - * Sometimes also referred to as a ParentLastClassLoader + * The ChildFirstURLClassLoader alters regular ClassLoader delegation and will + * check the URLs used in its initialization for matching classes before + * delegating to it's parent. Sometimes also referred to as a + * ParentLastClassLoader */ protected static class ChildFirstURLClassLoader extends CloseableURLClassLoader { private static final boolean CHILDFIRST_REGISTERED_AS_PARALLEL; @@ -984,7 +1010,8 @@ protected static class ChildFirstURLClassLoader extends CloseableURLClassLoader static { boolean registeredAsParallel; try { - Method parallelCapableMetod = ClassLoader.class.getDeclaredMethod("registerAsParallelCapable", (Class[]) null); //$NON-NLS-1$ + Method parallelCapableMetod = ClassLoader.class.getDeclaredMethod("registerAsParallelCapable", //$NON-NLS-1$ + (Class[]) null); parallelCapableMetod.setAccessible(true); registeredAsParallel = ((Boolean) parallelCapableMetod.invoke(null, (Object[]) null)).booleanValue(); } catch (Throwable e) {