|  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

hummmmm what is this "reads dependency information" from property file
thing.  The URLClassLoader I posted in December works totally implicitely,
we need an implicit design.  Care to explain what this design does with
respect to finding the right class in the VM?

marc

|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,dependentLo
|ader.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.deploym
|ent.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



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

Reply via email to