You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by ju...@apache.org on 2005/02/02 02:59:42 UTC

svn commit: r149468 - in geronimo/trunk/modules: assembly/ assembly/src/plan/ j2ee/src/java/org/apache/geronimo/j2ee/management/impl/ spring-builder/ spring-builder/src/java/org/apache/geronimo/spring/deployment/ spring/src/java/org/apache/geronimo/spring/

Author: jules
Date: Tue Feb  1 17:59:38 2005
New Revision: 149468

URL: http://svn.apache.org/viewcvs?view=rev&rev=149468
Log:
second cut of spring deployer - now split into deploy and runtime components

Added:
    geronimo/trunk/modules/assembly/src/plan/spring-runtime-plan.xml
    geronimo/trunk/modules/spring/src/java/org/apache/geronimo/spring/SpringApplicationImpl.java
      - copied, changed from r148865, geronimo/trunk/modules/j2ee/src/java/org/apache/geronimo/j2ee/management/impl/SpringApplicationImpl.java
Removed:
    geronimo/trunk/modules/j2ee/src/java/org/apache/geronimo/j2ee/management/impl/SpringApplicationImpl.java
Modified:
    geronimo/trunk/modules/assembly/maven.xml
    geronimo/trunk/modules/assembly/project.xml
    geronimo/trunk/modules/assembly/src/plan/j2ee-runtime-deployer-plan.xml
    geronimo/trunk/modules/assembly/src/plan/spring-deployer-plan.xml
    geronimo/trunk/modules/spring-builder/project.xml
    geronimo/trunk/modules/spring-builder/src/java/org/apache/geronimo/spring/deployment/SPRConfigBuilder.java
    geronimo/trunk/modules/spring/src/java/org/apache/geronimo/spring/SpringGBean.java

Modified: geronimo/trunk/modules/assembly/maven.xml
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/assembly/maven.xml?view=diff&r1=149467&r2=149468
==============================================================================
--- geronimo/trunk/modules/assembly/maven.xml (original)
+++ geronimo/trunk/modules/assembly/maven.xml Tue Feb  1 17:59:38 2005
@@ -264,6 +264,13 @@
             <ant:arg value="target/plan/j2ee-runtime-deployer-plan.xml"/>
         </ant:java>
 
+        <!-- build the spring runtime configuration -->
+        <ant:echo>Building spring runtime configuration</ant:echo>
+        <ant:java fork="true" jar="${distDir}/bin/deployer.jar" failonerror="true">
+            <ant:jvmarg value="-ea"/>
+            <ant:arg value="distribute"/>
+            <ant:arg value="target/plan/spring-runtime-plan.xml"/>
+        </ant:java>
         <!-- build the spring deployer configuration -->
         <ant:echo>Building spring deployer configuration</ant:echo>
         <ant:java fork="true" jar="${distDir}/bin/deployer.jar" failonerror="true">

Modified: geronimo/trunk/modules/assembly/project.xml
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/assembly/project.xml?view=diff&r1=149467&r2=149468
==============================================================================
--- geronimo/trunk/modules/assembly/project.xml (original)
+++ geronimo/trunk/modules/assembly/project.xml Tue Feb  1 17:59:38 2005
@@ -1090,6 +1090,14 @@
         <!-- spring support-->
         <dependency>
             <groupId>geronimo</groupId>
+            <artifactId>geronimo-spring</artifactId>
+            <version>${pom.currentVersion}</version>
+            <properties>
+                <repository>true</repository>
+            </properties>
+        </dependency>
+        <dependency>
+            <groupId>geronimo</groupId>
             <artifactId>geronimo-spring-builder</artifactId>
             <version>${pom.currentVersion}</version>
             <properties>

Modified: geronimo/trunk/modules/assembly/src/plan/j2ee-runtime-deployer-plan.xml
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/assembly/src/plan/j2ee-runtime-deployer-plan.xml?view=diff&r1=149467&r2=149468
==============================================================================
--- geronimo/trunk/modules/assembly/src/plan/j2ee-runtime-deployer-plan.xml (original)
+++ geronimo/trunk/modules/assembly/src/plan/j2ee-runtime-deployer-plan.xml Tue Feb  1 17:59:38 2005
@@ -64,14 +64,6 @@
          <uri>geronimo/jars/geronimo-axis-builder-${geronimo_version}.jar</uri>
     </dependency>
 
