User: cgjung  
  Date: 01/05/18 08:14:19

  Added:       src/main/org/jboss/deployment/scope
                        J2eeGlobalScopeDeployer.java Scope.java
                        ScopedURLClassLoader.java package.html
  Log:
  First "official" try for a scoped application deployer that is able to build
  "virtual" applications out of dependent ear�s. Currently reads dependency information
  from property file. setup of application management information is not yet
  correct.
  
  Revision  Changes    Path
  1.1                  
jboss/src/main/org/jboss/deployment/scope/J2eeGlobalScopeDeployer.java
  
  Index: J2eeGlobalScopeDeployer.java
  ===================================================================
  /*
   * JBoss, the OpenSource EJB server
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  
  package org.jboss.deployment.scope;
  
  import org.jboss.deployment.Deployment;
  import org.jboss.mgt.Application;
  import org.jboss.deployment.J2eeDeploymentException;
  import java.net.URL;
  import java.net.MalformedURLException;
  import java.net.URLClassLoader;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Collection;
  import java.util.Set;
  import java.io.IOException;
  import javax.management.ObjectName;
  import javax.management.MBeanException;
  import javax.management.RuntimeMBeanException;
  import javax.management.RuntimeErrorException;
  import javax.management.JMException;
  
  
  /**
   * This is an example deployer that uses the J2ee application scoping facility and
   * implements a proper (re-)deployment procedure.
   * In this case, we introduce a global scope.
   * @author  cgjung
   * @version 0.8
   */
  
  public class J2eeGlobalScopeDeployer extends org.jboss.deployment.J2eeDeployer {
      
      /** the global scope */
      protected Scope globalScope=null;
      
      /** Creates new J2eeDependencyDeployer */
      public J2eeGlobalScopeDeployer() {
      }
      
      /** starts the service by first creating
       * a new scope
       * @throws Exception to indicate
       * that either superclass or scope creation
       * went wrong.
       */
      public void startService() throws Exception {
          globalScope=createScope();
          super.startService();
      }
      
      /** factory method to create a new scope, May throw a general exception
       * if this very basic enterprise fails.
       * @throws Exception May throw any exception to indicate
       * instantiation problems of the scope (probably
       * because initial meta-data could not be found,
       * is corrupt, etc.)
       * @return a freshly instantiated and preconfigured scope.
       *
       */
      protected Scope createScope() throws Exception {
          return new Scope(log);
      }
      
      /** stops the service by freeing
       * scope afterwards
       */
      public void stopService() {
          super.stopService();
          globalScope=null;
      }
      
      
      /**
       * creates an application class loader for this deployment
       * this class loader will be shared between jboss and
       * tomcat via the contextclassloader
       * we include all ejb and web-modules at this level
       * to also be able to connect flat ejb-jars to each other
       * @param deployment the deployment that is about to be made,
       * but is already installed
       *
       * @throws J2eeDeploymentException to indicate
       * problems with instantiating the classloader
       * (maybe if reading some meta-data did not work properly)
       */
      protected void createContextClassLoader(Deployment deployment) throws 
J2eeDeploymentException {
          
          try{
              // get urls we want all classloaders of this application to share
              Set allUrls=new java.util.HashSet();
              
              // first we add the common urls (as does our parent)
              Iterator allCommonUrls=deployment.getCommonUrls().iterator();
              
              while(allCommonUrls.hasNext())
                  allUrls.add(allCommonUrls.next());
              
              // then the ejbmodules urls
              Iterator allEjbModules=deployment.getEjbModules().iterator();
              
              while(allEjbModules.hasNext()) {
                  Iterator allLocalUrls=((Deployment.Module) 
allEjbModules.next()).getLocalUrls().iterator();
                  while(allLocalUrls.hasNext())
                      allUrls.add(allLocalUrls.next());
              }
              
              // then the web modules urls
              Iterator allWebModules=deployment.getWebModules().iterator();
              
              while(allWebModules.hasNext()) {
                  Iterator allLocalUrls=((Deployment.Module) 
allWebModules.next()).getLocalUrls().iterator();
                  while(allLocalUrls.hasNext())
                      allUrls.add(allLocalUrls.next());
              }
              
              // create classloader with parent from context
              ClassLoader parent = Thread.currentThread().getContextClassLoader();
              // using the factory method
              ScopedURLClassLoader appCl = createScopedContextClassLoader((URL[]) 
allUrls.toArray(new URL[allUrls.size()]),parent,deployment);
              
              // set the result loader as the context class
              // loader for the deployment thread
              Thread.currentThread().setContextClassLoader(appCl);
          } catch(Exception e) {
              throw new J2eeDeploymentException("could not construct context 
classloader",e);
          }
      }
      
      /** factory method for scoped url classloaders factored out. May throw a general
       * exception if this enterprise fails.
       * @param urls the urls for which the scoped
       * classloader should be generated
       *
       * @param parent the parent loader
       *
       * @param deployment the deployment to which this classloader is
       * associated.
       *
       * @throws Exception to indicate
       * problems in constructing the
       * classloader (maybe because
       * meta-data was corrupt).
       *
       * @return a freshly instantiated and configured class loader
       *
       */
      protected ScopedURLClassLoader createScopedContextClassLoader(URL[] 
urls,ClassLoader parent,Deployment deployment) throws Exception {
          return new ScopedURLClassLoader(urls,parent,deployment,globalScope);
      }
      
      /** Overrides the normal (re-)deploy method in order to
       * take dependent applications into account.
       *
       * @param _url the url (file or http) to the archiv to deploy
       * @throws MalformedURLException in case of a malformed url
       * @throws J2eeDeploymentException if something went wrong...
       * @throws IOException if trouble while file download occurs
       */
      public void deploy(String _url) throws MalformedURLException, IOException, 
J2eeDeploymentException {
          URL url = new URL(_url);
          
          ObjectName lCollector = null;
          try {
              lCollector = new ObjectName( "Management", "service", "Collector" );
          }
          catch( Exception e ) {
          }
          
          // initialise teared down deployments just in case that nothing
          // is teared down
          List allTearedDown=new java.util.ArrayList();
          
          // undeploy first if it is a redeploy
          try {
              // use modified undeploy in order to tear down
              // dependent apps as well
              undeployWithDependencies(_url,allTearedDown,url);
              // Remove application data by its id
              server.invoke(
              lCollector,
              "removeApplication",
              new Object[] { _url },
              new String[] { "java.lang.String" }
              );
          } catch (Exception _e) {
              // fresh deployment case
              allTearedDown.add(url);
          }
          
          // now we (re-)deploy the whole bunch that was teared down
          // with us
          Iterator allDeployments=allTearedDown.iterator();
          
          while(allDeployments.hasNext()) {
              URL nextUrl=(URL) allDeployments.next();
              // maybe this deployment has already been made as
              // a side effect
              Deployment d = installer.findDeployment(nextUrl.toString());
              
              if(d==null) {
                  log.log("(Re-)Deploy J2EE application: " + nextUrl);
                  d=installApplication(nextUrl);
                  
                  try {
                      startApplication(d);
                      log.log("J2EE application: " + nextUrl + " is (re-)deployed.");
                      try {
                          // Now the application is deployed add it to the server data 
collector
                          Application lApplication = convert2Application( _url, d );
                          server.invoke(
                          lCollector,
                          "saveApplication",
                          new Object[] {
                              _url,
                              lApplication
                          },
                          new String[] {
                              "java.lang.String",
                              lApplication.getClass().getName()
                          }
                          );
                      }
                      catch( Exception e ) {
                          log.log("Report of deployment of J2EE application: " + _url 
+ " could not be reported.");
                      }
                  } catch (Exception _e) {
                      try {
                          stopApplication(d);
                      }
                      catch (Exception _e2) {
                          log.error("unable to stop application "+d.getName()+": 
"+_e2);
                      }
                      finally {
                          try {
                              uninstallApplication(_url);
                          }
                          catch (Exception _e3) {
                              log.error("unable to uninstall application 
"+d.getName()+": "+_e3);
                          }
                      }
                      
                      if (_e instanceof J2eeDeploymentException) {
                          throw (J2eeDeploymentException)_e;
                      }
                      else {
                          log.exception(_e);
                          throw new J2eeDeploymentException("fatal error: "+_e);
                      }
                  }
              }
          }
      }
      
      /** A new stop method that stops a running deployment
       * and its dependent applications and that logs their
       * urls (where the current deployment will be redeployed under newUrl)
       * in a set for redeployment.
       *
       * @param _d deployment to stop
       *
       * @param redeployUrls collects the sourceUrls of the
       * undeployed apps
       *
       * @param newUrl the url under which the current deployment should be 
redeployed, if at all
       *
       * @throws J2eeDeploymentException  to
       * indicate problems in undeployment.
       */
      protected void stopApplication(Deployment _d, List redeployUrls, URL newUrl) 
throws J2eeDeploymentException {
          // synchronize on the scope
          synchronized(globalScope.classLoaders) {
              
              // find out the corresponding classloader
              ScopedURLClassLoader source=(ScopedURLClassLoader)
              globalScope.classLoaders.get(_d.getLocalUrl());
              
              // its still here, so the thing is not already stopped
              if(source!=null) {
                  
                  try{
                      log.log("About to stop application "+_d.getName());
                  
                  // add it to the stopped list
                  redeployUrls.add(newUrl);
                  // get dependency information
                  Iterator 
allDependencies=globalScope.getDependentClassLoaders(source).
                  iterator();
                  // deregister classloader
                  globalScope.deRegisterClassLoader(source);
                  
                  // first stop the dependent stuff
                  while(allDependencies.hasNext()) {
                      ScopedURLClassLoader dependentLoader=(ScopedURLClassLoader) 
allDependencies.next();
                      
                      
stopApplication(dependentLoader.deployment,redeployUrls,dependentLoader.deployment.getSourceUrl());
                  }
                  
                  } finally {
                      
                      try{
                          // now we do the real stopping
                          super.stopApplication(_d);
                  
                          // and leave a last message to the classloader to
                          // tear down meta-data or such
                          source.onUndeploy();
                      } finally {
                          try{
                              uninstallApplication(_d);
                          } catch(IOException e) {
                              log.error("could not properly uninstall "+_d.getName());
                          }
                      }
                  }
                  
              } // if
          } // sync
          
      }
      
      /**  Overrides the proper stop in order to
       *   be redirected to the dependency stopper
       *   @param _d the deployment to stop
       *   @throws J2eeDeploymentException if an error occures for one of these
       *           modules
       */
      protected void stopApplication(Deployment _d) throws J2eeDeploymentException {
          stopApplication(_d,new java.util.ArrayList(),_d.getSourceUrl());
      }
      
      /** Undeploys the given URL (if it is deployed) and returns an array
       * of deployments that have been teared down
       * Actually only the file name is of interest, so it dont has to be
       * an URL to be undeployed, the file name is ok as well.
       * @param _app the stirng spec of the app to tear down
       *
       * @param allTearedDown collection of deployments that have been teared down as 
a result.
       *
       * @param newUrl url under which the application is to be redeployed, if at all
       *
       * @throws J2eeDeploymentException if something went wrong (but should have 
removed all files)
       * @throws IOException if file removement fails
       */
      public void undeployWithDependencies(String _app, List allTearedDown, URL 
newUrl) throws IOException, J2eeDeploymentException {
          // find currect deployment
          Deployment d = installer.findDeployment(_app);
          
          if (d == null)
              throw new J2eeDeploymentException("The application \""+name+"\" has not 
been deployed.");
          
          try {
              // use dependency stopper
              stopApplication(d, allTearedDown, newUrl);
          }
          catch (J2eeDeploymentException _e) {
              throw _e;
          }
          
      }
      
      /** Starts the successful downloaded deployment. <br>
       * Means the modules are deployed by the responsible container deployer
       * This version of the method does indeed start necessary
       * other applications as well.
       * @param dep the deployment to start
       *
       * @throws J2eeDeploymentException if an error occures for one of these
       *          modules
       */
      protected void startApplication(Deployment dep) throws J2eeDeploymentException {
          // here we collect all the started deployments (not only dep)
          // indexed by the sourceUrl
          Collection deployments=new java.util.ArrayList();
          
          startApplication(dep, deployments);
          
          Iterator allDeployments=deployments.iterator();
          
          while(allDeployments.hasNext()) {
              
              Deployment _d=(Deployment) allDeployments.next();
              
              // save the old classloader
              ClassLoader oldCl = Thread.currentThread().
              getContextClassLoader();
              
              // find out the corresponding classloader
              ScopedURLClassLoader source=(ScopedURLClassLoader)
              globalScope.classLoaders.get(_d.getLocalUrl());
              
              Thread.currentThread().setContextClassLoader(source);
              
              // redirect all modules to the responsible deployers
              Deployment.Module m = null;
              String moduleName = null;
              String message;
              try {
                  // Tomcat
                  Iterator it = _d.getWebModules().iterator();
                  if (it.hasNext() && !warDeployerAvailable())
                      throw new J2eeDeploymentException("application contains war 
files but no web container available");
                  
                  
                  while (it.hasNext()) {
                      m = (Deployment.Module)it.next();
                      moduleName = m.getName();
                      log.log("Starting module " + moduleName);
                      
                      // Call the TomcatDeployer that is loaded in the JMX server
                      server.invoke(warDeployer, "deploy",
                      new Object[] { m.getWebContext(), 
m.getLocalUrls().firstElement().toString()}, new String[] { "java.lang.String", 
"java.lang.String" });
                      
                      // since tomcat changes the context classloader...
                      Thread.currentThread().setContextClassLoader(source);
                  }
                  
                  // JBoss
                  // gather the ejb module urls and deploy the application
                  moduleName = _d.getName();
                  Collection tmp = new java.util.Vector();
                  for( it = _d.getEjbModules().iterator(); it.hasNext(); ) {
                      m = (Deployment.Module) it.next();
                      tmp.add( m.getLocalUrls().firstElement().toString() );
                  }
                  String[] jarUrls = new String[ tmp.size() ];
                  tmp.toArray( jarUrls );
                  // Call the ContainerFactory that is loaded in the JMX server
                  server.invoke(jarDeployer, "deploy",
                  new Object[]{ _d.getLocalUrl().toString(), jarUrls }, new String[]{ 
String.class.getName(), String[].class.getName() } );
              }
              catch (MBeanException _mbe) {
                  log.error("Starting "+moduleName+" failed!");
                  throw new J2eeDeploymentException("Error while starting 
"+moduleName+": " + _mbe.getTargetException().getMessage(), _mbe.getTargetException());
              }
              catch (RuntimeErrorException e) {
                  log.error("Starting "+moduleName+" failed!");
                  e.getTargetError().printStackTrace();
                  throw new J2eeDeploymentException("Error while starting 
"+moduleName+": " + e.getTargetError().getMessage(), e.getTargetError());
              }
              catch (RuntimeMBeanException e) {
                  log.error("Starting "+moduleName+" failed!");
                  e.getTargetException().printStackTrace();
                  throw new J2eeDeploymentException("Error while starting 
"+moduleName+": " + e.getTargetException().getMessage(), e.getTargetException());
              }
              catch (JMException _jme) {
                  log.error("Starting failed!");
                  throw new J2eeDeploymentException("Fatal error while interacting 
with deployer MBeans... " + _jme.getMessage());
              }
              finally {
                  Thread.currentThread().setContextClassLoader(oldCl);
              }
          }
          
      }
      
      /** Starts the successful downloaded deployment. <br>
       * Means the modules are deployed by the responsible container deployer
       * <comment author="cgjung">better be protected for subclassing </comment>
       * @param alreadyMarked the deployments that have already been installed and
       * that  must be properly deployed afterwards.
       * @param _d the deployment to start
       * @throws J2eeDeploymentException if an error occures for one of these
       *          modules
       */
      protected void startApplication(Deployment _d, Collection alreadyMarked) throws 
J2eeDeploymentException {
          
          ClassLoader parent=Thread.currentThread().getContextClassLoader();
          
          // set the context classloader for this application
          createContextClassLoader(_d);
          
          // save the application classloader for later
          ScopedURLClassLoader appCl = (ScopedURLClassLoader)
          Thread.currentThread().getContextClassLoader();
          
          alreadyMarked.add(_d);
          
          String[] dependentStuff=appCl.getDependingApplications();
          
          for(int count=0;count<dependentStuff.length;count++) {
  
              // reinstall parent 
              Thread.currentThread().setContextClassLoader(parent);
              
              try{
                  URL absoluteUrl=new URL(_d.getSourceUrl(),dependentStuff[count]);
                  
                  Deployment newD=installer.findDeployment(absoluteUrl.toString());
                  
                  if(newD==null) {
                      newD = installApplication(absoluteUrl);
                
                      startApplication(newD,alreadyMarked);
                  }
              } catch(MalformedURLException e) {
                  throw new J2eeDeploymentException("could not construct url for 
dependent application "+dependentStuff[count],e);
              } catch(IOException e) {
                  throw new J2eeDeploymentException("io problem when trying to access 
dependent application "+dependentStuff[count],e);
              } 
              
              
          } // for
          
          // reinstall parent 
              Thread.currentThread().setContextClassLoader(parent);
              
      }
  }
  
  
  
  1.1                  jboss/src/main/org/jboss/deployment/scope/Scope.java
  
  Index: Scope.java
  ===================================================================
  /*
   * JBoss, the OpenSource EJB server
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  
  package org.jboss.deployment.scope;
  
  import org.jboss.logging.Log;
  
  import java.util.Set;
  import java.util.Map;
  import java.util.Iterator;
  
  import java.net.URL;
  
  /**
   * Scope is a manager/mediator that connects several ScopedURLClassLoaders
   * with each other and computes their dependencies. The locks used in the scope
   * implementation are quite coarse-grained, maybe thread-unfriendly, but the
   * rationale is that classloading a) happens not too often (hopefully) in the
   * lifecycle of an application b) will dispatch only in special cases (where 
applications depliberately
   * share classes) to this scope class and c) is optimized by caching the locations.
   * @author  cgjung
   * @version 0.8
   */
  
  public class Scope {
      
      /** keeps a map of class loaders that participate in this scope */
      final protected Map classLoaders=new java.util.HashMap();
      
      /** keeps a hashtable of dependencies between the classLoaders */
      final protected Map dependencies=new java.util.HashMap();
      
      /** keeps a hashtable of class appearances */
      final protected Map classLocations=new java.util.HashMap();
      
      /** keeps a hashtable of resource appearances */
      final protected Map resourceLocations=new java.util.HashMap();
      
      /** keeps a reference to a logger which which to interact */
      final protected Log log;
      
      /** Creates new Scope */
      public Scope(Log log) {
          this.log=log;
      }
      
      /** registers a classloader in this scope */
      public ScopedURLClassLoader registerClassLoader(ScopedURLClassLoader loader) {
          // must synchronize not to collide with deregistrations and
          // dependency logging
          synchronized(classLoaders) {
              return (ScopedURLClassLoader) 
classLoaders.put(loader.deployment.getLocalUrl(),loader);
          }
      }
      
      
      /** deRegisters a classloader in this scope
       *  removes all cached data related to this classloader
       */
      public ScopedURLClassLoader deRegisterClassLoader(ScopedURLClassLoader loader) {
          // synchronized not to collide with registrations
          // and dependency logging
          synchronized(classLoaders) {
              // remove class locations
              clearByValue(classLocations,loader);
              // remove resource locations
              clearByValue(resourceLocations,loader);
              // remove dependency annotations
              dependencies.remove(loader);
              // and remove the loader
              return (ScopedURLClassLoader) 
classLoaders.remove(loader.deployment.getLocalUrl());
          }
      }
      
      /** helper method that will clear all entries from a map
       *  with a dedicated target value.
       */
      protected void clearByValue(Map map, Object value) {
          Iterator values=map.values().iterator();
          while(values.hasNext()) {
              if(values.next().equals(value))
                  // uses the very useful remove method of the value iterator!
                  values.remove();
          }
      }
      
      /** returns the classLoaders that a particular classLoader is
       *  dependent on. Should be called after locking classLoaders
       */
      public Set getDependentClassLoaders(ScopedURLClassLoader loader) {
          Set result=(Set) dependencies.get(loader);
          if(result==null)
              result=new java.util.HashSet();
          return result;
      }
      
      /** adds a dependency between two classloaders. this can be called
       *  from within application threads that require resource loading.
       *  Should be called after locking classLoaders
       */
      protected boolean addDependency(ScopedURLClassLoader source, 
ScopedURLClassLoader target) {
          // no rescursions necessary (but not volatile for the code)
          if(!source.equals(target)) {
              
              Set deps=(Set) dependencies.get(target);
              
              if(deps==null) {
                  deps=new java.util.HashSet();
                  dependencies.put(target,deps);
              }
              
              log.debug("Adding dependency from deployment 
"+source+":"+source.deployment.getLocalUrl()+" to deployment "+
                  target+":"+target.deployment.getLocalUrl());
              
              return deps.add(source);
          } else
              return false;
      }
      
      /** loads a class on behalf of a given classloader */
      public Class loadClass(String className, ScopedURLClassLoader source, boolean 
resolve)
      throws ClassNotFoundException {
          
          // short look into the class location cache, is synchronized in
          // case that the relevant target is simultaneously teared down
          synchronized(classLoaders) {
              ScopedURLClassLoader target= (ScopedURLClassLoader)
              classLocations.get(className);
              
              // its there, so log and load it
              if(target!=null) {
                  addDependency(source,target);
                  // we can be sure that the target loader
                  // has the class already in its own cache
                  // so this call should not cost much
                  return target.loadClass(className,resolve);
              }
              
              // otherwise we do a big lookup
              Iterator allLoaders=classLoaders.values().iterator();
          
              while(allLoaders.hasNext()) {
                  target=(ScopedURLClassLoader) allLoaders.next();
              
              // no recursion, please
              if(!target.equals(source)) {
                  try{
                      Class foundClass=target.loadClassProperly(className,resolve);
                      classLocations.put(className,target);
                      addDependency(source,target);
                      return foundClass;
                  } catch(ClassNotFoundException e) {
                      // proceed with the next loaders in scope
                  }
              }
          } // while
          
          // no loader in the scope has been able to load the class
          throw new ClassNotFoundException("could not resolve class "+
          className+" in scope.");
          
          } // sync
      }
      
      /** gets a URL on behalf of a given classloader */
      public URL getResource(String name, ScopedURLClassLoader source) {
          
          // short look into the resource location cache, is synchronized in
          // case that the relevant target is simultaneously teared down
          synchronized(classLoaders) {
              ScopedURLClassLoader target= (ScopedURLClassLoader)
                  resourceLocations.get(name);
              
              // its there, so log and load it
              if(target!=null)
                  addDependency(source,target);
          
             // the lock is released here, so that other threads could run too
              if(target!=null)
                  return target.getResource(name);
          
              // otherwise we do a big lookup
              Iterator allLoaders=classLoaders.values().iterator();
          
              while(allLoaders.hasNext()) {
                  target=(ScopedURLClassLoader) allLoaders.next();
              
              // no recursion, please
              if(!target.equals(source)) {
                      URL foundResource=target.getResourceProperly(name);
                      if(foundResource!=null) {
                          resourceLocations.put(name,target);
                          addDependency(source,target);
                          return foundResource;
                      }
              }
          } // while
          
          // no loader in the scope has been able to load the resource
          return null;
          
          } // sync
      }
  
  }
  
  
  
  1.1                  
jboss/src/main/org/jboss/deployment/scope/ScopedURLClassLoader.java
  
  Index: ScopedURLClassLoader.java
  ===================================================================
  /*
  * JBoss, the OpenSource EJB server
  *
  * Distributable under LGPL license.
  * See terms of license at gnu.org.
  */
  
  package org.jboss.deployment.scope;
  
  import org.jboss.deployment.Deployment;
  import java.net.URL;
  import java.net.URLClassLoader;
  
  import java.util.Collection;
  
  /**
   * A URLClassLoader that is tight to some J2EE deployment and that is 
   * able to share classes/resources under the associated scope. Hey, JDK-S**ckers
   * why did you annotate getResources final? 
   * @author  cgjung
   * @version 0.9
   */
  public class ScopedURLClassLoader extends URLClassLoader {
  
      /** reference to the scope to which resource loading calls
       *  can be delegated to. 
       */
      final protected Scope scope;
      
      /**
       * reference to the deployment that is associated
       * with this classloader
       */
      final protected Deployment deployment;
      
  
      /** Creates new ScopedURLClassLoader given a set of urls and a parent,
       *  representing a particular deployment */
      public ScopedURLClassLoader(URL[] urls, ClassLoader parent, Deployment 
deployment, Scope scope) {
          super(urls,parent);
          this.scope=scope;
          this.deployment=deployment;
          scope.registerClassLoader(this);
      }
      
      /** exposes the proper loadClass call */
      protected Class loadClassProperly(String name, boolean resolve) throws 
ClassNotFoundException {
          return super.loadClass(name,resolve);
      }
      
      /** redirects loadClass in case that it could not be found locally */
      protected Class loadClass(String name, boolean resolve) throws 
ClassNotFoundException {
          try{
              return super.loadClass(name,resolve);
          } catch(ClassNotFoundException e) {
              // redirect
              return scope.loadClass(name,this,resolve);
          }
      }
              
      /** exposes the proper getResource call */
      protected URL getResourceProperly(String name) {
          return super.getResource(name);
      }
      
      /** redirects getResource in case that it could not be found locally */
      public URL getResource(String name) {
          URL result=super.getResource(name);
          if(result==null)
              result=scope.getResource(name,this);
          return result;
      }
      
      /** what happens on undeploy, could be overridden to tear down meta-data and 
such */
      protected void onUndeploy() {
          // nothing
      }
  
      /** returns a set of relative urls in string spec that
       *  point to applications to which this application
       *  is (most likely) dependent on
       *  this feature is only prototypically implemented using a property file
       */
      public String[] getDependingApplications() {
          try{
              java.util.Properties localProps=new java.util.Properties();
              
              
localProps.load(getResourceProperly("META-INF/org.jboss.deployment.scope.properties").openStream());
              
              java.util.StringTokenizer tok=
                  new 
java.util.StringTokenizer(localProps.getProperty("org.jboss.deployment.scope.dependencies",""),";");
              
              Collection allDeps=new java.util.ArrayList();
              
              while(tok.hasMoreTokens())
                  allDeps.add(tok.nextToken());
              
              return (String[]) allDeps.toArray(new String[allDeps.size()]);
          } catch(Exception e) {
              return new String[0];
          }
      }
      
      
  
  }
  
  
  
  1.1                  jboss/src/main/org/jboss/deployment/scope/package.html
  
  Index: package.html
  ===================================================================
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  
  <HTML>
    <HEAD>
      <TITLE></TITLE>
    </HEAD>
    <BODY>
      This package hosts an extension to the J2eeDeployer that is able to
      virtually merge J2EE applications into a so-called scope. These
      scoped applications are able to share classes and resources. The dependencies 
      between the applications are logged and used to coherently undeploy parts
      of the scope.
    </BODY>
  </HTML>
  
  
  

_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to