| 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