-    <!-- should be in spring-deployer-plan.xml but...  -->
-    <dependency>
-        <uri>springframework/jars/${spring_artifact}-${spring_version}.jar</uri>
-    </dependency>
-    <dependency>
-        <uri>geronimo/jars/geronimo-spring-builder-${geronimo_version}.jar</uri>
-    </dependency>
-
     <!-- deployer gbeans -->
     <gbean namePart="Deployer" class="org.apache.geronimo.deployment.Deployer">
         <reference name="Builders">geronimo.server:j2eeType=ConfigBuilder,J2EEModule=org/apache/geronimo/RuntimeDeployer,*</reference>
@@ -176,11 +168,5 @@
 <!--    </gbean>-->
 <!---->
     <!-- end deployment block -->
-
-    <!-- should be in spring-deployer-plan.xml but...  -->
-    <gbean namePart="SPRBuilder" class="org.apache.geronimo.spring.deployment.SPRConfigBuilder">
-        <attribute name="defaultParentId">org/apache/geronimo/RuntimeDeployer</attribute>
-        <reference name="Repository">*:name=Repository,*</reference>
-    </gbean>
 
 </configuration>

Modified: geronimo/trunk/modules/assembly/src/plan/spring-deployer-plan.xml
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/assembly/src/plan/spring-deployer-plan.xml?view=diff&r1=149467&r2=149468
==============================================================================
--- geronimo/trunk/modules/assembly/src/plan/spring-deployer-plan.xml (original)
+++ geronimo/trunk/modules/assembly/src/plan/spring-deployer-plan.xml Tue Feb  1 17:59:38 2005
@@ -18,29 +18,33 @@
 
 <!-- $Rev: 126313 $ $Date: 2005-01-24 21:03:52 +0000 (Mon, 24 Jan 2005) $ -->
 
-<!--
-Child of the org/apache/geronimo/RuntimeDeployer configuration that adds the Spring deployer
--->
 <configuration
-    xmlns="http://geronimo.apache.org/xml/ns/deployment"
-    configId="org/apache/geronimo/SpringDeployer"
-    parentId="org/apache/geronimo/RuntimeDeployer"
-    >
+  xmlns="http://geronimo.apache.org/xml/ns/deployment"
+  configId="org/apache/geronimo/SpringDeployer"
+  parentId="org/apache/geronimo/SpringRuntime"
+  >
 
-    <!-- moved into j2ee-runtime-deployer-plan.xml because it doesn't work here -->
+  <dependency>
+    <uri>springframework/jars/${spring_artifact}-${spring_version}.jar</uri><!-- lose later -->
+  </dependency>
+  <dependency>
+    <uri>geronimo/jars/geronimo-common-${geronimo_version}.jar</uri>
+  </dependency>
+  <dependency>
+    <uri>geronimo/jars/geronimo-deployment-${geronimo_version}.jar</uri>
+  </dependency>
+  <dependency>
+    <uri>geronimo/jars/geronimo-spring-builder-${geronimo_version}.jar</uri>
+  </dependency>
 
-<!--
-    <dependency>
-        <uri>springframework/jars/${spring_artifact}-${spring_version}.jar</uri>
-    </dependency>
-    <dependency>
-        <uri>geronimo/jars/geronimo-spring-builder-${geronimo_version}.jar</uri>
-    </dependency>
+  <gbean namePart="Deployer" class="org.apache.geronimo.deployment.Deployer">
+    <reference name="Builders">geronimo.server:j2eeType=ConfigBuilder,J2EEModule=org/apache/geronimo/SpringDeployer,*</reference>
+    <reference name="Store">geronimo.server:j2eeType=ConfigurationStore,*</reference>
+  </gbean>
 
