Author: jacopoc Date: Mon Oct 20 16:13:33 2014 New Revision: 1633182 URL: http://svn.apache.org/r1633182 Log: Cleaned up the way the classloaders are setup at startup by removing duplicate logic and responsibilities between the start and base components.
Before this change the following classloader hierarchy was setup: 1) the "application" classloader for the "start" component 2) one "native lib" classloader for the "base" component 3) one "native lib" classloader for the all the other (non "base") framework/application/specialpurpose/hot-deploy components 4) one "web app" classloader for each of the webapplications After this commit the hierarchy is simplified by merging #2 and #3: a) the "application" classloader for the "start" component b) one "native lib" classloader for the all the framework/application/specialpurpose/hot-deploy components (including the "base" component) c) one "web app" classloader for each of the webapplications This has been achieved by merging the code that was setting up classloader #2 in the start component (for the "base" component) with the code that was setting up the classloader #3 in the base component: now all the code is in the start component. Modified: ofbiz/trunk/framework/base/ofbiz-component.xml ofbiz/trunk/framework/base/src/org/ofbiz/base/container/ComponentContainer.java ofbiz/trunk/framework/base/src/org/ofbiz/base/container/JustLoadComponentsContainer.java ofbiz/trunk/framework/start/src/org/ofbiz/base/start/Config.java ofbiz/trunk/framework/start/src/org/ofbiz/base/start/Start.java Modified: ofbiz/trunk/framework/base/ofbiz-component.xml URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/ofbiz-component.xml?rev=1633182&r1=1633181&r2=1633182&view=diff ============================================================================== --- ofbiz/trunk/framework/base/ofbiz-component.xml (original) +++ ofbiz/trunk/framework/base/ofbiz-component.xml Mon Oct 20 16:13:33 2014 @@ -22,9 +22,14 @@ under the License. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/ofbiz-component.xsd"> <resource-loader name="main" type="component"/> + <classpath type="dir" location="dtd"/> <classpath type="jar" location="build/lib/*"/> <classpath type="dir" location="config"/> <classpath type="jar" location="lib/*"/> + <classpath type="jar" location="lib/ant/*"/> + <classpath type="jar" location="lib/commons/*"/> + <classpath type="jar" location="lib/j2eespecs/*"/> + <classpath type="jar" location="lib/scripting/*"/> <test-suite loader="main" location="testdef/basetests.xml"/> Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/container/ComponentContainer.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/container/ComponentContainer.java?rev=1633182&r1=1633181&r2=1633182&view=diff ============================================================================== --- ofbiz/trunk/framework/base/src/org/ofbiz/base/container/ComponentContainer.java (original) +++ ofbiz/trunk/framework/base/src/org/ofbiz/base/container/ComponentContainer.java Mon Oct 20 16:13:33 2014 @@ -46,14 +46,9 @@ public class ComponentContainer implemen public static final String module = ComponentContainer.class.getName(); - //protected static List loadedComponents2 = null; - protected Classpath classPath = new Classpath(); - protected Classpath libraryPath = new Classpath(System.getProperty("java.library.path")); protected String configFileLocation = null; private String name; private boolean loaded = false; - private String instrumenterClassName; - private String instrumenterFile; @Override public void init(String[] args, String name, String configFile) throws ContainerException { @@ -69,25 +64,9 @@ public class ComponentContainer implemen loaderConfig = cc.getProperty("loader-config").value; } - // check for en override update classpath - boolean updateClassPath = true; - if (cc.getProperty("update-classpath") != null) { - updateClassPath = "true".equalsIgnoreCase(cc.getProperty("update-classpath").value); - } - if (cc.getProperty("ofbiz.instrumenterClassName") != null) { - instrumenterClassName = cc.getProperty("ofbiz.instrumenterClassName").value; - } else { - instrumenterClassName = null; - } - if (cc.getProperty("ofbiz.instrumenterFile") != null) { - instrumenterFile = cc.getProperty("ofbiz.instrumenterFile").value; - } else { - instrumenterFile = null; - } - // load the components try { - loadComponents(loaderConfig, updateClassPath, instrumenterClassName, instrumenterFile); + loadComponents(loaderConfig); } catch (AlreadyLoadedException e) { throw new ContainerException(e); } catch (ComponentException e) { @@ -102,10 +81,8 @@ public class ComponentContainer implemen return true; } - public synchronized void loadComponents(String loaderConfig, boolean updateClasspath, String instrumenterClassName, String instrumenterFile) throws AlreadyLoadedException, ComponentException { + public synchronized void loadComponents(String loaderConfig) throws AlreadyLoadedException, ComponentException { // set the loaded list; and fail if already loaded - //if (loadedComponents == null) { - // loadedComponents = new LinkedList(); if (!loaded) { loaded = true; } else { @@ -129,18 +106,6 @@ public class ComponentContainer implemen this.loadComponentFromConfig(parentPath, def); } } - - // set the new classloader/classpath on the current thread - if (updateClasspath) { - if (UtilValidate.isNotEmpty(instrumenterFile) && UtilValidate.isNotEmpty(instrumenterClassName)) { - classPath.instrument(instrumenterFile, instrumenterClassName); - } - - System.setProperty("java.library.path", libraryPath.toString()); - ClassLoader cl = classPath.getClassLoader(); - Thread.currentThread().setContextClassLoader(cl); - } - Debug.logInfo("All components loaded", module); } @@ -229,67 +194,10 @@ public class ComponentContainer implemen private void loadComponent(ComponentConfig config) { // make sure the component is enabled if (!config.enabled()) { - Debug.logInfo("Not Loading component : [" + config.getComponentName() + "] (disabled)", module); + Debug.logInfo("Not Loaded component : [" + config.getComponentName() + "] (disabled)", module); return; } - - Debug.logInfo("Loading component : [" + config.getComponentName() + "]", module); - boolean isBaseComponent = "base".equals(config.getComponentName()); - List<ComponentConfig.ClasspathInfo> classpathInfos = config.getClasspathInfos(); - String configRoot = config.getRootLocation(); - configRoot = configRoot.replace('\\', '/'); - // set the root to have a trailing slash - if (!configRoot.endsWith("/")) { - configRoot = configRoot + "/"; - } - if (classpathInfos != null) { - String nativeLibExt = System.mapLibraryName("someLib").replace("someLib", "").toLowerCase(); - for (ComponentConfig.ClasspathInfo cp: classpathInfos) { - String location = cp.location.replace('\\', '/'); - // set the location to not have a leading slash - if (location.startsWith("/")) { - location = location.substring(1); - } - if (!"jar".equals(cp.type) && !"dir".equals(cp.type)) { - Debug.logError("Classpath type '" + cp.type + "' is not supported; '" + location + "' not loaded", module); - continue; - } - String dirLoc = location; - if (dirLoc.endsWith("/*")) { - // strip off the slash splat - dirLoc = location.substring(0, location.length() - 2); - } - File path = FileUtil.getFile(configRoot + dirLoc); - if (path.exists()) { - if (path.isDirectory()) { - if ("dir".equals(cp.type)) { - if (!isBaseComponent) - classPath.addComponent(configRoot + location); - } - // load all .jar, .zip files and native libs in this directory - boolean containsNativeLibs = false; - for (File file: path.listFiles()) { - String fileName = file.getName().toLowerCase(); - if (fileName.endsWith(".jar") || fileName.endsWith(".zip")) { - if (!isBaseComponent) - classPath.addComponent(file); - } else if (fileName.endsWith(nativeLibExt)) { - containsNativeLibs = true; - } - } - if (containsNativeLibs) { - libraryPath.addComponent(path); - } - } else { - // add a single file - if (!isBaseComponent) - classPath.addComponent(configRoot + location); - } - } else { - Debug.logWarning("Location '" + configRoot + dirLoc + "' does not exist", module); - } - } - } + Debug.logInfo("Loaded component : [" + config.getComponentName() + "]", module); } /** Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/container/JustLoadComponentsContainer.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/container/JustLoadComponentsContainer.java?rev=1633182&r1=1633181&r2=1633182&view=diff ============================================================================== --- ofbiz/trunk/framework/base/src/org/ofbiz/base/container/JustLoadComponentsContainer.java (original) +++ ofbiz/trunk/framework/base/src/org/ofbiz/base/container/JustLoadComponentsContainer.java Mon Oct 20 16:13:33 2014 @@ -36,7 +36,7 @@ public class JustLoadComponentsContainer this.name = name; try { ComponentContainer cc = new ComponentContainer(); - cc.loadComponents(null, true, null, null); + cc.loadComponents(null); } catch (AlreadyLoadedException e) { Debug.logError(e, module); } catch (ComponentException e) { Modified: ofbiz/trunk/framework/start/src/org/ofbiz/base/start/Config.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/start/src/org/ofbiz/base/start/Config.java?rev=1633182&r1=1633181&r2=1633182&view=diff ============================================================================== --- ofbiz/trunk/framework/start/src/org/ofbiz/base/start/Config.java (original) +++ ofbiz/trunk/framework/start/src/org/ofbiz/base/start/Config.java Mon Oct 20 16:13:33 2014 @@ -18,7 +18,18 @@ *******************************************************************************/ package org.ofbiz.base.start; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; import java.io.File; +import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; @@ -291,47 +302,118 @@ public class Config { return props; } - void initClasspath(Classpath classPath) throws IOException { + void initClasspath(Classpath classPath, Classpath libraryPath) throws Exception { // add OFBIZ_HOME to class path classPath.addClasspath(this.ofbizHome); - - // load all the resources from the framework base component - // load all the jars from the base lib directory - if (this.baseLib != null) { - loadLibs(classPath, this.baseLib, true); - } - // load the ofbiz-base.jar and the ofbiz-base-test.jar - if (this.baseJar != null) { - classPath.addComponent(this.baseJar); - classPath.addComponent(this.baseJar.substring(0, this.baseJar.indexOf(".jar")) + "-test.jar"); - } - // load the base schema directory - if (this.baseDtd != null) { - classPath.addComponent(this.baseDtd); - } - // load the config directory - if (this.baseConfig != null) { - classPath.addComponent(this.baseConfig); - } + File home = new File(this.ofbizHome); + collectClasspathEntries(new File(home, "framework"), classPath, libraryPath); + collectClasspathEntries(new File(home, "applications"), classPath, libraryPath); + collectClasspathEntries(new File(home, "specialpurpose"), classPath, libraryPath); + collectClasspathEntries(new File(home, "hot-deploy"), classPath, libraryPath); + System.setProperty("java.library.path", libraryPath.toString()); classPath.instrument(this.instrumenterFile, this.instrumenterClassName); } - private void loadLibs(Classpath classPath, String path, boolean recurse) throws IOException { - File libDir = new File(path); - if (libDir.exists()) { - File files[] = libDir.listFiles(); - for (File file: files) { - String fileName = file.getName(); - if (file.isHidden()) { + private void collectClasspathEntries(File folder, Classpath classpath, Classpath libraryPath) throws ParserConfigurationException, IOException, SAXException { + if (!folder.exists() && !folder.isDirectory()) { + return; + } + FileFilter componentLoadFilter = new FileFilter() { + public boolean accept(File pathname) { + return "component-load.xml".equals(pathname.getName()); + } + }; + FileFilter folderFilter = new FileFilter() { + public boolean accept(File pathname) { + return pathname.isDirectory(); + } + }; + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + File[] componentLoadFiles; + List<File> ofbizComponents = new ArrayList<File>(); + componentLoadFiles = folder.listFiles(componentLoadFilter); + if (componentLoadFiles != null && componentLoadFiles.length == 1) { + File componentLoadFile = componentLoadFiles[0]; + // parse and get folder names to be processed + Document document = builder.parse(componentLoadFile); + Element element = document.getDocumentElement(); + NodeList loadComponents = element.getElementsByTagName("load-component"); + for (int i = 0; i < loadComponents.getLength(); i++) { + Node loadComponent = loadComponents.item(i); + NamedNodeMap attributes = loadComponent.getAttributes(); + Node componentLocation = attributes.getNamedItem("component-location"); + if (componentLocation == null) { + continue; + } + ofbizComponents.add(new File(new File(folder, componentLocation.getNodeValue()), "ofbiz-component.xml")); + } + } else { + File[] componentFolders = folder.listFiles(folderFilter); + for (File componentFolder: componentFolders) { + File ofbizComponent = new File(componentFolder, "ofbiz-component.xml"); + if (ofbizComponent.exists()) { + ofbizComponents.add(ofbizComponent); + } + } + } + String nativeLibExt = System.mapLibraryName("someLib").replace("someLib", "").toLowerCase(); + for (File ofbizComponent: ofbizComponents) { + Document document = builder.parse(ofbizComponent); + Element element = document.getDocumentElement(); + if (element.hasAttribute("enabled")) { + if ("false".equals(element.getAttribute("enabled"))) { continue; } - // FIXME: filter out other files? - if (file.isDirectory() && !"CVS".equals(fileName) && !".svn".equals(fileName) && recurse) { - loadLibs(classPath, file.getCanonicalPath(), recurse); - } else if (fileName.endsWith(".jar") || fileName.endsWith(".zip")) { - classPath.addComponent(file); + } + NodeList classpathEntries = element.getElementsByTagName("classpath"); + for (int i = 0; i < classpathEntries.getLength(); i++) { + Node classpathEntry = classpathEntries.item(i); + NamedNodeMap attributes = classpathEntry.getAttributes(); + Node type = attributes.getNamedItem("type"); + if (type == null || !("jar".equals(type.getNodeValue()) || "dir".equals(type.getNodeValue()))) { + continue; + } + Node location = attributes.getNamedItem("location"); + String locationValue = location.getNodeValue(); + locationValue = locationValue.replace('\\', '/'); + // set the location to not have a leading slash + if (locationValue.startsWith("/")) { + locationValue = locationValue.substring(1); + } + String dirLoc = locationValue; + if (dirLoc.endsWith("/*")) { + // strip off the slash splat + dirLoc = locationValue.substring(0, locationValue.length() - 2); + } + + String fileNameSeparator = ("\\".equals(File.separator) ? "\\" + File.separator : File.separator); + dirLoc = dirLoc.replaceAll("/+|\\\\+", fileNameSeparator); + File path = new File(ofbizComponent.getParent(), dirLoc); + if (path.exists()) { + if (path.isDirectory()) { + if ("dir".equals(type.getNodeValue())) { + classpath.addComponent(path.toString()); + } + // load all .jar, .zip files and native libs in this directory + boolean containsNativeLibs = false; + for (File file: path.listFiles()) { + String fileName = file.getName().toLowerCase(); + if (fileName.endsWith(".jar") || fileName.endsWith(".zip")) { + classpath.addComponent(file); + } else if (fileName.endsWith(nativeLibExt)) { + containsNativeLibs = true; + } + } + if (containsNativeLibs) { + libraryPath.addComponent(path); + } + } else { + classpath.addComponent(path.toString()); + } } } } } + } Modified: ofbiz/trunk/framework/start/src/org/ofbiz/base/start/Start.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/start/src/org/ofbiz/base/start/Start.java?rev=1633182&r1=1633181&r2=1633182&view=diff ============================================================================== --- ofbiz/trunk/framework/start/src/org/ofbiz/base/start/Start.java (original) +++ ofbiz/trunk/framework/start/src/org/ofbiz/base/start/Start.java Mon Oct 20 16:13:33 2014 @@ -241,9 +241,10 @@ public final class Start { private void initStartLoaders() throws StartupException { Classpath classPath = new Classpath(); + Classpath libraryPath = new Classpath(System.getProperty("java.library.path")); try { - this.config.initClasspath(classPath); - } catch (IOException e) { + this.config.initClasspath(classPath, libraryPath); + } catch (Exception e) { throw (StartupException) new StartupException("Couldn't initialized classpath").initCause(e); } ClassLoader classloader = classPath.getClassLoader();