Return-Path: Delivered-To: apmail-geronimo-scm-archive@www.apache.org Received: (qmail 16322 invoked from network); 18 Mar 2009 07:07:45 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 18 Mar 2009 07:07:45 -0000 Received: (qmail 66172 invoked by uid 500); 18 Mar 2009 07:07:45 -0000 Delivered-To: apmail-geronimo-scm-archive@geronimo.apache.org Received: (qmail 66131 invoked by uid 500); 18 Mar 2009 07:07:45 -0000 Mailing-List: contact scm-help@geronimo.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: dev@geronimo.apache.org List-Id: Delivered-To: mailing list scm@geronimo.apache.org Received: (qmail 66122 invoked by uid 99); 18 Mar 2009 07:07:44 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 18 Mar 2009 00:07:44 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 18 Mar 2009 07:07:42 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 3980B2388B05; Wed, 18 Mar 2009 07:07:22 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r755494 [4/5] - in /geronimo/sandbox/djencks/framework: ./ buildsupport/car-maven-plugin/src/main/java/org/apache/geronimo/mavenplugins/car/ configs/client-system/src/main/plan/ configs/geronimo-gbean-deployer/src/it/j2ee-system-2/src/main/... Date: Wed, 18 Mar 2009 07:07:19 -0000 To: scm@geronimo.apache.org From: djencks@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20090318070722.3980B2388B05@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Modified: geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/Configuration.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/Configuration.java?rev=755494&r1=755493&r2=755494&view=diff ============================================================================== --- geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/Configuration.java (original) +++ geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/Configuration.java Wed Mar 18 07:07:17 2009 @@ -19,18 +19,13 @@ import java.io.File; import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; -import java.util.ListIterator; import java.util.Map; import java.util.Set; @@ -40,21 +35,15 @@ import org.apache.geronimo.gbean.AbstractName; import org.apache.geronimo.gbean.AbstractNameQuery; import org.apache.geronimo.gbean.GBeanData; -import org.apache.geronimo.gbean.GBeanInfo; -import org.apache.geronimo.gbean.GBeanInfoBuilder; import org.apache.geronimo.gbean.GBeanLifecycle; import org.apache.geronimo.gbean.ReferencePatterns; +import org.apache.geronimo.gbean.annotation.GBean; +import org.apache.geronimo.gbean.annotation.ParamAttribute; import org.apache.geronimo.kernel.GBeanAlreadyExistsException; import org.apache.geronimo.kernel.GBeanNotFoundException; import org.apache.geronimo.kernel.Naming; -import org.apache.geronimo.kernel.classloader.JarFileClassLoader; import org.apache.geronimo.kernel.repository.Artifact; -import org.apache.geronimo.kernel.repository.ClassLoadingRule; -import org.apache.geronimo.kernel.repository.ClassLoadingRules; -import org.apache.geronimo.kernel.repository.Dependency; import org.apache.geronimo.kernel.repository.Environment; -import org.apache.geronimo.kernel.repository.ImportType; -import org.apache.geronimo.kernel.repository.MissingDependencyException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -87,14 +76,18 @@ * * @version $Rev:385718 $ $Date$ */ -public class Configuration implements GBeanLifecycle, ConfigurationParent -{ + +@GBean +public class Configuration implements GBeanLifecycle, ConfigurationParent { private static final Logger log = LoggerFactory.getLogger(Configuration.class); /** * Converts an Artifact to an AbstractName for a configuration. Does not * validate that this is a reasonable or resolved Artifact, or that it * corresponds to an actual Configuration. + * @param configId id for configuration + * @return abstract name constructed from supplied id + * @throws InvalidConfigException if the ObjectName could not be constructed */ public static AbstractName getConfigurationAbstractName(Artifact configId) throws InvalidConfigException { return new AbstractName(configId, Collections.singletonMap("configurationName", configId.toString()), getConfigurationObjectName(configId)); @@ -122,19 +115,14 @@ } /** - * The artifact id for this configuration. - */ - private final Artifact id; - - /** * The registered abstractName for this configuraion. */ private final AbstractName abstractName; /** - * Defines the environment requred for this configuration. + * Supplies classloader(s) for this configuration */ - private final Environment environment; + private final ClassLoaderHolder classLoaderHolder; /** * Used to resolve dependecies and paths @@ -142,24 +130,14 @@ private final ConfigurationResolver configurationResolver; /** - * Parent configurations used for class loader. - */ - private final List classParents = new ArrayList(); - - /** - * Parent configuations used for service resolution. + * Contains ids of class and service dependencies for parent configurations */ - private final List serviceParents = new ArrayList(); + private final DependencyNode dependencyNode; /** * All service parents depth first */ - private final List allServiceParents = new ArrayList(); - - /** - * Artifacts added to the class loader (non-configuation artifacts). - */ - private final LinkedHashSet dependencies = new LinkedHashSet(); + private final List allServiceParents; /** * The GBeanData objects by ObjectName @@ -167,21 +145,6 @@ private final Map gbeans = new LinkedHashMap(); /** - * The classloader used to load the child GBeans contained in this configuration. - */ - private final MultiParentClassLoader configurationClassLoader; - - /** - * The ClassLoader used by children configurations. - */ - private final ClassLoader childrenConfigurationClassLoader; - - /** - * The relative class path (URI) of this configuation. - */ - private final LinkedHashSet classPath; - - /** * Naming system used when generating a name for a new gbean */ private final Naming naming; @@ -189,257 +152,102 @@ /** * Environment, classpath, gbeans and other data for this configuration. */ - private ConfigurationData configurationData; + private final ConfigurationData configurationData; /** * The nested configurations of this configuration. */ - List children = new ArrayList(); + private final List children = new ArrayList(); /** - * The parent of this configuration; + * The enclosing parent of this configuration (e.g. if this is for a war file, an enclosing ear file's configuration); */ private Configuration parent = null; - + /** * Manageable Attribute Store containing overrides to this configuration. */ private ManageableAttributeStore attributeStore = null; /** - * Only used to allow declaration as a reference. - */ - public Configuration() { - id = null; - abstractName = null; - environment = null; - classPath = null; - configurationResolver = null; - configurationClassLoader = null; - childrenConfigurationClassLoader = null; - naming = null; - } - - /** * Creates a configuration. - * @param parents parents of this configuation (not ordered) + * + * @param classLoaderHolder Classloaders for this configuration * @param configurationData the module type, environment and classpath of the configuration - * @param configurationResolver used to resolve dependecies and paths - */ - public Configuration(Collection parents, - ConfigurationData configurationData, - ConfigurationResolver configurationResolver, - ManageableAttributeStore attributeStore) throws MissingDependencyException, MalformedURLException, NoSuchConfigException, InvalidConfigException { - if (parents == null) parents = Collections.EMPTY_SET; + * @param dependencyNode Class and Service parent ids + * @param allServiceParents ordered list of transitive closure of service parents for gbean searches + * @param attributeStore Customization info for gbeans + * @param configurationResolver (there should be a better way) Where this configuration is actually located in file system + * @throws InvalidConfigException if this configuration turns out to have a problem. + */ + public Configuration( + @ParamAttribute(name = "classLoaderHolder") ClassLoaderHolder classLoaderHolder, + @ParamAttribute(name = "configurationData") ConfigurationData configurationData, + @ParamAttribute(name = "dependencyNode") DependencyNode dependencyNode, + @ParamAttribute(name = "allServiceParents") List allServiceParents, + @ParamAttribute(name = "attributeStore") ManageableAttributeStore attributeStore, + @ParamAttribute(name = "configurationResolver") ConfigurationResolver configurationResolver) throws InvalidConfigException { + if (classLoaderHolder == null) throw new NullPointerException("classLoaders are null"); if (configurationData == null) throw new NullPointerException("configurationData is null"); - if (configurationResolver == null) throw new NullPointerException("configurationResolver is null"); + this.classLoaderHolder = classLoaderHolder; this.configurationData = configurationData; - this.environment = configurationData.getEnvironment(); - this.configurationResolver = configurationResolver; - this.classPath = new LinkedHashSet(configurationData.getClassPath()); this.naming = configurationData.getNaming(); this.attributeStore = attributeStore; - this.id = environment.getConfigId(); - abstractName = getConfigurationAbstractName(id); - - // - // Transitively resolve all the dependencies in the environment - // - List transitiveDependencies = configurationResolver.resolveTransitiveDependencies(parents, environment.getDependencies()); - - // - // Process transtive dependencies splitting it into classParents, serviceParents and artifactDependencies - // - Map parentsById = new HashMap(); - for (Configuration configuration : parents) { - Artifact id = configuration.getId(); - parentsById.put(id, configuration); - } - - for (Dependency dependency : transitiveDependencies) { - Artifact artifact = dependency.getArtifact(); - if (parentsById.containsKey(artifact)) { - Configuration parent = parentsById.get(artifact); - if (dependency.getImportType() == ImportType.CLASSES || dependency.getImportType() == ImportType.ALL) { - classParents.add(parent); - } - if (dependency.getImportType() == ImportType.SERVICES || dependency.getImportType() == ImportType.ALL) { - serviceParents.add(parent); - } - } else if (dependency.getImportType() == ImportType.SERVICES) { - throw new IllegalStateException("Could not find parent " + artifact + " in the parents collection"); - } else { - dependencies.add(artifact); - } - } + this.dependencyNode = dependencyNode; + this.allServiceParents = allServiceParents; + this.configurationResolver = configurationResolver; + abstractName = getConfigurationAbstractName(dependencyNode.getId()); try { - // - // Build the configuration class loader - // - configurationClassLoader = createConfigurationClasssLoader(parents, environment, classPath); - - ClassLoadingRules rules = environment.getClassLoadingRules(); - childrenConfigurationClassLoader = new ChildrenConfigurationClassLoader(configurationClassLoader, rules); - - // - // Get all service parents in depth first order - // - addDepthFirstServiceParents(this, allServiceParents, new HashSet()); - - // // Deserialize the GBeans in the configurationData - // - Collection gbeans = configurationData.getGBeans(configurationClassLoader); + Collection gbeans = configurationData.getGBeans(classLoaderHolder.getInternalClassLoader()); if (attributeStore != null) { - gbeans = attributeStore.applyOverrides(id, gbeans, configurationClassLoader); + gbeans = attributeStore.applyOverrides(dependencyNode.getId(), gbeans, classLoaderHolder.getInternalClassLoader()); } for (GBeanData gbeanData : gbeans) { this.gbeans.put(gbeanData.getAbstractName(), gbeanData); } - // - // Create child configurations - // - LinkedHashSet childParents = new LinkedHashSet(parents); - childParents.add(this); - for (Iterator iterator = configurationData.getChildConfigurations().entrySet().iterator(); iterator.hasNext();) { - Map.Entry entry = (Map.Entry) iterator.next(); - String moduleName = (String) entry.getKey(); - ConfigurationData childConfigurationData = (ConfigurationData) entry.getValue(); - Configuration childConfiguration = new Configuration(childParents, childConfigurationData, configurationResolver.createChildResolver(moduleName), attributeStore); - childConfiguration.parent = this; - children.add(childConfiguration); - } } catch (RuntimeException e) { shutdown(); throw e; } catch (Error e) { shutdown(); throw e; - } catch (MissingDependencyException e) { - shutdown(); - throw e; - } catch (MalformedURLException e) { - shutdown(); - throw e; - } catch (NoSuchConfigException e) { - shutdown(); - throw e; } catch (InvalidConfigException e) { shutdown(); throw e; } } - private MultiParentClassLoader createConfigurationClasssLoader(Collection parents, Environment environment, LinkedHashSet classPath) throws MalformedURLException, MissingDependencyException, NoSuchConfigException { - // create the URL list - URL[] urls = buildClassPath(classPath); - - // parents - List parentClassLoaders; - if (parents.size() == 0 && classParents.size() == 0) { - // no explicit parent set, so use the class loader of this class as - // the parent... this class should be in the root geronimo classloader, - // which is normally the system class loader but not always, so be safe - parentClassLoaders = Collections.singletonList(getClass().getClassLoader()); - } else { - parentClassLoaders = new ArrayList(classParents.size()); - for (Configuration configuration : classParents) { - parentClassLoaders.add(configuration.childrenConfigurationClassLoader); - } - } - - // we need to propagate the non-overrideable classes from parents - ClassLoadingRules classLoadingRules = environment.getClassLoadingRules(); - ClassLoadingRule nonOverrideableRule = classLoadingRules.getNonOverrideableRule(); - for (Configuration parent : classParents) { - Environment parentEnvironment = parent.getEnvironment(); - ClassLoadingRules parentClassLoadingRules = parentEnvironment.getClassLoadingRules(); - ClassLoadingRule parentNonOverrideableRule = parentClassLoadingRules.getNonOverrideableRule(); - nonOverrideableRule.merge(parentNonOverrideableRule); - } - - if (log.isDebugEnabled()) { - StringBuffer buf = new StringBuffer("ClassLoader structure for configuration ").append(id).append("\n"); - buf.append("Parent configurations:\n"); - for (Configuration configuration : classParents) { - buf.append(" ").append(configuration.getId()).append("\n"); - } - buf.append("ClassPath:\n"); - for (URL url : urls) { - buf.append(" ").append(url).append("\n"); - } - log.debug(buf.toString()); - } - - // The JarFileClassLoader was created to address a locking problem seen only on Windows platforms. - // It carries with it a slight performance penalty that needs to be addressed. Rather than make - // *nix OSes carry this burden we'll engage the JarFileClassLoader for Windows or if the user - // specifically requests it. We'll look more at this issue in the future. - boolean useJarFileClassLoader = false; - if (System.getProperty("Xorg.apache.geronimo.JarFileClassLoader") == null) { - useJarFileClassLoader = System.getProperty("os.name").startsWith("Windows"); - } else { - useJarFileClassLoader = Boolean.getBoolean("Xorg.apache.geronimo.JarFileClassLoader"); - } - if (useJarFileClassLoader) { - return new JarFileClassLoader(environment.getConfigId(), - urls, - parentClassLoaders, - classLoadingRules); - } else { - return new MultiParentClassLoader(environment.getConfigId(), - urls, - parentClassLoaders, - classLoadingRules); - } - } - - private void addDepthFirstServiceParents(Configuration configuration, List ancestors, Set ids) { - if (!ids.contains(configuration.getId())) { - ancestors.add(configuration); - ids.add(configuration.getId()); - for (Configuration parent : configuration.getServiceParents()) { - addDepthFirstServiceParents(parent, ancestors, ids); - } - } - } - - private URL[] buildClassPath(LinkedHashSet classPath) throws MalformedURLException, MissingDependencyException, NoSuchConfigException { - List urls = new ArrayList(); - for (Artifact artifact : dependencies) { - File file = configurationResolver.resolve(artifact); - urls.add(file.toURL()); - } - if (classPath != null) { - for (String pattern : classPath) { - Set matches = configurationResolver.resolve(pattern); - for (URL url : matches) { - urls.add(url); - } - } - } - return urls.toArray(new URL[urls.size()]); + /** + * Add a contained configuration, such as for a war inside an ear + * @param child contained configuration + */ + void addChild(Configuration child) { + children.add(child); + child.parent = this; } /** * Return the unique Id + * * @return the unique Id */ public Artifact getId() { - return id; + return dependencyNode.getId(); } /** * Gets the unique name of this configuration within the kernel. + * * @return the unique name of this configuration */ public String getObjectName() { try { - return getConfigurationObjectName(id).getCanonicalName(); + return getConfigurationObjectName(getId()).getCanonicalName(); } catch (InvalidConfigException e) { throw new AssertionError(e); } @@ -449,41 +257,51 @@ return abstractName; } + public ClassLoaderHolder getClassLoaderHolder() { + return classLoaderHolder; + } + /** * Gets the parent configurations used for class loading. * @return the parents of this configuration used for class loading */ - public List getClassParents() { - return classParents; - } +// public List getClassParents() { +// return classParents; +// } /** * Gets the parent configurations used for service resolution. + * * @return the parents of this configuration used for service resolution */ - public List getServiceParents() { - return serviceParents; +// public List getServiceParents() { +// return serviceParents; +// } + public DependencyNode getDependencyNode() { + return dependencyNode; } /** * Gets the artifact dependencies of this configuration. * @return the artifact dependencies of this configuration */ - public LinkedHashSet getDependencies() { - return dependencies; - } +// public LinkedHashSet getDependencies() { +// return dependencies; +// } /** * Gets the declaration of the environment in which this configuration runs. + * * @return the environment of this configuration */ public Environment getEnvironment() { - return environment; + return configurationData.getEnvironment(); } /** * This is used by the configuration manager to restart an existing configuation. * Do not modify the configuration data. + * * @return the configuration data for this configuration; do not modify */ ConfigurationData getConfigurationData() { @@ -495,36 +313,16 @@ } /** - * @deprecated this is only exposed temporarily for configuration manager + * Provide a way to locate where this configuration is for web apps and persistence units + * @return the ConfigurationResolver for this configuration */ public ConfigurationResolver getConfigurationResolver() { return configurationResolver; } /** - * Gets the relative class path (URIs) of this configuration. - * @return the relative class path of this configuation - */ - public List getClassPath() { - return new ArrayList(classPath); - } - - public void addToClassPath(String pattern) throws IOException { - if (!classPath.contains(pattern)) { - try { - Set matches = configurationResolver.resolve(pattern); - for (URL url : matches) { - configurationClassLoader.addURL(url); - } - classPath.add(pattern); - } catch (Exception e) { - throw (IOException)new IOException("Unable to extend classpath with " + pattern).initCause(e); - } - } - } - - /** * Gets the type of the configuration (WAR, RAR et cetera) + * * @return Type of the configuration. */ public ConfigurationModuleType getModuleType() { @@ -533,6 +331,7 @@ /** * Gets the time at which this configuration was created (or deployed). + * * @return the time at which this configuration was created (or deployed) */ public long getCreated() { @@ -541,10 +340,12 @@ /** * Gets the class loader for this configuration. + * * @return the class loader for this configuration + * @deprecated use the impl instead */ public ClassLoader getConfigurationClassLoader() { - return configurationClassLoader; + return getClassLoaderHolder().getInternalClassLoader(); } /** @@ -552,7 +353,7 @@ * configurations within this one as a WAR can be within an EAR; not * including wholly separate configurations that just depend on this * one as a parent. - * + * * @return the nested configuration of this configuration */ public List getChildren() { @@ -561,6 +362,7 @@ /** * Gets the configurations owned by this configuration. This is only used for cascade-uninstall. + * * @return the configurations owned by this configuration */ public Set getOwnedConfigurations() { @@ -569,6 +371,7 @@ /** * Gets an unmodifiable collection of the GBeanDatas for the GBeans in this configuration. + * * @return the GBeans in this configuration */ public Map getGBeans() { @@ -577,6 +380,7 @@ /** * Determines of this configuration constains the specified GBean. + * * @param gbean the name of the GBean * @return true if this configuration contains the specified GBean; false otherwise */ @@ -587,19 +391,21 @@ /** * Gets the enclosing configuration of this one (e.g. the EAR for a WAR), * or null if it has none. + * * @return enclosing configuration, if any */ public Configuration getEnclosingConfiguration() { return parent; } - + /** * Gets the manageable attribute store for this configuration. * This is used in the configuration manager to apply overrides - * @return + * + * @return customization source for gbeans */ - ManageableAttributeStore getManageableAttributeStore(){ - return attributeStore; + ManageableAttributeStore getManageableAttributeStore() { + return attributeStore; } public synchronized AbstractName addGBean(String name, GBeanData gbean) throws GBeanAlreadyExistsException { @@ -610,7 +416,7 @@ String j2eeType = gbean.getGBeanInfo().getJ2eeType(); if (j2eeType == null) j2eeType = "GBean"; - abstractName = naming.createRootName(id, name, j2eeType); + abstractName = naming.createRootName(getId(), name, j2eeType); gbean.setAbstractName(abstractName); if (gbeans.containsKey(abstractName)) { @@ -666,7 +472,7 @@ if (result.size() > 1) { throw new GBeanNotFoundException("More than one match to referencePatterns in local configuration", patterns, mapToNames(result)); } else if (result.size() == 1) { - return (GBeanData) result.iterator().next(); + return result.iterator().next(); } // search all parents @@ -692,7 +498,7 @@ private Set mapToNames(Set datas) { Set names = new HashSet(datas.size()); - for (GBeanData gBeanData: datas) { + for (GBeanData gBeanData : datas) { names.add(gBeanData.getAbstractName()); } return names; @@ -744,7 +550,7 @@ * Find the gbeanDatas matching the patterns in this configuration only, ignoring parents. * * @param configuration configuration to look in - * @param patterns patterns to look for + * @param patterns patterns to look for * @return set of gbeandatas matching one of the patterns from this configuration only, not including parents. */ public LinkedHashSet findGBeanDatas(Configuration configuration, Set patterns) { @@ -771,17 +577,17 @@ } public void doStart() throws Exception { - log.debug("Started configuration {}", id); + log.debug("Started configuration {}", getId()); } public synchronized void doStop() throws Exception { - log.debug("Stopping configuration {}", id); + log.debug("Stopping configuration {}", getId()); shutdown(); } public void doFail() { - log.debug("Failed configuration {}", id); + log.debug("Failed configuration {}", getId()); shutdown(); } @@ -793,34 +599,7 @@ // clear references to GBeanDatas gbeans.clear(); - // destroy the class loader - if (configurationClassLoader != null) { - configurationClassLoader.destroy(); - } - } - - public static final GBeanInfo GBEAN_INFO; - - static { - GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(Configuration.class);//does not use jsr-77 naming - infoFactory.addReference("Parents", Configuration.class); - infoFactory.addAttribute("configurationData", ConfigurationData.class, true, false); - infoFactory.addAttribute("configurationResolver", ConfigurationResolver.class, true); - infoFactory.addAttribute("managedAttributeStore", ManageableAttributeStore.class, true); - - infoFactory.addInterface(Configuration.class); - - infoFactory.setConstructor(new String[]{ - "Parents", - "configurationData", - "configurationResolver", - "managedAttributeStore" - }); - - GBEAN_INFO = infoFactory.getBeanInfo(); + classLoaderHolder.destroy(); } - public static GBeanInfo getGBeanInfo() { - return GBEAN_INFO; - } } Modified: geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/ConfigurationData.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/ConfigurationData.java?rev=755494&r1=755493&r2=755494&view=diff ============================================================================== --- geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/ConfigurationData.java (original) +++ geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/ConfigurationData.java Wed Mar 18 07:07:17 2009 @@ -191,6 +191,12 @@ if (gbeanInfo == null) throw new NullPointerException("gbeanInfo is null"); return gbeanState.addGBean(name, gbeanInfo, naming, environment); } + + public GBeanData addGBean(String name, Class gbeanClass) { + if (name == null) throw new NullPointerException("name is null"); + if (gbeanClass == null) throw new NullPointerException("gbeanInfo is null"); + return gbeanState.addGBean(name, gbeanClass, naming, environment); + } public GBeanState getGbeanState() { return gbeanState; Modified: geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/ConfigurationManager.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/ConfigurationManager.java?rev=755494&r1=755493&r2=755494&view=diff ============================================================================== --- geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/ConfigurationManager.java (original) +++ geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/ConfigurationManager.java Wed Mar 18 07:07:17 2009 @@ -56,7 +56,7 @@ * * @version $Rev$ $Date$ */ -public interface ConfigurationManager { +public interface ConfigurationManager extends ConfigurationSource { /** * Is the specified configuration installed into the server * environment? That is, does it exist in the configuration store, @@ -145,7 +145,7 @@ * * @return a List>AbstractName< of the stores this manager controls */ - List listStores(); + List listStores(); /** * Get all the ConfigurationStores known to this manager at present @@ -195,7 +195,7 @@ * * @return the specified configuration or null if the configuration has not been loaded */ - Configuration getConfiguration(Artifact configurationId); +// Configuration getConfiguration(Artifact configurationId); /** * Load the specified configuration (from a config store) and all Added: geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/ConfigurationSource.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/ConfigurationSource.java?rev=755494&view=auto ============================================================================== --- geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/ConfigurationSource.java (added) +++ geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/ConfigurationSource.java Wed Mar 18 07:07:17 2009 @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +package org.apache.geronimo.kernel.config; + +import org.apache.geronimo.kernel.repository.Artifact; + +/** + * @version $Rev$ $Date$ + */ +public interface ConfigurationSource { + + /** + * Gets a loaded Configuration (does not see unloaded configurations). + * + * @param configurationId the unique ID of the configuration to get, which + * must be fully resolved (isResolved() == true) + * + * @return the specified configuration or null if the configuration has not been loaded + */ + Configuration getConfiguration(Artifact configurationId); + +} Propchange: geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/ConfigurationSource.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/ConfigurationSource.java ------------------------------------------------------------------------------ svn:keywords = Date Revision Propchange: geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/ConfigurationSource.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/ConfigurationUtil.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/ConfigurationUtil.java?rev=755494&r1=755493&r2=755494&view=diff ============================================================================== --- geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/ConfigurationUtil.java (original) +++ geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/ConfigurationUtil.java Wed Mar 18 07:07:17 2009 @@ -39,11 +39,11 @@ import org.slf4j.LoggerFactory; import org.apache.geronimo.gbean.AbstractName; import org.apache.geronimo.gbean.AbstractNameQuery; -import org.apache.geronimo.gbean.GAttributeInfo; import org.apache.geronimo.gbean.GBeanData; import org.apache.geronimo.gbean.GReferenceInfo; import org.apache.geronimo.gbean.InvalidConfigurationException; import org.apache.geronimo.gbean.ReferencePatterns; +import org.apache.geronimo.gbean.GAttributeInfo; import org.apache.geronimo.kernel.ClassLoading; import org.apache.geronimo.kernel.GBeanAlreadyExistsException; import org.apache.geronimo.kernel.GBeanNotFoundException; @@ -179,7 +179,7 @@ // build the gbean data Artifact configId = configurationData.getId(); AbstractName abstractName = Configuration.getConfigurationAbstractName(configId); - GBeanData gbeanData = new GBeanData(abstractName, Configuration.GBEAN_INFO); + GBeanData gbeanData = new GBeanData(abstractName, Configuration.class); gbeanData.setAttribute("configurationData", configurationData); Collection repositories = null; @@ -196,7 +196,17 @@ configurationData.getEnvironment().setDependencies(Collections.EMPTY_SET); } } - gbeanData.setAttribute("configurationResolver", new ConfigurationResolver(configurationData, repositories, artifactResolver)); + ConfigurationResolver configurationResolver = new ConfigurationResolver(configurationData, repositories, artifactResolver); + + DependencyNode dependencyNode = new DependencyNode(configId, new LinkedHashSet(), new LinkedHashSet()); + gbeanData.setAttribute("dependencyNode", dependencyNode); + JarFileClassLoaderFactory classLoaderFactory = new JarFileClassLoaderFactory(); + gbeanData.setAttribute("classLoaderHolder", classLoaderFactory.buildClassLoaders(Collections.emptyList(), + configurationData.getEnvironment(), + new LinkedHashSet(configurationData.getClassPath()), + configurationResolver));//buildClassLoaders(configurationData, loadedConfigurations, dependencyNode)); + gbeanData.setAttribute("allServiceParents", Collections.emptyList()); + // load and start the gbean kernel.loadGBean(gbeanData, classLoader); @@ -324,9 +334,9 @@ * @return The ConfigurationManager * @throws IllegalStateException Occurs if a ConfigurationManager cannot be identified */ - public static ConfigurationManager getConfigurationManager(Kernel kernel) { + public static ConfigurationManager getConfigurationManager(Kernel kernel) throws GBeanNotFoundException { AbstractName configurationManagerName = getConfigurationManagerName(kernel); - return (ConfigurationManager) kernel.getProxyManager().createProxy(configurationManagerName, ConfigurationManager.class); + return (ConfigurationManager) kernel.getGBean(configurationManagerName); } /** @@ -335,34 +345,33 @@ * @return The EdtiableConfigurationManager, or none if there is not one available. * @throws IllegalStateException Occurs if there are multiple EditableConfigurationManagers in the kernel. */ - public static EditableConfigurationManager getEditableConfigurationManager(Kernel kernel) { - Set names = kernel.listGBeans(new AbstractNameQuery(EditableConfigurationManager.class.getName())); - for (Iterator iterator = names.iterator(); iterator.hasNext();) { - AbstractName abstractName = (AbstractName) iterator.next(); - if (!kernel.isRunning(abstractName)) { - iterator.remove(); - } - } - if (names.isEmpty()) { - return null; // may be one, just not editable - } - if (names.size() > 1) { - throw new IllegalStateException("More than one Configuration Manager was found in the kernel"); - } - AbstractName configurationManagerName = (AbstractName) names.iterator().next(); - return (EditableConfigurationManager) kernel.getProxyManager().createProxy(configurationManagerName, EditableConfigurationManager.class); - } +// public static EditableConfigurationManager getEditableConfigurationManager(Kernel kernel) { +// Set names = kernel.listGBeans(new AbstractNameQuery(EditableConfigurationManager.class.getName())); +// for (Iterator iterator = names.iterator(); iterator.hasNext();) { +// AbstractName abstractName = (AbstractName) iterator.next(); +// if (!kernel.isRunning(abstractName)) { +// iterator.remove(); +// } +// } +// if (names.isEmpty()) { +// return null; // may be one, just not editable +// } +// if (names.size() > 1) { +// throw new IllegalStateException("More than one Configuration Manager was found in the kernel"); +// } +// AbstractName configurationManagerName = (AbstractName) names.iterator().next(); +// return (EditableConfigurationManager) kernel.getProxyManager().createProxy(configurationManagerName, EditableConfigurationManager.class); +// } public static void releaseConfigurationManager(Kernel kernel, ConfigurationManager configurationManager) { - kernel.getProxyManager().destroyProxy(configurationManager); +// kernel.getProxyManager().destroyProxy(configurationManager); } static void preprocessGBeanData(AbstractName configurationName, Configuration configuration, GBeanData gbeanData) throws InvalidConfigException { if (log.isDebugEnabled()) { log.debug("resolving dependencies for " + gbeanData.getAbstractName()); } - for (Iterator references = gbeanData.getReferencesNames().iterator(); references.hasNext();) { - String referenceName = (String) references.next(); + for (String referenceName : gbeanData.getReferencesNames()) { GReferenceInfo referenceInfo = gbeanData.getGBeanInfo().getReference(referenceName); if (referenceInfo == null) { throw new InvalidConfigException("No reference named " + referenceName + " in gbean " + gbeanData.getAbstractName()); @@ -384,8 +393,7 @@ } Set newDependencies = new HashSet(); - for (Iterator dependencyIterator = gbeanData.getDependencies().iterator(); dependencyIterator.hasNext();) { - ReferencePatterns referencePatterns = (ReferencePatterns) dependencyIterator.next(); + for (ReferencePatterns referencePatterns : gbeanData.getDependencies()) { AbstractName abstractName; try { abstractName = configuration.findGBean(referencePatterns); @@ -400,7 +408,7 @@ gbeanData.setDependencies(newDependencies); // If the GBean has a configurationBaseUrl attribute, set it - // todo Even though this is not used by the classloader, web apps still need this. WHY??? + // todo Even though this is not used by the classloader, web apps and persistence units still need this. WHY??? GAttributeInfo attribute = gbeanData.getGBeanInfo().getAttribute("configurationBaseUrl"); if (attribute != null && attribute.getType().equals("java.net.URL")) { try { @@ -420,16 +428,15 @@ } static void startConfigurationGBeans(AbstractName configurationName, Configuration configuration, Kernel kernel) throws InvalidConfigException { - List gbeans = new ArrayList(configuration.getGBeans().values()); + List gbeans = new ArrayList(configuration.getGBeans().values()); Collections.sort(gbeans, new GBeanData.PriorityComparator()); - List loaded = new ArrayList(gbeans.size()); - List started = new ArrayList(gbeans.size()); + List loaded = new ArrayList(gbeans.size()); + List started = new ArrayList(gbeans.size()); try { // register all the GBeans - for (Iterator iterator = gbeans.iterator(); iterator.hasNext();) { - GBeanData gbeanData = (GBeanData) iterator.next(); + for (GBeanData gbeanData : gbeans) { // copy the gbeanData object as not to mutate the original gbeanData = new GBeanData(gbeanData); @@ -450,17 +457,15 @@ try { // start the gbeans - for (Iterator iterator = gbeans.iterator(); iterator.hasNext();) { - GBeanData gbeanData = (GBeanData) iterator.next(); + for (GBeanData gbeanData : gbeans) { AbstractName gbeanName = gbeanData.getAbstractName(); kernel.startRecursiveGBean(gbeanName); started.add(gbeanName); } // assure all of the gbeans are started - List unstarted = new ArrayList(); - for (Iterator iterator = gbeans.iterator(); iterator.hasNext();) { - GBeanData gbeanData = (GBeanData) iterator.next(); + List unstarted = new ArrayList(); + for (GBeanData gbeanData : gbeans) { AbstractName gbeanName = gbeanData.getAbstractName(); if (State.RUNNING_INDEX != kernel.getGBeanState(gbeanName)) { String stateReason = null; @@ -488,13 +493,11 @@ throw new InvalidConfigException(e); } - for (Iterator iterator = configuration.getChildren().iterator(); iterator.hasNext();) { - Configuration childConfiguration = (Configuration) iterator.next(); + for (Configuration childConfiguration : configuration.getChildren()) { ConfigurationUtil.startConfigurationGBeans(configurationName, childConfiguration, kernel); } } catch (Throwable e) { - for (Iterator iterator = started.iterator(); iterator.hasNext();) { - AbstractName gbeanName = (AbstractName) iterator.next(); + for (AbstractName gbeanName : started) { try { kernel.stopGBean(gbeanName); } catch (GBeanNotFoundException ignored) { @@ -503,8 +506,7 @@ log.debug("Error cleaning up after failed start of configuration " + configuration.getId() + " gbean " + gbeanName, kernelException); } } - for (Iterator iterator = loaded.iterator(); iterator.hasNext();) { - AbstractName gbeanName = (AbstractName) iterator.next(); + for (AbstractName gbeanName : loaded) { try { kernel.unloadGBean(gbeanName); } catch (GBeanNotFoundException ignored) { Added: geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/DependencyNode.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/DependencyNode.java?rev=755494&view=auto ============================================================================== --- geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/DependencyNode.java (added) +++ geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/DependencyNode.java Wed Mar 18 07:07:17 2009 @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +package org.apache.geronimo.kernel.config; + +import java.util.LinkedHashSet; + +import org.apache.geronimo.kernel.repository.Artifact; + +/** + * Tracks dependency info for a plugin/configuration + * + * @version $Rev$ $Date$ + */ +public class DependencyNode { + + private final Artifact id; + private final LinkedHashSet classParents; + private final LinkedHashSet serviceParents; + + public DependencyNode(Artifact id, LinkedHashSet classParents, LinkedHashSet serviceParents) { + this.id = id; + this.classParents = classParents; + this.serviceParents = serviceParents; + } + + public Artifact getId() { + return id; + } + + public LinkedHashSet getClassParents() { + return classParents; + } + + public LinkedHashSet getServiceParents() { + return serviceParents; + } + + public LinkedHashSet getParents() { + LinkedHashSet all = new LinkedHashSet(classParents); + all.addAll(serviceParents); + return all; + } +} Propchange: geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/DependencyNode.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/DependencyNode.java ------------------------------------------------------------------------------ svn:keywords = Date Revision Propchange: geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/DependencyNode.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/DependencyNodeUtil.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/DependencyNodeUtil.java?rev=755494&view=auto ============================================================================== --- geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/DependencyNodeUtil.java (added) +++ geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/DependencyNodeUtil.java Wed Mar 18 07:07:17 2009 @@ -0,0 +1,107 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +package org.apache.geronimo.kernel.config; + +import java.util.List; +import java.util.Set; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashSet; + +import org.apache.geronimo.kernel.repository.Artifact; +import org.apache.geronimo.kernel.repository.Environment; +import org.apache.geronimo.kernel.repository.ArtifactResolver; +import org.apache.geronimo.kernel.repository.Dependency; +import org.apache.geronimo.kernel.repository.MissingDependencyException; +import org.apache.geronimo.kernel.repository.ImportType; + +/** + * @version $Rev$ $Date$ + */ +public class DependencyNodeUtil { + + //TODO not clear if we need to pass in ConfigurationManager rather than configsById + public static List getAllServiceParents(DependencyNode root, ConfigurationManager configurationManager) throws NoSuchConfigException { + List ancestors = new ArrayList(); + Set ids = new HashSet(); + addDepthFirstServiceParents(root, ancestors, ids, configurationManager); + return ancestors; + } + + private static void addDepthFirstServiceParents(DependencyNode root, List ancestors, Set ids, ConfigurationSource configurationManager) throws NoSuchConfigException { + Artifact id = root.getId(); + if (!ids.contains(id)) { + Configuration configuration = getConfiguration(id, configurationManager, ids); + ancestors.add(configuration); + ids.add(root.getId()); + for (Artifact parentId : root.getServiceParents()) { + DependencyNode parent = getConfiguration(parentId, configurationManager, ids).getDependencyNode(); + addDepthFirstServiceParents(parent, ancestors, ids, configurationManager); + } + } + } + + private static Configuration getConfiguration(Artifact id, ConfigurationSource configurationManager, Object info) throws NoSuchConfigException { + Configuration configuration = configurationManager.getConfiguration(id); + if (configuration == null) { + throw new NoSuchConfigException(id, "Configuration " + id + " not found in configuration manager " + configurationManager + " after finding: " + info); + } + return configuration; + } + + public static void addClassParents(DependencyNode node, LinkedHashSet parents, ConfigurationSource configurationManager) throws NoSuchConfigException { + for (Artifact artifact: node.getClassParents()) { + parents.add(getConfiguration(artifact, configurationManager, parents)); + } + } + public static void addServiceParents(DependencyNode node, LinkedHashSet parents, ConfigurationSource configurationManager) throws NoSuchConfigException { + for (Artifact artifact: node.getServiceParents()) { + parents.add(getConfiguration(artifact, configurationManager, parents)); + } + } + + public static DependencyNode toDependencyNode(Environment environment, ArtifactResolver artifactResolver, ConfigurationManager configurationFilter) throws MissingDependencyException { + Artifact id = environment.getConfigId(); + LinkedHashSet classParents = new LinkedHashSet(); + LinkedHashSet serviceParents = new LinkedHashSet(); + for (Dependency dependency: environment.getDependencies()) { + try { + Artifact parent = artifactResolver.resolveInClassLoader(dependency.getArtifact()); + if (configurationFilter.isConfiguration(parent)) { + if (dependency.getImportType() == ImportType.ALL || dependency.getImportType() == ImportType.SERVICES) { + serviceParents.add(parent); + } + if (dependency.getImportType() == ImportType.ALL || dependency.getImportType() == ImportType.CLASSES) { + classParents.add(parent); + } + } else { + if (dependency.getImportType() == ImportType.SERVICES) { + throw new MissingDependencyException("Not a configuration but import type services only", parent, id); + } + } + } catch (MissingDependencyException e) { + throw (MissingDependencyException)new MissingDependencyException("Attempting to resolve environment: " + environment, dependency.getArtifact(), id).initCause(e); + } + } + return new DependencyNode(id, classParents, serviceParents); + } + +} Propchange: geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/DependencyNodeUtil.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/DependencyNodeUtil.java ------------------------------------------------------------------------------ svn:keywords = Date Revision Propchange: geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/DependencyNodeUtil.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/EditableKernelConfigurationManager.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/EditableKernelConfigurationManager.java?rev=755494&r1=755493&r2=755494&view=diff ============================================================================== --- geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/EditableKernelConfigurationManager.java (original) +++ geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/EditableKernelConfigurationManager.java Wed Mar 18 07:07:17 2009 @@ -27,10 +27,8 @@ import org.apache.geronimo.gbean.GBeanData; import org.apache.geronimo.gbean.GBeanInfo; import org.apache.geronimo.gbean.GBeanInfoBuilder; -import org.apache.geronimo.kernel.GBeanAlreadyExistsException; import org.apache.geronimo.kernel.GBeanNotFoundException; import org.apache.geronimo.kernel.Kernel; -import org.apache.geronimo.kernel.management.State; import org.apache.geronimo.kernel.repository.Artifact; import org.apache.geronimo.kernel.repository.ArtifactManager; import org.apache.geronimo.kernel.repository.ArtifactResolver; @@ -63,6 +61,7 @@ watchers, classLoader); this.defaultStoreNameQuery = defaultStoreNameQuery; + throw new RuntimeException("more than deprecated"); } @Override @@ -84,106 +83,106 @@ } public void addGBeanToConfiguration(Artifact configurationId, GBeanData gbean, boolean start) throws InvalidConfigException { - Configuration configuration = getConfiguration(configurationId); - - try { - // add the gbean to the configuration - configuration.addGBean(gbean); - } catch (GBeanAlreadyExistsException e) { - throw new InvalidConfigException("Cound not add GBean " + gbean.getAbstractName() + " to configuration " + configurationId, e); - } - - addGBeanToConfiguration(configuration, gbean, start); +// Configuration configuration = getConfiguration(configurationId); +// +// try { +// // add the gbean to the configuration +// configuration.addGBean(gbean); +// } catch (GBeanAlreadyExistsException e) { +// throw new InvalidConfigException("Cound not add GBean " + gbean.getAbstractName() + " to configuration " + configurationId, e); +// } +// +// addGBeanToConfiguration(configuration, gbean, start); } public void addGBeanToConfiguration(Artifact configurationId, String name, GBeanData gbean, boolean start) throws InvalidConfigException { - Configuration configuration = getConfiguration(configurationId); - - try { - // add the gbean to the configuration - configuration.addGBean(name, gbean); - } catch (GBeanAlreadyExistsException e) { - throw new InvalidConfigException("Cound not add GBean " + gbean.getAbstractName() + " to configuration " + configurationId, e); - } - - addGBeanToConfiguration(configuration, gbean, start); - } - - private void addGBeanToConfiguration(Configuration configuration, GBeanData gbean, boolean start) throws InvalidConfigException { - ClassLoader configurationClassLoader = configuration.getConfigurationClassLoader(); - ClassLoader oldCl = Thread.currentThread().getContextClassLoader(); - try { - Thread.currentThread().setContextClassLoader(configurationClassLoader); - - log.trace("Registering GBean " + gbean.getAbstractName()); - - - // preprocess the gbean data before loading it into the kernel - ConfigurationUtil.preprocessGBeanData(configuration.getAbstractName(), configuration, gbean); - - // register the bean with the kernel - kernel.loadGBean(gbean, configurationClassLoader); - - // start the configuration - if (start) { - try { - kernel.startRecursiveGBean(gbean.getAbstractName()); - } catch (GBeanNotFoundException e) { - throw new InvalidConfigException("How could we not find a GBean that we just loaded ('" + gbean.getAbstractName() + "')?", e); - } - } - - } catch(Exception e) { - // clean up failed gbean - try { - configuration.removeGBean(gbean.getAbstractName()); - } catch (GBeanNotFoundException e1) { - // this is good - } - try { - kernel.stopGBean(gbean.getAbstractName()); - } catch (GBeanNotFoundException e1) { - // this is good - } - try { - kernel.unloadGBean(gbean.getAbstractName()); - } catch (GBeanNotFoundException e1) { - // this is good - } - - if (e instanceof InvalidConfigException) { - throw (InvalidConfigException) e; - } - throw new InvalidConfigException("Cound not add GBean " + gbean.getAbstractName() + " to configuration " + configuration.getId(), e); - } finally { - Thread.currentThread().setContextClassLoader(oldCl); - } - - if (attributeStore != null) { - attributeStore.addGBean(configuration.getId(), gbean, configurationClassLoader); - } - } +// Configuration configuration = getConfiguration(configurationId); +// +// try { +// // add the gbean to the configuration +// configuration.addGBean(name, gbean); +// } catch (GBeanAlreadyExistsException e) { +// throw new InvalidConfigException("Cound not add GBean " + gbean.getAbstractName() + " to configuration " + configurationId, e); +// } +// +// addGBeanToConfiguration(configuration, gbean, start); + } + +// private void addGBeanToConfiguration(Configuration configuration, GBeanData gbean, boolean start) throws InvalidConfigException { +// ClassLoader configurationClassLoader = configuration.getConfigurationClassLoader(); +// ClassLoader oldCl = Thread.currentThread().getContextClassLoader(); +// try { +// Thread.currentThread().setContextClassLoader(configurationClassLoader); +// +// log.trace("Registering GBean " + gbean.getAbstractName()); +// +// +// // preprocess the gbean data before loading it into the kernel +// ConfigurationUtil.preprocessGBeanData(configuration.getAbstractName(), configuration, gbean); +// +// // register the bean with the kernel +// kernel.loadGBean(gbean, configurationClassLoader); +// +// // start the configuration +// if (start) { +// try { +// kernel.startRecursiveGBean(gbean.getAbstractName()); +// } catch (GBeanNotFoundException e) { +// throw new InvalidConfigException("How could we not find a GBean that we just loaded ('" + gbean.getAbstractName() + "')?", e); +// } +// } +// +// } catch(Exception e) { +// // clean up failed gbean +// try { +// configuration.removeGBean(gbean.getAbstractName()); +// } catch (GBeanNotFoundException e1) { +// // this is good +// } +// try { +// kernel.stopGBean(gbean.getAbstractName()); +// } catch (GBeanNotFoundException e1) { +// // this is good +// } +// try { +// kernel.unloadGBean(gbean.getAbstractName()); +// } catch (GBeanNotFoundException e1) { +// // this is good +// } +// +// if (e instanceof InvalidConfigException) { +// throw (InvalidConfigException) e; +// } +// throw new InvalidConfigException("Cound not add GBean " + gbean.getAbstractName() + " to configuration " + configuration.getId(), e); +// } finally { +// Thread.currentThread().setContextClassLoader(oldCl); +// } +// +// if (attributeStore != null) { +// attributeStore.addGBean(configuration.getId(), gbean, configurationClassLoader); +// } +// } public void removeGBeanFromConfiguration(Artifact configurationId, AbstractName gbeanName) throws GBeanNotFoundException, InvalidConfigException { - Configuration configuration = getConfiguration(configurationId); - if (!configuration.containsGBean(gbeanName)) { - throw new GBeanNotFoundException(gbeanName); - } - configuration.removeGBean(gbeanName); - - try { - if (kernel.getGBeanState(gbeanName) == State.RUNNING_INDEX) { - kernel.stopGBean(gbeanName); - } - kernel.unloadGBean(gbeanName); - } catch (GBeanNotFoundException e) { - // Bean is no longer loaded - } - - // Make sure it's not loaded next time the configuration is loaded - if (attributeStore != null) { - attributeStore.setShouldLoad(configurationId, gbeanName, false); - } +// Configuration configuration = getConfiguration(configurationId); +// if (!configuration.containsGBean(gbeanName)) { +// throw new GBeanNotFoundException(gbeanName); +// } +// configuration.removeGBean(gbeanName); +// +// try { +// if (kernel.getGBeanState(gbeanName) == State.RUNNING_INDEX) { +// kernel.stopGBean(gbeanName); +// } +// kernel.unloadGBean(gbeanName); +// } catch (GBeanNotFoundException e) { +// // Bean is no longer loaded +// } +// +// // Make sure it's not loaded next time the configuration is loaded +// if (attributeStore != null) { +// attributeStore.setShouldLoad(configurationId, gbeanName, false); +// } } public static final GBeanInfo GBEAN_INFO; Modified: geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/GBeanState.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/GBeanState.java?rev=755494&r1=755493&r2=755494&view=diff ============================================================================== --- geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/GBeanState.java (original) +++ geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/GBeanState.java Wed Mar 18 07:07:17 2009 @@ -32,4 +32,5 @@ void addGBean(GBeanData gbeanData); GBeanData addGBean(String name, GBeanInfo gbeanInfo, Naming naming, Environment environment); + GBeanData addGBean(String name, Class gbeanClass, Naming naming, Environment environment); } Added: geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/JarFileClassLoaderFactory.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/JarFileClassLoaderFactory.java?rev=755494&view=auto ============================================================================== --- geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/JarFileClassLoaderFactory.java (added) +++ geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/JarFileClassLoaderFactory.java Wed Mar 18 07:07:17 2009 @@ -0,0 +1,179 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +package org.apache.geronimo.kernel.config; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.Collections; +import java.util.Set; +import java.net.MalformedURLException; +import java.net.URL; +import java.io.File; + +import org.apache.geronimo.kernel.repository.Environment; +import org.apache.geronimo.kernel.repository.Dependency; +import org.apache.geronimo.kernel.repository.Artifact; +import org.apache.geronimo.kernel.repository.ImportType; +import org.apache.geronimo.kernel.repository.ClassLoadingRules; +import org.apache.geronimo.kernel.repository.MissingDependencyException; +import org.apache.geronimo.kernel.repository.ClassLoadingRule; +import org.apache.geronimo.kernel.classloader.JarFileClassLoader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @version $Rev$ $Date$ + */ +public class JarFileClassLoaderFactory { + private static final Logger log = LoggerFactory.getLogger(JarFileClassLoaderFactory.class); + + public ClassLoaderHolder buildClassLoaders(Collection parents, + Environment environment, + LinkedHashSet classPath, + ConfigurationResolver configurationResolver) throws MissingDependencyException, MalformedURLException, NoSuchConfigException { + + List classParents = new ArrayList(); + LinkedHashSet dependencies = new LinkedHashSet(); + // + // Transitively resolve all the dependencies in the environment + // + List transitiveDependencies = configurationResolver.resolveTransitiveDependencies(parents, environment.getDependencies()); + + // + // Process transtive dependencies splitting it into classParents, serviceParents and artifactDependencies + // + Map parentsById = new HashMap(); + for (Configuration configuration : parents) { + Artifact id = configuration.getId(); + parentsById.put(id, configuration); + } + //TODO why the complexigy? why not just use parents passed in? + for (Dependency dependency : transitiveDependencies) { + Artifact artifact = dependency.getArtifact(); + if (parentsById.containsKey(artifact)) { + Configuration parent = parentsById.get(artifact); + if (dependency.getImportType() == ImportType.CLASSES || dependency.getImportType() == ImportType.ALL) { + classParents.add(parent); + } + } else if (dependency.getImportType() == ImportType.SERVICES) { + throw new IllegalStateException("Could not find parent " + artifact + " in the parents collection"); + } else { + dependencies.add(artifact); + } + } + + // + // Build the configuration class loader + // + ClassLoader configurationClassLoader = createConfigurationClasssLoader(parents, environment, classPath, classParents, dependencies, configurationResolver); + + ClassLoadingRules rules = environment.getClassLoadingRules(); + ClassLoader childrenConfigurationClassLoader = new ChildrenConfigurationClassLoader(configurationClassLoader, rules); + + return new ClassLoaderHolder(configurationClassLoader, childrenConfigurationClassLoader); + } + + private MultiParentClassLoader createConfigurationClasssLoader(Collection parents, Environment environment, LinkedHashSet classPath, Collection classParents, LinkedHashSet dependencies, ConfigurationResolver configurationResolver) throws MalformedURLException, MissingDependencyException, NoSuchConfigException { + // create the URL list + URL[] urls = buildClassPath(dependencies, classPath, configurationResolver); + + // parents + List parentClassLoaders; + if (parents.size() == 0 && classParents.size() == 0) { + // no explicit parent set, so use the class loader of this class as + // the parent... this class should be in the root geronimo classloader, + // which is normally the system class loader but not always, so be safe + parentClassLoaders = Collections.singletonList(getClass().getClassLoader()); + } else { + parentClassLoaders = new ArrayList(classParents.size()); + for (Configuration parent : classParents) { + parentClassLoaders.add(parent.getClassLoaderHolder().getExternalClassLoader()); + } + } + + // we need to propagate the non-overrideable classes from parents + ClassLoadingRules classLoadingRules = environment.getClassLoadingRules(); + ClassLoadingRule nonOverrideableRule = classLoadingRules.getNonOverrideableRule(); + for (Configuration parent : classParents) { + Environment parentEnvironment = parent.getConfigurationData().getEnvironment(); + ClassLoadingRules parentClassLoadingRules = parentEnvironment.getClassLoadingRules(); + ClassLoadingRule parentNonOverrideableRule = parentClassLoadingRules.getNonOverrideableRule(); + nonOverrideableRule.merge(parentNonOverrideableRule); + } + + if (log.isDebugEnabled()) { + StringBuffer buf = new StringBuffer("ClassLoader structure for configuration ").append(environment.getConfigId()).append("\n"); + buf.append("Parent configurations:\n"); + for (Configuration configuration : classParents) { + buf.append(" ").append(configuration.getId()).append("\n"); + } + buf.append("ClassPath:\n"); + for (URL url : urls) { + buf.append(" ").append(url).append("\n"); + } + log.debug(buf.toString()); + } + + // The JarFileClassLoader was created to address a locking problem seen only on Windows platforms. + // It carries with it a slight performance penalty that needs to be addressed. Rather than make + // *nix OSes carry this burden we'll engage the JarFileClassLoader for Windows or if the user + // specifically requests it. We'll look more at this issue in the future. + boolean useJarFileClassLoader; + if (System.getProperty("Xorg.apache.geronimo.JarFileClassLoader") == null) { + useJarFileClassLoader = System.getProperty("os.name").startsWith("Windows"); + } else { + useJarFileClassLoader = Boolean.getBoolean("Xorg.apache.geronimo.JarFileClassLoader"); + } + if (useJarFileClassLoader) { + return new JarFileClassLoader(environment.getConfigId(), + urls, + parentClassLoaders, + classLoadingRules); + } else { + return new MultiParentClassLoader(environment.getConfigId(), + urls, + parentClassLoaders, + classLoadingRules); + } + } + + private URL[] buildClassPath(LinkedHashSet dependencies, LinkedHashSet classPath, ConfigurationResolver configurationResolver) throws MalformedURLException, MissingDependencyException, NoSuchConfigException { + List urls = new ArrayList(); + for (Artifact artifact : dependencies) { + File file = configurationResolver.resolve(artifact); + urls.add(file.toURL()); + } + if (classPath != null) { + for (String pattern : classPath) { + Set matches = configurationResolver.resolve(pattern); + for (URL url : matches) { + urls.add(url); + } + } + } + return urls.toArray(new URL[urls.size()]); + } + +} Propchange: geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/JarFileClassLoaderFactory.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/JarFileClassLoaderFactory.java ------------------------------------------------------------------------------ svn:keywords = Date Revision Propchange: geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/JarFileClassLoaderFactory.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/KernelConfigurationManager.java URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/KernelConfigurationManager.java?rev=755494&r1=755493&r2=755494&view=diff ============================================================================== --- geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/KernelConfigurationManager.java (original) +++ geronimo/sandbox/djencks/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/config/KernelConfigurationManager.java Wed Mar 18 07:07:17 2009 @@ -17,15 +17,15 @@ package org.apache.geronimo.kernel.config; +import java.net.MalformedURLException; import java.util.Collection; import java.util.Collections; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.apache.geronimo.gbean.AbstractName; import org.apache.geronimo.gbean.AbstractNameQuery; import org.apache.geronimo.gbean.GBeanData; @@ -42,6 +42,9 @@ import org.apache.geronimo.kernel.repository.ArtifactManager; import org.apache.geronimo.kernel.repository.ArtifactResolver; import org.apache.geronimo.kernel.repository.DefaultArtifactResolver; +import org.apache.geronimo.kernel.repository.MissingDependencyException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * The standard non-editable ConfigurationManager implementation. That is, @@ -49,7 +52,6 @@ * GBeans included in a configuration. * * @version $Rev:386276 $ $Date$ - * @see EditableConfigurationManager */ public class KernelConfigurationManager extends SimpleConfigurationManager implements GBeanLifecycle { @@ -62,14 +64,14 @@ private boolean online = true; public KernelConfigurationManager(Kernel kernel, - Collection stores, - ManageableAttributeStore attributeStore, - PersistentConfigurationList configurationList, - ArtifactManager artifactManager, - ArtifactResolver artifactResolver, - Collection repositories, - Collection watchers, - ClassLoader classLoader) { + Collection stores, + ManageableAttributeStore attributeStore, + PersistentConfigurationList configurationList, + ArtifactManager artifactManager, + ArtifactResolver artifactResolver, + Collection repositories, + Collection watchers, + ClassLoader classLoader) { super(stores, createArtifactResolver(artifactResolver, artifactManager, repositories), @@ -88,7 +90,8 @@ if (artifactResolver != null) { return artifactResolver; } - return new DefaultArtifactResolver(artifactManager, repositories, null); + //TODO no reference to this may cause problems + return new DefaultArtifactResolver(artifactManager, repositories, null, Collections.emptyList()); } public synchronized LifecycleResults loadConfiguration(Artifact configurationId) throws NoSuchConfigException, LifecycleException { @@ -125,30 +128,44 @@ super.migrateConfiguration(oldName, newName, configuration, running); if (configurationList != null) { configurationList.migrateConfiguration(oldName, newName, configuration); - if(running) { + if (running) { configurationList.startConfiguration(newName); } } } - protected Configuration load(ConfigurationData configurationData, LinkedHashSet resolvedParentIds, Map loadedConfigurations) throws InvalidConfigException { + protected Configuration load(ConfigurationData configurationData, LinkedHashSet resolvedParentIds, Map loadedConfigurations) throws InvalidConfigException { Artifact configurationId = configurationData.getId(); AbstractName configurationName = Configuration.getConfigurationAbstractName(configurationId); - GBeanData gbeanData = new GBeanData(configurationName, Configuration.GBEAN_INFO); + GBeanData gbeanData = new GBeanData(configurationName, Configuration.class); gbeanData.setAttribute("configurationData", configurationData); - gbeanData.setAttribute("configurationResolver", new ConfigurationResolver(configurationData, repositories, getArtifactResolver())); - //TODO is this dangerous? - gbeanData.setAttribute("managedAttributeStore", attributeStore); + DependencyNode dependencyNode = null; + ConfigurationResolver configurationResolver = new ConfigurationResolver(configurationData, repositories, getArtifactResolver()); + gbeanData.setAttribute("configurationResolver", configurationResolver); + try { + dependencyNode = buildDependencyNode(configurationData); + ClassLoaderHolder classLoaderHolder = buildClassLoaders(configurationData, loadedConfigurations, dependencyNode, configurationResolver); + + gbeanData.setAttribute("dependencyNode", dependencyNode); + gbeanData.setAttribute("classLoaderHolder", classLoaderHolder); + gbeanData.setAttribute("allServiceParents", buildAllServiceParents(loadedConfigurations, dependencyNode)); + } catch (MissingDependencyException e) { + throw new InvalidConfigException(e); + } catch (MalformedURLException e) { + throw new InvalidConfigException(e); + } catch (NoSuchConfigException e) { + throw new InvalidConfigException(e); + } + //TODO is this dangerous? should really add dependency on attribute store name + gbeanData.setAttribute("attributeStore", attributeStore); // add parents to the parents reference collection - LinkedHashSet parentNames = new LinkedHashSet(); - for (Iterator iterator = resolvedParentIds.iterator(); iterator.hasNext();) { - Artifact resolvedParentId = (Artifact) iterator.next(); + LinkedHashSet parentNames = new LinkedHashSet(); + for (Artifact resolvedParentId : resolvedParentIds) { AbstractName parentName = Configuration.getConfigurationAbstractName(resolvedParentId); parentNames.add(parentName); } gbeanData.addDependencies(parentNames); - gbeanData.setReferencePatterns("Parents", parentNames); // load the configuration try { @@ -171,7 +188,14 @@ // declare the dependencies as loaded if (artifactManager != null) { - artifactManager.loadArtifacts(configurationId, configuration.getDependencies()); + artifactManager.loadArtifacts(configurationId, configuration.getDependencyNode().getParents()); + } + Map moreLoadedConfigurations = new LinkedHashMap(loadedConfigurations); + moreLoadedConfigurations.put(dependencyNode.getId(), configuration); + for (Map.Entry childEntry: configurationData.getChildConfigurations().entrySet()) { + ConfigurationResolver childResolver = configurationResolver.createChildResolver(childEntry.getKey()); + Configuration child = doLoad(childEntry.getValue(), resolvedParentIds, moreLoadedConfigurations, childResolver); + configuration.addChild(child); } log.debug("Loaded Configuration {}", configurationName); @@ -283,10 +307,10 @@ protected void uninstall(Artifact configurationId) { if (configurationList != null) { - configurationList.removeConfiguration( configurationId ); + configurationList.removeConfiguration(configurationId); } } - + public void doStart() { kernel.registerShutdownHook(shutdownHook); } @@ -303,7 +327,7 @@ private final Kernel kernel; private final ConfigurationModel configurationModel; private final Logger log = LoggerFactory.getLogger(ShutdownHook.class); - + public ShutdownHook(Kernel kernel, ConfigurationModel configurationModel) { this.kernel = kernel; this.configurationModel = configurationModel; @@ -322,7 +346,7 @@ LinkedHashSet startedChildren = configurationModel.getStartedChildren(configName.getArtifact()); for (Iterator iterator = startedChildren.iterator(); iterator.hasNext();) { Artifact configurationId = (Artifact) iterator.next(); - Set childConfig = kernel.listGBeans(new AbstractNameQuery(configurationId, Collections.emptyMap() , Configuration.class.getName())); + Set childConfig = kernel.listGBeans(new AbstractNameQuery(configurationId, Collections.emptyMap(), Configuration.class.getName())); if (!childConfig.isEmpty()) { AbstractName childConfigName = (AbstractName) childConfig.iterator().next(); if (!orderedConfigs.contains(childConfigName))