-    <gbean namePart="SPRBuilder" class="org.apache.geronimo.spring.deployment.SPRConfigBuilder">
-        <attribute name="defaultParentId">org/apache/geronimo/RuntimeDeployer</attribute>
-        <reference name="Repository">*:name=Repository,*</reference>
-    </gbean>
--->
+  <gbean namePart="SPRBuilder" class="org.apache.geronimo.spring.deployment.SPRConfigBuilder">
+    <attribute name="defaultParentId">org/apache/geronimo/SpringRuntime</attribute>
+    <reference name="Repository">*:name=Repository,*</reference>
+  </gbean>
 
 </configuration>

Added: geronimo/trunk/modules/assembly/src/plan/spring-runtime-plan.xml
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/assembly/src/plan/spring-runtime-plan.xml?view=auto&rev=149468
==============================================================================
--- geronimo/trunk/modules/assembly/src/plan/spring-runtime-plan.xml (added)
+++ geronimo/trunk/modules/assembly/src/plan/spring-runtime-plan.xml Tue Feb  1 17:59:38 2005
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright 2004 The Apache Software Foundation
+
+    Licensed 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.
+-->
+
+<!-- $Rev: 47568 $ $Date: 2004-09-30 01:21:54 -0700 (Thu, 30 Sep 2004) $ -->
+
+<configuration
+  xmlns="http://geronimo.apache.org/xml/ns/deployment"
+  configId="org/apache/geronimo/SpringRuntime"
+  parentId="org/apache/geronimo/System"
+  >
+
+  <dependency>
+    <uri>springframework/jars/${spring_artifact}-${spring_version}.jar</uri>
+  </dependency>
+  <dependency>
+    <uri>geronimo/jars/geronimo-spring-${geronimo_version}.jar</uri>
+  </dependency>
+
+<!--
+  <gbean namePart="Spring" class="org.apache.geronimo.spring.SpringGBean">
+  </gbean>
+-->
+
+</configuration>

Modified: geronimo/trunk/modules/spring-builder/project.xml
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/spring-builder/project.xml?view=diff&r1=149467&r2=149468
==============================================================================
--- geronimo/trunk/modules/spring-builder/project.xml (original)
+++ geronimo/trunk/modules/spring-builder/project.xml Tue Feb  1 17:59:38 2005
@@ -94,13 +94,11 @@
             </properties>
         </dependency>
 
-<!--
        <dependency>
             <groupId>geronimo</groupId>
             <artifactId>geronimo-spring</artifactId>
             <version>${pom.currentVersion}</version>
         </dependency>
--->
 
        <dependency>
             <groupId>geronimo</groupId>

Modified: geronimo/trunk/modules/spring-builder/src/java/org/apache/geronimo/spring/deployment/SPRConfigBuilder.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/spring-builder/src/java/org/apache/geronimo/spring/deployment/SPRConfigBuilder.java?view=diff&r1=149467&r2=149468
==============================================================================
--- geronimo/trunk/modules/spring-builder/src/java/org/apache/geronimo/spring/deployment/SPRConfigBuilder.java (original)
+++ geronimo/trunk/modules/spring-builder/src/java/org/apache/geronimo/spring/deployment/SPRConfigBuilder.java Tue Feb  1 17:59:38 2005
@@ -21,9 +21,11 @@
 import java.net.URI;
 import java.net.URL;
 import java.net.URLClassLoader;
+import java.util.Collections;
 import java.util.Enumeration;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.ArrayList;
 import java.util.jar.JarFile;
 import java.util.zip.ZipEntry;
 import javax.management.MalformedObjectNameException;
@@ -42,9 +44,8 @@
 import org.apache.geronimo.kernel.Kernel;
 import org.apache.geronimo.kernel.config.ConfigurationModuleType;
 import org.apache.geronimo.kernel.repository.Repository;
-import org.springframework.beans.factory.support.DefaultListableBeanFactory;
-import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
-import org.springframework.core.io.ClassPathResource;
+import org.apache.geronimo.spring.SpringGBean;
+import org.apache.geronimo.spring.SpringApplicationImpl;
 
 /**
  * @version $Rev: 126313 $ $Date: 2005-01-24 21:03:52 +0000 (Mon, 24 Jan 2005) $
@@ -52,10 +53,12 @@
 public class SPRConfigBuilder
   implements ConfigurationBuilder
 {
-  private final Log        log=LogFactory.getLog(SPRConfigBuilder.class);
-  private final Kernel     kernel;
-  private final Repository repository;
-  private final URI        defaultParentId;
+  protected static final Log log=LogFactory.getLog(SPRConfigBuilder.class);
+  protected static final String defaultConfigPath="META-INF/spring.xml";
+
+  protected final Kernel     kernel;
+  protected final Repository repository;
+  protected final URI        defaultParentId;
 
   public
     SPRConfigBuilder(URI defaultParentId, Repository repository, Kernel kernel)
@@ -99,102 +102,62 @@
     // - we should check out META-INF/geronimo-spring.xml
     // - could we inject stuff about environment into BeanFactory ?
 
-    DefaultListableBeanFactory dlbf=new DefaultListableBeanFactory();
-    XmlBeanDefinitionReader xbdr=new XmlBeanDefinitionReader(dlbf);
-
-    return xbdr;
-  }
-
-  // TODO - it would be nice if this printed out original names of
-  // jars, rather than name of file that has been copied out...
-  protected void
-    addJarToClassPath(DeploymentContext ctx, JarFile jar)
-    throws Exception
-  {
-    String name=jar.getName();
-    log.info("Adding Jar to application ClassLoader: "+name);
-    ctx.addIncludeAsPackedJar(new URI(name+".tmp"), jar); // without the .tmp this crashes horribly
-
-    // TODO - if NestedJarFile were totally transparent we could
-    // remove this test and recurse to the bottom of the innermost jar
-    // - but instead we end up hanging waiting for the first entry of
-    // the first nested jar - So we are stuck with just supporting one
-    // level of nesting for the moment - shame :-(
-    if (!(jar instanceof NestedJarFile))
-    {
-      for (Enumeration e=jar.entries(); e.hasMoreElements();)
-      {
-	String entry=((ZipEntry)e.nextElement()).getName();
-	if (entry.endsWith(".jar")) // TODO - is this test sufficient ?
-	  addJarToClassPath(ctx, new NestedJarFile(jar, entry));
-      }
-    }
+    return this;		// token passed to buildConfiguration()...
   }
 
   public List
     buildConfiguration(Object plan, JarFile sprFile, File outfile)
     throws IOException, DeploymentException
   {
-    if (!(plan instanceof XmlBeanDefinitionReader))
+    if (!(plan instanceof SPRConfigBuilder)) // hacky...
       return null;
 
-    XmlBeanDefinitionReader xbdr=(XmlBeanDefinitionReader)plan;
-
     log.info("Building: "+sprFile.getName());
 
+    String moduleId="Spring-App-1"; // what should this look like ?
+
     SPRContext ctx=null;
     try
     {
       URI configId=new URI(sprFile.getName());	// could be overridden in META-INF/geronimo-spring.xml
       URI parentId=defaultParentId; // could be overridden in META-INF/geronimo-spring.xml
+      URI configPath=new URI(defaultConfigPath);
 
       ctx=new SPRContext(outfile, configId, ConfigurationModuleType.SPR, parentId, kernel);
 
-      // set up classpath
-      addJarToClassPath(ctx, sprFile);
+      // set up classpath and files that we want available in final
+      // distribution...
+      List classPath=new ArrayList();
+      classPath.add(new URI("."));
 
-      // looks like this is for recursively unpacking an archive... - perhaps we need it ?
-      //       for (Enumeration e=sprFile.entries(); e.hasMoreElements();)
-      //       {
-      // 	ZipEntry entry = (ZipEntry) e.nextElement();
-      // 	String name=entry.getName();
-      // 	ctx.addFile(URI.create(name), sprFile, entry);
-      //       }
+      for (Enumeration e=sprFile.entries(); e.hasMoreElements();)
+      {
+       	ZipEntry entry = (ZipEntry) e.nextElement();
+       	String name=entry.getName();
+       	ctx.addFile(URI.create(name), sprFile, entry);
+
+	if (name.endsWith(".jar"))
+	  classPath.add(new URI(name));
+      }
 
       // now we can get ClassLoader...
-      ClassLoader cl=ctx.getClassLoader(repository);
+      //ClassLoader cl=ctx.getClassLoader(repository);
 
-      xbdr.setBeanClassLoader(cl);
-      xbdr.loadBeanDefinitions(new ClassPathResource("META-INF/spring.xml", cl));
+      // managed Object for this Spring Application
+      {
+	ObjectName name=new ObjectName("geronimo.config", "name", sprFile.getName());
+	GBeanData gbeanData=new GBeanData(name, SpringApplicationImpl.GBEAN_INFO);
+	ctx.addGBean(gbeanData);
+      }
 
-      // force lazy construction of every bean described...
-      DefaultListableBeanFactory dlbf=(DefaultListableBeanFactory)xbdr.getBeanFactory(); // hacky...
-      String[] ids=dlbf.getBeanDefinitionNames();
-      int n=ids.length;
-      for (int i=n; i>0; i--)
-	dlbf.getBean(ids[i-1]);
-      log.info("Deployed: "+n+" POJO"+(n==1?"":"s"));
-
-      ObjectName name=new ObjectName("geronimo.spring", "name", sprFile.getName());
-      GBeanData gbeanData=new GBeanData(name, org.apache.geronimo.j2ee.management.impl.SpringApplicationImpl.GBEAN_INFO);
-
-      // what sort of thing might we want to make available via this GBean ?
-      // contents of dds ?
-      // number of beans constructucted ?
-      // integration points for other apps (how/what?)
-      // - The Bean Factory and Reader ?
-      // etc...
-
-      // setting 'kernel' results in a NotSerializableException: after
-      // returning from this method...
-
-      // gbeanData.setAttribute("kernel", kernel);
-      // gbeanData.setReferencePattern("objectName", name);
-
-      // It looks like by doing this our context creates and registers
-      // a GBean - representation for this Spring application in the
-      // kernel...
-      ctx.addGBean(gbeanData);
+      // the actual Application...
+      {
+	ObjectName name=new ObjectName("geronimo.spring", "name", sprFile.getName());
+	GBeanData gbeanData=new GBeanData(name, SpringGBean.GBEAN_INFO);
+	gbeanData.setAttribute("classPath", classPath.toArray(new URI[classPath.size()]));
+	gbeanData.setAttribute("configPath", configPath);
+	ctx.addGBean(gbeanData);
+      }
     }
     catch (Exception e)
     {
@@ -202,9 +165,9 @@
     }
     finally
     {
-      ctx.close();
+      if (ctx!=null) ctx.close();
     }
 
-    return new LinkedList(); // what should we return in this list ?
+    return Collections.singletonList(moduleId);
   }
 }

Copied: geronimo/trunk/modules/spring/src/java/org/apache/geronimo/spring/SpringApplicationImpl.java (from r148865, geronimo/trunk/modules/j2ee/src/java/org/apache/geronimo/j2ee/management/impl/SpringApplicationImpl.java)
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/spring/src/java/org/apache/geronimo/spring/SpringApplicationImpl.java?view=diff&rev=149468&p1=geronimo/trunk/modules/j2ee/src/java/org/apache/geronimo/j2ee/management/impl/SpringApplicationImpl.java&r1=148865&p2=geronimo/trunk/modules/spring/src/java/org/apache/geronimo/spring/SpringApplicationImpl.java&r2=149468
==============================================================================
--- geronimo/trunk/modules/j2ee/src/java/org/apache/geronimo/j2ee/management/impl/SpringApplicationImpl.java (original)
+++ geronimo/trunk/modules/spring/src/java/org/apache/geronimo/spring/SpringApplicationImpl.java Tue Feb  1 17:59:38 2005
@@ -15,22 +15,13 @@
  *  limitations under the License.
  */
 
-package org.apache.geronimo.j2ee.management.impl;
+package org.apache.geronimo.spring;
 
-import java.util.Hashtable;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
+//import javax.management.ObjectName;
 
 import org.apache.geronimo.gbean.GBeanInfo;
 import org.apache.geronimo.gbean.GBeanInfoBuilder;
 import org.apache.geronimo.kernel.Kernel;
-import org.apache.geronimo.kernel.jmx.JMXUtil;
-import org.apache.geronimo.system.serverinfo.ServerInfo;
-import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
-
-// I know that this should not be here (in the j2ee package) but,
-// until someone who knows what they are doing has time to have a look
-// at it, this seems the path of least resistance...
 
 /**
  * @version $Rev: 126313 $ $Date: 2005-01-24 21:03:52 +0000 (Mon, 24 Jan 2005) $

Modified: geronimo/trunk/modules/spring/src/java/org/apache/geronimo/spring/SpringGBean.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/spring/src/java/org/apache/geronimo/spring/SpringGBean.java?view=diff&r1=149467&r2=149468
==============================================================================
--- geronimo/trunk/modules/spring/src/java/org/apache/geronimo/spring/SpringGBean.java (original)
+++ geronimo/trunk/modules/spring/src/java/org/apache/geronimo/spring/SpringGBean.java Tue Feb  1 17:59:38 2005
@@ -17,12 +17,17 @@
 
 package org.apache.geronimo.spring;
 
+import java.net.URI;
+import java.net.URL;
+import java.net.URLClassLoader;
 import java.util.Hashtable;
 import javax.management.MalformedObjectNameException;
 import javax.management.ObjectName;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.geronimo.gbean.GBeanInfo;
+import org.apache.geronimo.gbean.GBeanInfoBuilder;
 import org.apache.geronimo.gbean.GBeanLifecycle;
 import org.apache.geronimo.gbean.WaitingException;
 import org.apache.geronimo.gbean.jmx.GBeanMBean;
@@ -30,6 +35,8 @@
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.config.BeanPostProcessor;
 import org.springframework.beans.factory.support.BeanDefinitionValidationException;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
 import org.springframework.beans.factory.xml.XmlBeanFactory;
 import org.springframework.core.io.ClassPathResource;
 import org.springframework.core.io.Resource;
@@ -39,136 +46,187 @@
  *
  * @version $Rev$
  */
-public class SpringGBean implements GBeanLifecycle {
-    private static final Log log = LogFactory.getLog(SpringGBean.class);
-
-    private ObjectName objectName;
-    private String url;
-    private Kernel kernel;
-    private XmlBeanFactory factory;
+public class SpringGBean
+  implements GBeanLifecycle
+{
+  protected static final Log log = LogFactory.getLog(SpringGBean.class);
+
+  // injected into ctor
+  protected final Kernel      kernel;
+  protected final String      objectName;
+  protected final ClassLoader classLoader;
+  protected final URI[]       classPath;
+  protected final URL         configurationBaseUrl;
+  protected final URI         configPath;
+
+  protected DefaultListableBeanFactory factory;
+
+  //----------------------------------------
+  public static final GBeanInfo GBEAN_INFO;
+
+  static
+  {
+    GBeanInfoBuilder infoBuilder = new GBeanInfoBuilder("Spring Application Context", SpringGBean.class);
+
+    infoBuilder.addAttribute("kernel"               , Kernel.class      , false);
+    infoBuilder.addAttribute("objectName"           , String.class      , false);
+    infoBuilder.addAttribute("classLoader"          , ClassLoader.class , false);
+    infoBuilder.addAttribute("classPath"            , URI[].class       , true);
+    infoBuilder.addAttribute("configurationBaseUrl" , URL.class         , true);
+    infoBuilder.addAttribute("configPath"           , URI.class         , true);
+
+    infoBuilder.setConstructor(new String[]{
+				 "kernel",
+				 "objectName",
+				 "classLoader",
+				 "classPath",
+				 "configurationBaseUrl",
+				 "configPath"
+			       });
+
+    GBEAN_INFO = infoBuilder.getBeanInfo();
+  }
+
+  public static GBeanInfo getGBeanInfo() {return GBEAN_INFO;}
+
+  //----------------------------------------
+
+
+  public
+    SpringGBean(Kernel kernel, String objectName, ClassLoader classLoader, URI[] classPath, URL configurationBaseUrl, URI configPath)
+  {
+    this.kernel               =kernel;
+    this.objectName           =objectName;
+    this.configPath           =configPath;
+    this.classLoader          =classLoader;
+    this.classPath            =classPath;
+    this.configurationBaseUrl =configurationBaseUrl;
+  }
+
+  // GBeanLifecycle
+  //-------------------------------------------------------------------------
+
+  public void
+    doStart()
+    throws WaitingException, Exception
+  {
+    // set up classloader
+    URI root = URI.create(configurationBaseUrl.toString());
+
+    URL[] urls=new URL[classPath.length];
+
+    for (int i=0; i<classPath.length; i++)
+    {
+      URL url=root.resolve(classPath[i]).toURL();
+      log.info("classPath["+i+"]: "+url);
+      urls[i]=url;
+    }
+
+    ClassLoader cl=new URLClassLoader(urls, classLoader);
+
+    // delegate work to Spring framework...
+    factory=new DefaultListableBeanFactory();
+    XmlBeanDefinitionReader xbdr=new XmlBeanDefinitionReader(factory);
+    xbdr.setBeanClassLoader(cl);
+    xbdr.loadBeanDefinitions(new ClassPathResource(configPath.toString(), cl));
+
+    // force lazy construction of every bean described...
+    String[] ids=factory.getBeanDefinitionNames();
+    int n=ids.length;
+    for (int i=n; i>0; i--)
+      factory.getBean(ids[i-1]);
+    log.info("Deployed: "+n+" POJO"+(n==1?"":"s"));
+
+    // James was going to use these to register each spring-bean as
+    // a gbean - do we want to do that ?
+
+    // factory.addBeanPostProcessor(new BeanPostProcessor() {
+    // 	public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
+    // 	  return beforeInitialization(bean, name);
+    // 	}
+
+    // 	public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
+    // 	  return afterInitialization(bean, name);
+    // 	}
+    //       });
+  }
+
+  public void
+    doStop()
+    throws WaitingException, Exception
+  {
+    factory.destroySingletons();
     /*
-    private String[] springNames;
-    private Map springNameToObjectName = new HashMap();
+      if (springNames != null) {
+      for (int i = 0, size = springNames.length; i < size; i++ ) {
+      String name = springNames[i];
+      ObjectName objectName = (ObjectName) springNameToObjectName.get(name);
+      // TODO - how do we invoke the 'close' in Spring??
+      }
+      }
     */
+  }
 
-    public SpringGBean(Kernel kernel) {
-        this.kernel = kernel;
-    }
-
-    // Properties
-    //-------------------------------------------------------------------------
-    public ObjectName getObjectName() {
-        return objectName;
-    }
-
-    public void setObjectName(ObjectName objectName) {
-        this.objectName = objectName;
-    }
-
-    public String getUrl() {
-        return url;
-    }
-
-    public void setUrl(String url) {
-        this.url = url;
-    }
-
-    // GBeanLifecycle
-    //-------------------------------------------------------------------------
-
-    public void doStart() throws WaitingException, Exception {
-        if (url == null) {
-            throw new Exception("No URL specified, cannot load the Spring XML config file");
-        }
-        if (objectName == null) {
-            throw new Exception("No objectName injected for this GBean by the kernel!");
-        }
-        factory = new XmlBeanFactory(createResource());
-        factory.addBeanPostProcessor(new BeanPostProcessor() {
-            public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
-                return beforeInitialization(bean, name);
-            }
-
-            public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
-                return afterInitialization(bean, name);
-            }
-        });
-    }
-
-    public void doStop() throws WaitingException, Exception {
-        factory.destroySingletons();
-/*
-        if (springNames != null) {
-            for (int i = 0, size = springNames.length; i < size; i++ ) {
-                String name = springNames[i];
-                ObjectName objectName = (ObjectName) springNameToObjectName.get(name);
-                // TODO - how do we invoke the 'close' in Spring??
-            }
-        }
-*/
-    }
-
-    public void doFail() {
-        factory.destroySingletons();
-    }
-
-    /**
-     * Creates a resource from the current URL which by default will use the classpath
-     *
-     * @return
-     */
-    protected Resource createResource() {
-        return new ClassPathResource(url);
-    }
-
-    /**
-     * Do we need to apply an interceptor to the bean?
-     */
-    protected Object beforeInitialization(Object bean, String name) {
-        // we could add some interceptor stuff here if we like
-        return bean;
-    }
-
-    /**
-     * Create an GBean wrapper
-     */
-    protected Object afterInitialization(Object bean, String name) throws BeansException {
-        try {
-            ObjectName objectName = createObjectName(name);
-            /*
-            springNameToObjectName.put(name, objectName);
-            */
-            GBeanMBean gbean = createGBean(bean, name);
-            if (gbean == null) {
-                log.warn("No GBean available for name: " + name + " bean: " + bean);
-            }
-            else {
-                kernel.loadGBean(objectName, gbean);
-            }
-        }
-        catch (Exception e) {
-            throw new BeanDefinitionValidationException("Could not load the GBean for name: " + name + " bean: " + bean + ". Reason: " + e, e);
-        }
-        return bean;
-    }
-
-    /**
-     * Factory method to create an ObjectName for the Spring bean
-     *
-     * @param name the name of the bean in the Spring config file
-     * @return the ObjectName to use for the given Spring bean name
-     */
-    protected ObjectName createObjectName(String name) throws MalformedObjectNameException {
-        Hashtable nameProps = new Hashtable(objectName.getKeyPropertyList());
-        nameProps.put("name", name);
-        return new ObjectName(objectName.getDomain(), nameProps);
-    }
-
-    /**
-     * @return a newly created GBeanMBean for the given bean
-     */
-    protected GBeanMBean createGBean(Object bean, String name) {
-        // TODO
-        return null;
-    }
-}
\ No newline at end of file
+  public void
+    doFail()
+  {
+    factory.destroySingletons();
+  }
+
+  /**
+   * Do we need to apply an interceptor to the bean?
+   */
+  protected Object
+    beforeInitialization(Object bean, String name)
+  {
+    // we could add some interceptor stuff here if we like
+    return bean;
+  }
+
+  /**
+   * Create an GBean wrapper
+   */
+  protected Object afterInitialization(Object bean, String name)
+    throws BeansException
+  {
+    //     try {
+    //       ObjectName objectName = createObjectName(name);
+    //       /*
+    //  	springNameToObjectName.put(name, objectName);
+    //       */
+    //       GBeanMBean gbean = createGBean(bean, name);
+    //       if (gbean == null) {
+    //  	log.warn("No GBean available for name: " + name + " bean: " + bean);
+    //       }
+    //       else {
+    //  	kernel.loadGBean(objectName, gbean);
+    //       }
+    //     }
+    //     catch (Exception e) {
+    //       throw new BeanDefinitionValidationException("Could not load the GBean for name: " + name + " bean: " + bean + ". Reason: " + e, e);
+    //     }
+    return bean;
+  }
+
+  /**
+   * Factory method to create an ObjectName for the Spring bean
+   *
+   * @param name the name of the bean in the Spring config file
+   * @return the ObjectName to use for the given Spring bean name
+   */
+//   protected ObjectName createObjectName(String name) throws MalformedObjectNameException {
+//     Hashtable nameProps = new Hashtable(objectName.getKeyPropertyList());
+//     nameProps.put("name", name);
+//     return new ObjectName(objectName.getDomain(), nameProps);
+//   }
+
+  /**
+   * @return a newly created GBeanMBean for the given bean
+   */
+//   protected GBeanMBean
+//     createGBean(Object bean, String name)
+//   {
+//     // TODO
+//     return null;
+//   }
+}