[jboss-cvs] JBossAS SVN: r57455 - in trunk: server/src/main/org/jboss/naming server/src/main/org/jboss/web tomcat tomcat/src/main/org/jboss/web/tomcat/tc6 tomcat/src/main/org/jboss/web/tomcat/tc6/deployers
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Thu Oct 5 17:51:15 EDT 2006
Author: scott.stark at jboss.org
Date: 2006-10-05 17:51:03 -0400 (Thu, 05 Oct 2006)
New Revision: 57455
Added:
trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/deployers/TomcatDeployment.java
Modified:
trunk/server/src/main/org/jboss/naming/JNDIView.java
trunk/server/src/main/org/jboss/web/AbstractWebDeployer.java
trunk/server/src/main/org/jboss/web/WebApplication.java
trunk/tomcat/.classpath
trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/TomcatDeployer.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/TomcatInjectionContainer.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/WebAppLoader.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/WebCtxLoader.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/deployers/WarDeployer.java
Log:
Refactoring for VDF
Modified: trunk/server/src/main/org/jboss/naming/JNDIView.java
===================================================================
--- trunk/server/src/main/org/jboss/naming/JNDIView.java 2006-10-05 19:36:02 UTC (rev 57454)
+++ trunk/server/src/main/org/jboss/naming/JNDIView.java 2006-10-05 21:51:03 UTC (rev 57455)
@@ -106,7 +106,7 @@
Thread.currentThread().setContextClassLoader(webApplication.getMetaData().getENCLoader());
- buffer.append("<h2>java:comp namespace of the " + webApplication.getDeploymentInfo().getCanonicalName()
+ buffer.append("<h2>java:comp namespace of the " + webApplication.getCanonicalName()
+ " application:</h2>\n");
try
@@ -280,7 +280,7 @@
while ( it.hasNext()==true )
{
WebApplication webApplication = (WebApplication) it.next();
- openWebModuleTag(buffer, webApplication.getDeploymentInfo().getCanonicalName());
+ openWebModuleTag(buffer, webApplication.getCanonicalName());
Thread.currentThread().setContextClassLoader(webApplication.getMetaData().getENCLoader());
Modified: trunk/server/src/main/org/jboss/web/AbstractWebDeployer.java
===================================================================
--- trunk/server/src/main/org/jboss/web/AbstractWebDeployer.java 2006-10-05 19:36:02 UTC (rev 57454)
+++ trunk/server/src/main/org/jboss/web/AbstractWebDeployer.java 2006-10-05 21:51:03 UTC (rev 57455)
@@ -383,7 +383,6 @@
Policy.getPolicy().refresh();
warInfo = new WebApplication(webMetaData);
- warInfo.setDeploymentInfo(di);
warInfo.setClassLoader(warLoader);
performDeploy(warInfo, warURL.toString(), webAppParser);
}
Modified: trunk/server/src/main/org/jboss/web/WebApplication.java
===================================================================
--- trunk/server/src/main/org/jboss/web/WebApplication.java 2006-10-05 19:36:02 UTC (rev 57454)
+++ trunk/server/src/main/org/jboss/web/WebApplication.java 2006-10-05 21:51:03 UTC (rev 57455)
@@ -22,6 +22,9 @@
package org.jboss.web;
import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
import org.jboss.metadata.WebMetaData;
import org.jboss.deployment.DeploymentInfo;
@@ -36,17 +39,38 @@
public class WebApplication
{
/** Class loader of this application */
- ClassLoader classLoader = null;
+ protected ClassLoader classLoader = null;
/** name of this application */
- String name = "";
+ protected String name = "";
+ protected String canonicalName;
/** URL where this application was deployed from */
- URL url;
+ protected URL url;
/** The web app metadata from the web.xml and jboss-web.xml descriptors */
- WebMetaData metaData;
+ protected WebMetaData metaData;
/** Arbitary data object for storing application specific data */
- Object data;
- /** The DeploymentInfo for the war */
- DeploymentInfo warInfo;
+ protected Object data;
+ /** The jmx domain of the web container */
+ protected String domain;
+ /**
+ * The parent class loader first model flag
+ */
+ protected boolean java2ClassLoadingCompliance = false;
+ /**
+ * A flag indicating if war archives should be unpacked
+ */
+ protected boolean unpackWars = true;
+ /**
+ * If true, ejb-links that don't resolve don't cause an error (fallback to
+ * jndi-name)
+ */
+ protected boolean lenientEjbLink = false;
+ /**
+ * The default security-domain name to use
+ */
+ protected String defaultSecurityDomain;
+ protected HashMap vhostToHostNames = new HashMap();
+ /** Deployer config bean */
+ protected Object deployerConfig;
/** Create an empty WebApplication instance
*/
@@ -111,6 +135,14 @@
this.name = name;
}
+ public String getCanonicalName()
+ {
+ return canonicalName;
+ }
+ public void setCanonicalName(String canonicalName)
+ {
+ this.canonicalName = canonicalName;
+ }
/** Get the URL from which this WebApplication was deployed
* @return URL where this application was deployed from
@@ -156,16 +188,124 @@
this.data = data;
}
- public DeploymentInfo getDeploymentInfo()
+
+ public String getDomain()
{
- return warInfo;
+ return domain;
}
+ public void setDomain(String domain)
+ {
+ this.domain = domain;
+ }
+ /**
+ * Get the flag indicating if the normal Java2 parent first class loading
+ * model should be used over the servlet 2.3 web container first model.
+ * @return true for parent first, false for the servlet 2.3 model
+ * @jmx.managed-attribute
+ */
+ public boolean getJava2ClassLoadingCompliance()
+ {
+ return java2ClassLoadingCompliance;
+ }
- public void setDeploymentInfo(DeploymentInfo warInfo)
+ /**
+ * Set the flag indicating if the normal Java2 parent first class loading
+ * model should be used over the servlet 2.3 web container first model.
+ * @param flag true for parent first, false for the servlet 2.3 model
+ * @jmx.managed-attribute
+ */
+ public void setJava2ClassLoadingCompliance(boolean flag)
{
- this.warInfo = warInfo;
+ java2ClassLoadingCompliance = flag;
}
+ /**
+ * Get the flag indicating if war archives should be unpacked. This may need
+ * to be set to false as long extraction paths under deploy can show up as
+ * deployment failures on some platforms.
+ * @return true is war archives should be unpacked
+ * @jmx.managed-attribute
+ */
+ public boolean getUnpackWars()
+ {
+ return unpackWars;
+ }
+
+ /**
+ * Get the flag indicating if war archives should be unpacked. This may need
+ * to be set to false as long extraction paths under deploy can show up as
+ * deployment failures on some platforms.
+ * @param flag , true is war archives should be unpacked
+ * @jmx.managed-attribute
+ */
+ public void setUnpackWars(boolean flag)
+ {
+ this.unpackWars = flag;
+ }
+
+ /**
+ * Get the flag indicating if ejb-link errors should be ignored in favour of
+ * trying the jndi-name in jboss-web.xml
+ * @return a <code>boolean</code> value
+ * @jmx.managed-attribute
+ */
+ public boolean getLenientEjbLink()
+ {
+ return lenientEjbLink;
+ }
+
+ /**
+ * Set the flag indicating if ejb-link errors should be ignored in favour of
+ * trying the jndi-name in jboss-web.xml
+ * @jmx.managed-attribute
+ */
+ public void setLenientEjbLink(boolean flag)
+ {
+ lenientEjbLink = flag;
+ }
+
+ /**
+ * Get the default security domain implementation to use if a war does not
+ * declare a security-domain.
+ * @return jndi name of the security domain binding to use.
+ * @jmx.managed-attribute
+ */
+ public String getDefaultSecurityDomain()
+ {
+ return defaultSecurityDomain;
+ }
+
+ /**
+ * Set the default security domain implementation to use if a war does not
+ * declare a security-domain.
+ * @param defaultSecurityDomain - jndi name of the security domain binding to
+ * use.
+ * @jmx.managed-attribute
+ */
+ public void setDefaultSecurityDomain(String defaultSecurityDomain)
+ {
+ this.defaultSecurityDomain = defaultSecurityDomain;
+ }
+
+ public Map getVhostToHostNames()
+ {
+ return this.vhostToHostNames;
+ }
+ public void setVhostToHostNames(Map map)
+ {
+ this.vhostToHostNames.clear();
+ this.vhostToHostNames.putAll(map);
+ }
+
+ public Object getDeployerConfig()
+ {
+ return deployerConfig;
+ }
+ public void setDeployerConfig(Object config)
+ {
+ this.deployerConfig = config;
+ }
+
public String toString()
{
StringBuffer buffer = new StringBuffer("{WebApplication: ");
Modified: trunk/tomcat/.classpath
===================================================================
--- trunk/tomcat/.classpath 2006-10-05 19:36:02 UTC (rev 57454)
+++ trunk/tomcat/.classpath 2006-10-05 21:51:03 UTC (rev 57455)
@@ -43,5 +43,6 @@
<classpathentry sourcepath="C:/svn/JBossHead/projects/test/test/src/main" kind="lib" path="/thirdparty/jboss/test/lib/jboss-test.jar"/>
<classpathentry kind="lib" path="/thirdparty/junit/lib/junit.jar"/>
<classpathentry kind="lib" path="/thirdparty/jboss/aop/lib/jboss-aop-jdk50.jar"/>
+ <classpathentry sourcepath="/ejb3/C:/svn/JBossMC/jbossmc/trunk/dependency/src/main" kind="lib" path="/thirdparty/jboss/microcontainer/lib/jboss-dependency.jar"/>
<classpathentry kind="output" path="output/eclipse-classes"/>
</classpath>
Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/TomcatDeployer.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/TomcatDeployer.java 2006-10-05 19:36:02 UTC (rev 57454)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/TomcatDeployer.java 2006-10-05 21:51:03 UTC (rev 57455)
@@ -156,7 +156,7 @@
URL url = new URL(warUrl);
ClassLoader loader = Thread.currentThread().getContextClassLoader();
- injectionContainer = new TomcatInjectionContainer(webAppParser, appInfo);
+ injectionContainer = new TomcatInjectionContainer(webAppParser, appInfo, null);
Loader webLoader = getWebLoader(loader, url);
appInfo.setName(url.getPath());
Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/TomcatInjectionContainer.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/TomcatInjectionContainer.java 2006-10-05 19:36:02 UTC (rev 57454)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/TomcatInjectionContainer.java 2006-10-05 21:51:03 UTC (rev 57455)
@@ -136,9 +136,10 @@
protected AbstractWebContainer.WebDescriptorParser parser;
protected WebApplication appInfo;
- public TomcatInjectionContainer(AbstractWebContainer.WebDescriptorParser parser, WebApplication appInfo)
+ public TomcatInjectionContainer(AbstractWebContainer.WebDescriptorParser parser,
+ WebApplication appInfo, DeploymentInfo di)
{
- this.di = appInfo.getDeploymentInfo();
+ this.di = di;
EAR ear = null;
this.parser = parser;
this.appInfo = appInfo;
Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/WebAppLoader.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/WebAppLoader.java 2006-10-05 19:36:02 UTC (rev 57454)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/WebAppLoader.java 2006-10-05 21:51:03 UTC (rev 57455)
@@ -48,6 +48,10 @@
setLoaderClass(WebAppClassLoader.class.getName());
}
+ public WebAppLoader(ClassLoader parent, String[] filteredPackages)
+ {
+ this(parent, filteredPackages, null);
+ }
public WebAppLoader(ClassLoader parent, String[] filteredPackages, TomcatInjectionContainer container)
{
super(parent);
Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/WebCtxLoader.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/WebCtxLoader.java 2006-10-05 19:36:02 UTC (rev 57454)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/WebCtxLoader.java 2006-10-05 21:51:03 UTC (rev 57455)
@@ -78,8 +78,12 @@
*
* @param encLoader
*/
- WebCtxLoader(ClassLoader encLoader, TomcatInjectionContainer container)
+ public WebCtxLoader(ClassLoader encLoader)
{
+ this(encLoader, null);
+ }
+ public WebCtxLoader(ClassLoader encLoader, TomcatInjectionContainer container)
+ {
this.encLoader = encLoader;
this.ctxLoader = new ENCLoader(encLoader);
ClassLoader parent = encLoader;
Added: trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/deployers/TomcatDeployment.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/deployers/TomcatDeployment.java 2006-10-05 19:36:02 UTC (rev 57454)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/deployers/TomcatDeployment.java 2006-10-05 21:51:03 UTC (rev 57455)
@@ -0,0 +1,986 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.web.tomcat.tc6.deployers;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.MalformedURLException;
+import java.net.URLClassLoader;
+import java.security.CodeSource;
+import java.security.cert.Certificate;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import javax.management.Attribute;
+import javax.management.JMException;
+import javax.management.MBeanServer;
+import javax.management.ObjectInstance;
+import javax.management.ObjectName;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.LinkRef;
+import javax.naming.NamingException;
+
+import org.apache.catalina.Loader;
+import org.jboss.deployers.spi.DeploymentException;
+import org.jboss.deployment.DeploymentInfo;
+import org.jboss.ejb.EjbUtil;
+import org.jboss.logging.Logger;
+import org.jboss.metadata.EjbLocalRefMetaData;
+import org.jboss.metadata.EjbRefMetaData;
+import org.jboss.metadata.EnvEntryMetaData;
+import org.jboss.metadata.MessageDestinationMetaData;
+import org.jboss.metadata.MessageDestinationRefMetaData;
+import org.jboss.metadata.ResourceEnvRefMetaData;
+import org.jboss.metadata.ResourceRefMetaData;
+import org.jboss.metadata.WebMetaData;
+import org.jboss.mx.loading.LoaderRepositoryFactory;
+import org.jboss.mx.util.MBeanServerLocator;
+import org.jboss.naming.NonSerializableFactory;
+import org.jboss.util.naming.Util;
+import org.jboss.security.AuthorizationManager;
+import org.jboss.security.authorization.PolicyRegistration;
+import org.jboss.security.plugins.AuthorizationManagerServiceMBean;
+import org.jboss.web.AbstractWebContainer;
+import org.jboss.web.AbstractWebDeployer;
+import org.jboss.web.WebApplication;
+import org.jboss.web.tomcat.security.JaccContextValve;
+import org.jboss.web.tomcat.security.RunAsListener;
+import org.jboss.web.tomcat.security.SecurityAssociationValve;
+import org.jboss.web.tomcat.tc6.DeployerConfig;
+import org.jboss.web.tomcat.tc6.WebAppLoader;
+import org.jboss.web.tomcat.tc6.WebCtxLoader;
+import org.jboss.web.tomcat.tc6.session.AbstractJBossManager;
+import org.jboss.web.tomcat.tc6.session.ClusteringNotSupportedException;
+import org.jboss.web.tomcat.tc6.session.JBossCacheManager;
+import org.jboss.webservice.WebServiceClientHandler;
+import org.omg.CORBA.ORB;
+import org.apache.tomcat.util.modeler.Registry;
+
+/**
+ * A tomcat web application deployment.
+ *
+ * @author Scott.Stark at jboss.org
+ * @author Costin Manolache
+ * @version $Revision: 56605 $
+ */
+public class TomcatDeployment
+{
+ private static final Logger log = Logger.getLogger(TomcatDeployment.class);
+ /**
+ * The name of the war level context configuration descriptor
+ */
+ private static final String CONTEXT_CONFIG_FILE = "WEB-INF/context.xml";
+
+ /**
+ * Optional XACML Policy File
+ */
+ private static final String XACML_POLICY_FILE = "WEB-INF/jboss-xacml-policy.xml";
+
+ private WebApplication warInfo;
+ private DeployerConfig config;
+ private String[] javaVMs =
+ {" jboss.management.local:J2EEServer=Local,j2eeType=JVM,name=localhost"};
+ private String serverName = "jboss";
+ private String hostName;
+ private String warUrl;
+ private ORB orb = null;
+ private MBeanServer server;
+
+ //private TomcatInjectionContainer injectionContainer;
+
+ public TomcatDeployment(WebApplication warInfo, String hostName, String warUrl)
+ {
+ this.warInfo = warInfo;
+ this.hostName = hostName;
+ this.warUrl = warUrl;
+ this.config = (DeployerConfig) warInfo.getDeployerConfig();
+ }
+
+ public ORB getORB()
+ {
+ return orb;
+ }
+ public void setORB(ORB orb)
+ {
+ this.orb = orb;
+ }
+
+ public void start()
+ throws Exception
+ {
+ // TODO: Need to remove the dependency on MBeanServer
+ server = MBeanServerLocator.locateJBoss();
+ performDeployInternal();
+ }
+ public void stop()
+ {
+ server = null;
+ }
+
+ protected void performDeployInternal()
+ throws Exception
+ {
+
+ WebMetaData metaData = warInfo.getMetaData();
+ String ctxPath = metaData.getContextRoot();
+ if (ctxPath.equals("/") || ctxPath.equals("/ROOT") || ctxPath.equals(""))
+ {
+ log.debug("deploy root context=" + ctxPath);
+ ctxPath = "/";
+ metaData.setContextRoot(ctxPath);
+ }
+
+ log.info("deploy, ctxPath=" + ctxPath + ", warUrl=" + shortWarUrlFromServerHome(warUrl));
+
+ URL url = new URL(warUrl);
+
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ // injectionContainer = new TomcatInjectionContainer(webAppParser, appInfo);
+ Loader webLoader = getWebLoader(loader, url);
+
+ warInfo.setName(url.getPath());
+ warInfo.setClassLoader(loader);
+ warInfo.setURL(url);
+
+ String objectNameS = warInfo.getDomain()
+ + ":j2eeType=WebModule,name=//" +
+ ((hostName == null) ? "localhost" : hostName)
+ + ctxPath + ",J2EEApplication=none,J2EEServer=none";
+
+ ObjectName objectName = new ObjectName(objectNameS);
+
+ /*
+ server.createMBean("org.apache.tomcat.util.modeler.BaseModelMBean",
+ objectName, new Object[]{warInfo.getContextClassName()},
+ new String[]{"java.lang.String"});
+ */
+ String contextClassName = config.getContextClassName();
+ Registry.getRegistry().registerComponent(Class.forName(contextClassName).newInstance(),
+ objectName, contextClassName);
+
+ // Find and set warInfo file on the context
+ // If WAR is packed, expand warInfo file to temp folder
+ String ctxConfig = null;
+ try
+ {
+ ctxConfig = findConfig(url);
+ }
+ catch (IOException e)
+ {
+ log.debug("No " + CONTEXT_CONFIG_FILE + " in " + url, e);
+ }
+
+ /*
+ if (injectionContainer != null)
+ {
+ server.setAttribute(objectName, new Attribute("annotationProcessor", injectionContainer));
+ }
+ */
+
+ server.setAttribute(objectName, new Attribute("docBase", url.getFile()));
+
+ server.setAttribute(objectName, new Attribute("configFile", ctxConfig));
+
+ server.setAttribute(objectName, new Attribute
+ ("defaultContextXml", "context.xml"));
+ server.setAttribute(objectName, new Attribute
+ ("defaultWebXml", "conf/web.xml"));
+
+ server.setAttribute(objectName, new Attribute("javaVMs", javaVMs));
+
+ server.setAttribute(objectName, new Attribute("server", serverName));
+
+ server.setAttribute(objectName, new Attribute
+ ("saveConfig", Boolean.FALSE));
+
+ if (webLoader != null)
+ {
+ server.setAttribute(objectName, new Attribute
+ ("loader", webLoader));
+ }
+ else
+ {
+ server.setAttribute(objectName, new Attribute
+ ("parentClassLoader", loader));
+ }
+
+ server.setAttribute(objectName, new Attribute
+ ("delegate", new Boolean(warInfo.getJava2ClassLoadingCompliance())));
+
+ String[] jspCP = getCompileClasspath(loader);
+ StringBuffer classpath = new StringBuffer();
+ for (int u = 0; u < jspCP.length; u++)
+ {
+ String repository = jspCP[u];
+ if (repository == null)
+ continue;
+ if (repository.startsWith("file://"))
+ repository = repository.substring(7);
+ else if (repository.startsWith("file:"))
+ repository = repository.substring(5);
+ else
+ continue;
+ if (repository == null)
+ continue;
+ // ok it is a file. Make sure that is is a directory or jar file
+ File fp = new File(repository);
+ if (!fp.isDirectory())
+ {
+ // if it is not a directory, try to open it as a zipfile.
+ try
+ {
+ // avoid opening .xml files
+ if (fp.getName().toLowerCase().endsWith(".xml"))
+ continue;
+
+ ZipFile zip = new ZipFile(fp);
+ zip.close();
+ }
+ catch (IOException e)
+ {
+ continue;
+ }
+
+ }
+ if (u > 0)
+ classpath.append(File.pathSeparator);
+ classpath.append(repository);
+ }
+
+ server.setAttribute(objectName, new Attribute
+ ("compilerClasspath", classpath.toString()));
+
+ // Set the session cookies flag according to metadata
+ switch (metaData.getSessionCookies())
+ {
+ case WebMetaData.SESSION_COOKIES_ENABLED:
+ server.setAttribute(objectName, new Attribute
+ ("cookies", new Boolean(true)));
+ log.debug("Enabling session cookies");
+ break;
+ case WebMetaData.SESSION_COOKIES_DISABLED:
+ server.setAttribute(objectName, new Attribute
+ ("cookies", new Boolean(false)));
+ log.debug("Disabling session cookies");
+ break;
+ default:
+ log.debug("Using session cookies default setting");
+ }
+
+ // Add a valve to estalish the JACC context before authorization valves
+ Certificate[] certs = null;
+ CodeSource cs = new CodeSource(url, certs);
+ JaccContextValve jaccValve = new JaccContextValve(metaData.getJaccContextID(), cs);
+ server.invoke(objectName, "addValve",
+ new Object[]{jaccValve},
+ new String[]{"org.apache.catalina.Valve"}
+ );
+
+ // Pass the metadata to the RunAsListener via a thread local
+ RunAsListener.metaDataLocal.set(metaData);
+ try
+ {
+ // Init the container; this will also start it
+ server.invoke(objectName, "init", new Object[]{}, new String[]{});
+ }
+ finally
+ {
+ RunAsListener.metaDataLocal.set(null);
+ }
+
+ // make the context class loader known to the WebMetaData, ws4ee needs it
+ // to instanciate service endpoint pojos that live in this webapp
+ Loader ctxLoader = (Loader)server.getAttribute(objectName, "loader");
+ metaData.setContextLoader(ctxLoader.getClassLoader());
+
+ // Clustering
+ if (metaData.getDistributable())
+ {
+ // Try to initate clustering, fallback to standard if no clustering is available
+ try
+ {
+ AbstractJBossManager manager = null;
+ String managerClassName = config.getManagerClass();
+ Class managerClass = Thread.currentThread().getContextClassLoader().loadClass(managerClassName);
+ manager = (AbstractJBossManager) managerClass.newInstance();
+ String name = "//" + ((hostName == null) ? "localhost" : hostName) + ctxPath;
+ manager.init(name, metaData, config.isUseJK(), config.isUseLocalCache());
+
+ if (manager instanceof JBossCacheManager)
+ {
+ String snapshotMode = config.getSnapshotMode();
+ int snapshotInterval = config.getSnapshotInterval();
+ JBossCacheManager jbcm = (JBossCacheManager) manager;
+ jbcm.setSnapshotMode(snapshotMode);
+ jbcm.setSnapshotInterval(snapshotInterval);
+ }
+
+ server.setAttribute(objectName, new Attribute("manager", manager));
+
+ log.debug("Enabled clustering support for ctxPath=" + ctxPath);
+ }
+ catch (ClusteringNotSupportedException e)
+ {
+ // JBAS-3513 Just log a WARN, not an ERROR
+ log.warn("Failed to setup clustering, clustering disabled. ClusteringNotSupportedException: " +
+ e.getMessage());
+ }
+ catch (NoClassDefFoundError ncdf)
+ {
+ // JBAS-3513 Just log a WARN, not an ERROR
+ log.debug("Classes needed for clustered webapp unavailable", ncdf);
+ log.warn("Failed to setup clustering, clustering disabled. NoClassDefFoundError: " +
+ ncdf.getMessage());
+ }
+ catch(Throwable t)
+ {
+ // TODO consider letting this through and fail the deployment
+ log.error("Failed to setup clustering, clustering disabled. Exception: ", t);
+ }
+ }
+
+ /* Add security association valve after the authorization
+ valves so that the authenticated user may be associated with the
+ request thread/session.
+ */
+ SecurityAssociationValve valve = new SecurityAssociationValve(metaData,
+ config.getSecurityManagerService());
+ valve.setSubjectAttributeName(config.getSubjectAttributeName());
+ server.invoke(objectName, "addValve",
+ new Object[]{valve},
+ new String[]{"org.apache.catalina.Valve"});
+
+ // Retrieve the state, and throw an exception in case of a failure
+ Integer state = (Integer) server.getAttribute(objectName, "state");
+ if (state.intValue() != 1)
+ {
+ throw new DeploymentException("URL " + warUrl + " deployment failed");
+ }
+
+ warInfo.setAppData(objectName);
+
+ /* TODO: Create mbeans for the servlets
+ ObjectName servletQuery = new ObjectName
+ (config.getCatalinaDomain() + ":j2eeType=Servlet,WebModule="
+ + objectName.getKeyProperty("name") + ",*");
+ Iterator iterator = server.queryMBeans(servletQuery, null).iterator();
+ while (iterator.hasNext())
+ {
+ di.mbeans.add(((ObjectInstance)iterator.next()).getObjectName());
+ }
+ */
+
+ if(metaData.getSecurityDomain() != null)
+ {
+ String secDomain = org.jboss.security.Util.unprefixSecurityDomain(metaData.getSecurityDomain());
+ //Associate the Context Id with the Security Domain
+ String contextID = metaData.getJaccContextID();
+
+ //Check if xacml policy is available
+ URL xacmlPolicyFile = null;
+ try
+ {
+ xacmlPolicyFile = this.findXACMLFile(url);
+ if(xacmlPolicyFile != null)
+ {
+ AuthorizationManager authzmgr= org.jboss.security.Util.getAuthorizationManager(secDomain);
+ if(authzmgr instanceof PolicyRegistration)
+ {
+ PolicyRegistration xam = (PolicyRegistration)authzmgr;
+ xam.registerPolicy(contextID,xacmlPolicyFile);
+ }
+ }
+ }
+ catch(IOException ioe)
+ {
+ //Ignore
+ }
+ }
+
+ log.debug("Initialized: " + warInfo + " " + objectName);
+ }
+
+ public Loader getWebLoader(ClassLoader loader, URL url)
+ throws MalformedURLException
+ {
+ Loader webLoader = null;
+ /* If we are using the jboss class loader we need to augment its path
+ to include the WEB-INF/{lib,classes} dirs or else scoped class loading
+ does not see the war level overrides. The call to setWarURL adds these
+ paths to the deployment UCL.
+ */
+
+ if (config.isUseJBossWebLoader())
+ {
+ WebCtxLoader jbossLoader = new WebCtxLoader(loader/*, injectionContainer*/);
+ jbossLoader.setWarURL(url);
+ webLoader = jbossLoader;
+ }
+ else
+ {
+ String[] pkgs = config.getFilteredPackages();
+ WebAppLoader jbossLoader = new WebAppLoader(loader, pkgs/*, injectionContainer*/);
+ jbossLoader.setDelegate(warInfo.getJava2ClassLoadingCompliance());
+ webLoader = jbossLoader;
+ }
+ return webLoader;
+ }
+
+ /*
+ public void setInjectionContainer(TomcatInjectionContainer container)
+ {
+ this.injectionContainer = container;
+ }
+ */
+
+ /**
+ * Called as part of the undeploy() method template to ask the
+ * subclass for perform the web container specific undeployment steps.
+ */
+ protected void performUndeploy(String warUrl, WebApplication warInfo)
+ throws Exception
+ {
+ if (warInfo == null)
+ {
+ log.debug("performUndeploy, no WebApplication found for URL "
+ + warUrl);
+ return;
+ }
+
+ log.info("undeploy, ctxPath=" + warInfo.getMetaData().getContextRoot()
+ + ", warUrl=" + shortWarUrlFromServerHome(warUrl));
+
+ WebMetaData metaData = warInfo.getMetaData();
+ String hostName = null;
+ Iterator hostNames = metaData.getVirtualHosts();
+ if (hostNames.hasNext())
+ {
+ hostName = hostNames.next().toString();
+ }
+ performUndeployInternal(hostName, warUrl, warInfo);
+ while (hostNames.hasNext())
+ {
+ String additionalHostName = hostNames.next().toString();
+ performUndeployInternal(additionalHostName, warUrl, warInfo);
+ }
+
+ }
+
+ protected void performUndeployInternal(String hostName, String warUrl,
+ WebApplication warInfo)
+ throws Exception
+ {
+
+ WebMetaData metaData = warInfo.getMetaData();
+ String ctxPath = metaData.getContextRoot();
+
+ // TODO: Need to remove the dependency on MBeanServer
+ MBeanServer server = MBeanServerLocator.locateJBoss();
+ // If the server is gone, all apps were stopped already
+ if (server == null)
+ return;
+
+ ObjectName objectName = new ObjectName(config.getCatalinaDomain()
+ + ":j2eeType=WebModule,name=//" +
+ ((hostName == null) ? "localhost" : hostName)
+ + ctxPath + ",J2EEApplication=none,J2EEServer=none");
+
+ if (server.isRegistered(objectName))
+ {
+ // Contexts should be stopped by the host already
+ server.invoke(objectName, "destroy", new Object[]{},
+ new String[]{});
+ }
+
+ }
+
+ private String findConfig(URL warURL) throws IOException
+ {
+ String result = null;
+ // See if the warUrl is a dir or a file
+ File warFile = new File(warURL.getFile());
+ if (warURL.getProtocol().equals("file") && warFile.isDirectory() == true)
+ {
+ File webDD = new File(warFile, CONTEXT_CONFIG_FILE);
+ if (webDD.exists() == true) result = webDD.getAbsolutePath();
+ }
+ else
+ {
+ ZipFile zipFile = new ZipFile(warFile);
+ ZipEntry entry = zipFile.getEntry(CONTEXT_CONFIG_FILE);
+ if (entry != null)
+ {
+ InputStream zipIS = zipFile.getInputStream(entry);
+ byte[] buffer = new byte[512];
+ int bytes;
+ result = warFile.getAbsolutePath() + "-context.xml";
+ FileOutputStream fos = new FileOutputStream(result);
+ while ((bytes = zipIS.read(buffer)) > 0)
+ {
+ fos.write(buffer, 0, bytes);
+ }
+ zipIS.close();
+ fos.close();
+ }
+ zipFile.close();
+ }
+ return result;
+ }
+
+ /**
+ * A utility method that walks up the ClassLoader chain starting at the given
+ * loader and queries each ClassLoader for a 'URL[] getURLs()' method from
+ * which a complete classpath of URL strings is built.
+ */
+ public String[] getCompileClasspath(ClassLoader loader)
+ {
+ HashSet tmp = new HashSet();
+ ClassLoader cl = loader;
+ while (cl != null)
+ {
+ URL[] urls = AbstractWebContainer.getClassLoaderURLs(cl);
+ addURLs(tmp, urls);
+ cl = cl.getParent();
+ }
+ try
+ {
+ URL[] globalUrls = (URL[]) server.getAttribute(LoaderRepositoryFactory.DEFAULT_LOADER_REPOSITORY,
+ "URLs");
+ addURLs(tmp, globalUrls);
+ }
+ catch (Exception e)
+ {
+ log.warn("Could not get global URL[] from default loader repository!", e);
+ } // end of try-catch
+ log.trace("JSP CompileClasspath: " + tmp);
+ String[] cp = new String[tmp.size()];
+ tmp.toArray(cp);
+ return cp;
+ }
+
+ private void addURLs(Set urlSet, URL[] urls)
+ {
+ for (int u = 0; u < urls.length; u++)
+ {
+ URL url = urls[u];
+ urlSet.add(url.toExternalForm());
+ }
+ }
+
+ /**
+ * This method is invoked from within subclass performDeploy() method
+ * implementations when they invoke WebDescriptorParser.parseWebAppDescriptors().
+ * @param loader the ClassLoader for the web application. May not be null.
+ * @param metaData the WebMetaData from the WebApplication object passed to
+ * the performDeploy method.
+ */
+ protected void processEnc(ClassLoader loader, WebMetaData metaData)
+ throws Exception
+ {
+ log.debug("AbstractWebContainer.parseWebAppDescriptors, Begin");
+ InitialContext iniCtx = new InitialContext();
+ Context envCtx = null;
+ Thread currentThread = Thread.currentThread();
+ ClassLoader currentLoader = currentThread.getContextClassLoader();
+ try
+ {
+ // Create a java:comp/env environment unique for the web application
+ log.debug("Creating ENC using ClassLoader: " + loader);
+ ClassLoader parent = loader.getParent();
+ while (parent != null)
+ {
+ log.debug(".." + parent);
+ parent = parent.getParent();
+ }
+ // TODO: Where does this ENC get tidied up?
+ currentThread.setContextClassLoader(loader);
+ metaData.setENCLoader(loader);
+ envCtx = (Context) iniCtx.lookup("java:comp");
+
+
+ // Bind the orb
+ if (orb != null)
+ {
+ NonSerializableFactory.rebind(envCtx, "ORB", orb);
+ log.debug("Bound java:comp/ORB");
+ }
+
+ // Add a link to the global transaction manager
+ envCtx.bind("UserTransaction", new LinkRef("UserTransaction"));
+ log.debug("Linked java:comp/UserTransaction to JNDI name: UserTransaction");
+ envCtx = envCtx.createSubcontext("env");
+ processEncReferences(metaData, envCtx);
+ }
+ finally
+ {
+ currentThread.setContextClassLoader(currentLoader);
+ }
+
+ String securityDomain = metaData.getSecurityDomain();
+ log.debug("linkSecurityDomain");
+ linkSecurityDomain(securityDomain, envCtx);
+ log.debug("AbstractWebContainer.parseWebAppDescriptors, End");
+ }
+
+ protected void processEncReferences(WebMetaData metaData, Context envCtx)
+ throws ClassNotFoundException, NamingException, DeploymentException
+ {
+ Iterator envEntries = metaData.getEnvironmentEntries();
+ log.debug("addEnvEntries");
+ addEnvEntries(envEntries, envCtx);
+ Iterator resourceEnvRefs = metaData.getResourceEnvReferences();
+ log.debug("linkResourceEnvRefs");
+ linkResourceEnvRefs(resourceEnvRefs, envCtx);
+ Iterator resourceRefs = metaData.getResourceReferences();
+ log.debug("linkResourceRefs");
+ linkResourceRefs(resourceRefs, envCtx);
+ log.debug("linkMessageDestinationRefs");
+ linkMessageDestinationRefs(metaData, envCtx);
+ Iterator ejbRefs = metaData.getEjbReferences();
+ log.debug("linkEjbRefs");
+ linkEjbRefs(ejbRefs, envCtx);
+ Iterator ejbLocalRefs = metaData.getEjbLocalReferences();
+ log.debug("linkEjbLocalRefs");
+ linkEjbLocalRefs(ejbLocalRefs, envCtx);
+ Iterator serviceRefs = metaData.getServiceReferences();
+ log.debug("linkServiceRefs");
+ //WebServiceClientHandler.setupServiceRefEnvironment(envCtx, serviceRefs);
+ }
+
+ protected void addEnvEntries(Iterator envEntries, Context envCtx)
+ throws ClassNotFoundException, NamingException
+ {
+ while (envEntries.hasNext())
+ {
+ EnvEntryMetaData entry = (EnvEntryMetaData) envEntries.next();
+ log.debug("Binding env-entry: " + entry.getName() + " of type: " +
+ entry.getType() + " to value:" + entry.getValue());
+ EnvEntryMetaData.bindEnvEntry(envCtx, entry);
+ }
+ }
+
+ protected void linkResourceEnvRefs(Iterator resourceEnvRefs, Context envCtx)
+ throws NamingException
+ {
+ while (resourceEnvRefs.hasNext())
+ {
+ ResourceEnvRefMetaData ref = (ResourceEnvRefMetaData) resourceEnvRefs.next();
+ String resourceName = ref.getJndiName();
+ String refName = ref.getRefName();
+ if (ref.getType().equals("java.net.URL"))
+ {
+ try
+ {
+ log.debug("Binding '" + refName + "' to URL: " + resourceName);
+ URL url = new URL(resourceName);
+ Util.bind(envCtx, refName, url);
+ }
+ catch (MalformedURLException e)
+ {
+ throw new NamingException("Malformed URL:" + e.getMessage());
+ }
+ }
+ else if (resourceName != null)
+ {
+ log.debug("Linking '" + refName + "' to JNDI name: " + resourceName);
+ Util.bind(envCtx, refName, new LinkRef(resourceName));
+ }
+ else
+ {
+ throw new NamingException("resource-env-ref: " + refName
+ + " has no valid JNDI binding. Check the jboss-web/resource-env-ref.");
+ }
+ }
+ }
+
+ protected void linkResourceRefs(Iterator resourceRefs, Context envCtx)
+ throws NamingException
+ {
+ while (resourceRefs.hasNext())
+ {
+ ResourceRefMetaData ref = (ResourceRefMetaData) resourceRefs.next();
+ String jndiName = ref.getJndiName();
+ String refName = ref.getRefName();
+ if (ref.getType().equals("java.net.URL"))
+ {
+ try
+ {
+ String resURL = ref.getResURL();
+ if (ref.getResURL() != null)
+ {
+ log.debug("Binding '" + refName + "' to URL: " + resURL);
+ URL url = new URL(resURL);
+ Util.bind(envCtx, refName, url);
+ }
+ else
+ {
+ log.debug("Linking '" + refName + "' to URL: " + resURL);
+ LinkRef urlLink = new LinkRef(jndiName);
+ Util.bind(envCtx, refName, urlLink);
+ }
+ }
+ catch (MalformedURLException e)
+ {
+ throw new NamingException("Malformed URL:" + e.getMessage());
+ }
+ }
+ else if (jndiName != null)
+ {
+ log.debug("Linking '" + refName + "' to JNDI name: " + jndiName);
+ Util.bind(envCtx, refName, new LinkRef(jndiName));
+ }
+ else
+ {
+ throw new NamingException("resource-ref: " + refName
+ + " has no valid JNDI binding. Check the jboss-web/resource-ref.");
+ }
+ }
+ }
+
+ protected void linkMessageDestinationRefs(WebMetaData metaData, Context envCtx)
+ throws NamingException, DeploymentException
+ {
+ Iterator i = metaData.getMessageDestinationReferences();
+
+ while (i.hasNext())
+ {
+ MessageDestinationRefMetaData ref = (MessageDestinationRefMetaData) i.next();
+
+ String refName = ref.getRefName();
+ String jndiName = ref.getJNDIName();
+ String link = ref.getLink();
+ if (link != null)
+ {
+ if (jndiName == null)
+ {
+ MessageDestinationMetaData messageDestination = null; //EjbUtil.findMessageDestination(server, di, link);
+ if (messageDestination == null)
+ throw new DeploymentException("message-destination-ref '" + refName +
+ "' message-destination-link '" + link + "' not found and no jndi-name in jboss-web.xml");
+ else
+ {
+ String linkJNDIName = messageDestination.getJNDIName();
+ if (linkJNDIName == null)
+ log.warn("message-destination '" + link + "' has no jndi-name in jboss-web.xml");
+ else
+ jndiName = linkJNDIName;
+ }
+ }
+ else
+ log.warn("message-destination-ref '" + refName +
+ "' ignoring message-destination-link '" + link + "' because it has a jndi-name in jboss-web.xml");
+ }
+ else if (jndiName == null)
+ throw new DeploymentException("message-destination-ref '" + refName +
+ "' has no message-destination-link in web.xml and no jndi-name in jboss-web.xml");
+ Util.bind(envCtx, refName, new LinkRef(jndiName));
+ }
+ }
+
+ protected void linkEjbRefs(Iterator ejbRefs, Context envCtx)
+ throws NamingException
+ {
+ while (ejbRefs.hasNext())
+ {
+ EjbRefMetaData ejb = (EjbRefMetaData) ejbRefs.next();
+ String name = ejb.getName();
+ String linkName = ejb.getLink();
+ String jndiName = null;
+
+ //use ejb-link if it is specified
+ if (linkName != null)
+ {
+ jndiName = null; // EjbUtil.findEjbLink(server, di, linkName);
+
+ //if flag does not allow misconfigured ejb-links, it is an error
+ if ((jndiName == null) && !(warInfo.getLenientEjbLink()))
+ throw new NamingException("ejb-ref: " + name + ", no ejb-link match");
+ }
+
+
+ //fall through to the jndiName
+ if (jndiName == null)
+ {
+ jndiName = ejb.getJndiName();
+ if (jndiName == null)
+ throw new NamingException("ejb-ref: " + name + ", no ejb-link in web.xml and no jndi-name in jboss-web.xml");
+ }
+
+ log.debug("Linking ejb-ref: " + name + " to JNDI name: " + jndiName);
+ Util.bind(envCtx, name, new LinkRef(jndiName));
+ }
+ }
+
+ protected void linkEjbLocalRefs(Iterator ejbRefs, Context envCtx)
+ throws NamingException
+ {
+ while (ejbRefs.hasNext())
+ {
+ EjbLocalRefMetaData ejb = (EjbLocalRefMetaData) ejbRefs.next();
+ String name = ejb.getName();
+ String linkName = ejb.getLink();
+ String jndiName = null;
+
+ //use the ejb-link field if it is specified
+ if (linkName != null)
+ {
+ jndiName = null; // EjbUtil.findLocalEjbLink(server, di, linkName);
+
+ //if flag does not allow misconfigured ejb-links, it is an error
+ if ((jndiName == null) && !(warInfo.getLenientEjbLink()))
+ throw new NamingException("ejb-ref: " + name + ", no ejb-link match");
+ }
+
+
+ if (jndiName == null)
+ {
+ jndiName = ejb.getJndiName();
+ if (jndiName == null)
+ {
+ String msg = null;
+ if (linkName == null)
+ {
+ msg = "ejb-local-ref: '" + name + "', no ejb-link in web.xml and "
+ + "no local-jndi-name in jboss-web.xml";
+ }
+ else
+ {
+ msg = "ejb-local-ref: '" + name + "', with web.xml ejb-link: '"
+ + linkName + "' failed to resolve to an ejb with a LocalHome";
+ }
+ throw new NamingException(msg);
+ }
+ }
+
+ log.debug("Linking ejb-local-ref: " + name + " to JNDI name: " + jndiName);
+ Util.bind(envCtx, name, new LinkRef(jndiName));
+ }
+ }
+
+ /**
+ * This creates a java:comp/env/security context that contains a securityMgr
+ * binding pointing to an AuthenticationManager implementation and a
+ * realmMapping binding pointing to a RealmMapping implementation. If the
+ * jboss-web.xml descriptor contained a security-domain element then the
+ * bindings are LinkRefs to the jndi name specified by the security-domain
+ * element. If there was no security-domain element then the bindings are to
+ * NullSecurityManager instance which simply allows all access.
+ */
+ protected void linkSecurityDomain(String securityDomain, Context envCtx)
+ throws NamingException
+ {
+ if (securityDomain == null)
+ {
+ securityDomain = config.getDefaultSecurityDomain();
+ log.debug("No security-domain given, using default: " + securityDomain);
+ }
+ log.debug("Linking security/securityMgr to JNDI name: " + securityDomain);
+ Util.bind(envCtx, "security/securityMgr", new LinkRef(securityDomain));
+ Util.bind(envCtx, "security/realmMapping", new LinkRef(securityDomain+"/realmMapping"));
+ Util.bind(envCtx, "security/authorizationMgr", new LinkRef(securityDomain+"/authorizationMgr"));
+ Util.bind(envCtx, "security/security-domain", new LinkRef(securityDomain));
+ Util.bind(envCtx, "security/subject", new LinkRef(securityDomain + "/subject"));
+ }
+
+ /**
+ * A utility method that searches the given loader for the resources:
+ * "javax/servlet/resources/web-app_2_3.dtd", "org/apache/jasper/resources/jsp12.dtd",
+ * and "javax/ejb/EJBHome.class" and returns an array of URL strings. Any
+ * jar: urls are reduced to the underlying <url> portion of the
+ * 'jar:<url>!/{entry}' construct.
+ */
+ public String[] getStandardCompileClasspath(ClassLoader loader)
+ {
+ String[] jspResources = {
+ "javax/servlet/resources/web-app_2_3.dtd",
+ "org/apache/jasper/resources/jsp12.dtd",
+ "javax/ejb/EJBHome.class"
+ };
+ ArrayList tmp = new ArrayList();
+ for (int j = 0; j < jspResources.length; j++)
+ {
+ URL rsrcURL = loader.getResource(jspResources[j]);
+ if (rsrcURL != null)
+ {
+ String url = rsrcURL.toExternalForm();
+ if (rsrcURL.getProtocol().equals("jar"))
+ {
+ // Parse the jar:<url>!/{entry} URL
+ url = url.substring(4);
+ int seperator = url.indexOf('!');
+ url = url.substring(0, seperator);
+ }
+ tmp.add(url);
+ }
+ else
+ {
+ log.warn("Failed to fin jsp rsrc: " + jspResources[j]);
+ }
+ }
+ log.trace("JSP StandardCompileClasspath: " + tmp);
+ String[] cp = new String[tmp.size()];
+ tmp.toArray(cp);
+ return cp;
+ }
+
+ /**
+ * Locate a XACMl Policy file packaged in the war
+ * @param warURL
+ * @return
+ * @throws IOException
+ */
+ private URL findXACMLFile(URL warURL) throws IOException
+ {
+ URL result = null;
+ // See if the warUrl is a dir or a file
+ File warFile = new File(warURL.getFile());
+ if (warURL.getProtocol().equals("file") && warFile.isDirectory() == true)
+ {
+ File webDD = new File(warFile, XACML_POLICY_FILE);
+ if (webDD.exists() == true)
+ result = webDD.toURL();
+ }
+ return result;
+ }
+
+ private String shortWarUrlFromServerHome(String warUrl)
+ {
+ String serverHomeUrl = System.getProperty(org.jboss.system.server.ServerConfig.SERVER_HOME_URL);
+
+ if (warUrl == null || serverHomeUrl == null)
+ return warUrl;
+
+ if (warUrl.startsWith(serverHomeUrl))
+ return ".../" + warUrl.substring(serverHomeUrl.length());
+ else
+ return warUrl;
+ }
+}
Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/deployers/WarDeployer.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/deployers/WarDeployer.java 2006-10-05 19:36:02 UTC (rev 57454)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/deployers/WarDeployer.java 2006-10-05 21:51:03 UTC (rev 57455)
@@ -21,35 +21,510 @@
*/
package org.jboss.web.tomcat.tc6.deployers;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.security.Policy;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.LinkRef;
+import javax.naming.NamingException;
+import javax.security.jacc.PolicyConfiguration;
+import javax.security.jacc.PolicyConfigurationFactory;
+import javax.security.jacc.PolicyContextException;
+
import org.jboss.deployers.plugins.deployers.helpers.AbstractSimpleRealDeployer;
import org.jboss.deployers.spi.DeploymentException;
import org.jboss.deployers.spi.deployer.DeploymentUnit;
+import org.jboss.deployers.spi.structure.DeploymentContext;
+import org.jboss.deployment.DeploymentInfo;
+import org.jboss.deployment.J2eeApplicationMetaData;
+import org.jboss.ejb.Container;
+import org.jboss.ejb.EjbUtil;
+import org.jboss.metadata.EjbLocalRefMetaData;
+import org.jboss.metadata.EjbRefMetaData;
+import org.jboss.metadata.EnvEntryMetaData;
+import org.jboss.metadata.MessageDestinationMetaData;
+import org.jboss.metadata.MessageDestinationRefMetaData;
+import org.jboss.metadata.ResourceEnvRefMetaData;
+import org.jboss.metadata.ResourceRefMetaData;
import org.jboss.metadata.WebMetaData;
+import org.jboss.mx.loading.LoaderRepositoryFactory;
+import org.jboss.mx.util.MBeanServerLocator;
+import org.jboss.naming.NonSerializableFactory;
+import org.jboss.naming.Util;
+import org.jboss.resource.metadata.ConnectorMetaData;
+import org.jboss.security.AuthorizationManager;
+import org.jboss.security.authorization.PolicyRegistration;
+import org.jboss.system.metadata.ServiceAttributeMetaData;
+import org.jboss.system.metadata.ServiceConstructorMetaData;
+import org.jboss.system.metadata.ServiceInjectionValueMetaData;
+import org.jboss.system.metadata.ServiceMetaData;
+import org.jboss.web.AbstractWebContainer;
+import org.jboss.web.WebApplication;
+import org.jboss.web.WebPermissionMapping;
+import org.jboss.web.tomcat.tc6.DeployerConfig;
+import org.jboss.webservice.WebServiceClientHandler;
+import org.omg.CORBA.ORB;
/**
* The war deployer that transforms a WebMetaData deployment type into a kernel bean
*
* @author Scott.Stark at jboss.org
+ * @author adrian at jboss.com
* @version $Revision:$
*/
public class WarDeployer extends AbstractSimpleRealDeployer<WebMetaData>
{
+ /**
+ * The parent class loader first model flag
+ */
+ protected boolean java2ClassLoadingCompliance = false;
+ /**
+ * A flag indicating if war archives should be unpacked
+ */
+ protected boolean unpackWars = true;
+ /**
+ * If true, ejb-links that don't resolve don't cause an error (fallback to
+ * jndi-name)
+ */
+ protected boolean lenientEjbLink = false;
+ /**
+ * The default security-domain name to use
+ */
+ protected String defaultSecurityDomain;
+ private DeployerConfig config = new DeployerConfig();
+
public WarDeployer()
{
super(WebMetaData.class);
}
+ /**
+ * Get the flag indicating if the normal Java2 parent first class loading
+ * model should be used over the servlet 2.3 web container first model.
+ * @return true for parent first, false for the servlet 2.3 model
+ * @jmx.managed-attribute
+ */
+ public boolean getJava2ClassLoadingCompliance()
+ {
+ return java2ClassLoadingCompliance;
+ }
+
+ /**
+ * Set the flag indicating if the normal Java2 parent first class loading
+ * model should be used over the servlet 2.3 web container first model.
+ * @param flag true for parent first, false for the servlet 2.3 model
+ * @jmx.managed-attribute
+ */
+ public void setJava2ClassLoadingCompliance(boolean flag)
+ {
+ java2ClassLoadingCompliance = flag;
+ }
+
+ /**
+ * Get the flag indicating if war archives should be unpacked. This may need
+ * to be set to false as long extraction paths under deploy can show up as
+ * deployment failures on some platforms.
+ * @return true is war archives should be unpacked
+ * @jmx.managed-attribute
+ */
+ public boolean getUnpackWars()
+ {
+ return unpackWars;
+ }
+
+ /**
+ * Get the flag indicating if war archives should be unpacked. This may need
+ * to be set to false as long extraction paths under deploy can show up as
+ * deployment failures on some platforms.
+ * @param flag , true is war archives should be unpacked
+ * @jmx.managed-attribute
+ */
+ public void setUnpackWars(boolean flag)
+ {
+ this.unpackWars = flag;
+ }
+
+ /**
+ * Get the flag indicating if ejb-link errors should be ignored in favour of
+ * trying the jndi-name in jboss-web.xml
+ * @return a <code>boolean</code> value
+ * @jmx.managed-attribute
+ */
+ public boolean getLenientEjbLink()
+ {
+ return lenientEjbLink;
+ }
+
+ /**
+ * Set the flag indicating if ejb-link errors should be ignored in favour of
+ * trying the jndi-name in jboss-web.xml
+ * @jmx.managed-attribute
+ */
+ public void setLenientEjbLink(boolean flag)
+ {
+ lenientEjbLink = flag;
+ }
+
+ /**
+ * Get the default security domain implementation to use if a war does not
+ * declare a security-domain.
+ * @return jndi name of the security domain binding to use.
+ * @jmx.managed-attribute
+ */
+ public String getDefaultSecurityDomain()
+ {
+ return defaultSecurityDomain;
+ }
+
+ /**
+ * Set the default security domain implementation to use if a war does not
+ * declare a security-domain.
+ * @param defaultSecurityDomain - jndi name of the security domain binding to
+ * use.
+ * @jmx.managed-attribute
+ */
+ public void setDefaultSecurityDomain(String defaultSecurityDomain)
+ {
+ this.defaultSecurityDomain = defaultSecurityDomain;
+ }
+
+ /**
+ * Deploy a web app based on the WebMetaData.
+ * @param unit - the war for the deployment
+ * @param metaData - the metadata for the deployment
+ */
@Override
- public void deploy(DeploymentUnit unit, WebMetaData deployment) throws DeploymentException
+ public void deploy(DeploymentUnit unit, WebMetaData metaData)
+ throws DeploymentException
{
- log.debug("deploy, deployment="+deployment);
+ String ctxPath = metaData.getContextRoot();
+ if (ctxPath.equals("/") || ctxPath.equals("/ROOT") || ctxPath.equals(""))
+ {
+ log.debug("deploy root context=" + ctxPath);
+ ctxPath = "/";
+ metaData.setContextRoot(ctxPath);
+ }
+
+ Thread thread = Thread.currentThread();
+ ClassLoader appClassLoader = thread.getContextClassLoader();
+ WebApplication warInfo = null;
+ try
+ {
+ // Create a classloader for the war to ensure a unique ENC
+ URL[] empty = {};
+ ClassLoader ucl = unit.getClassLoader();
+ URLClassLoader warLoader1 = URLClassLoader.newInstance(empty, ucl);
+ URLClassLoader warLoader = warLoader1;
+ thread.setContextClassLoader(warLoader);
+ String webContext = null; // TODO
+ if (webContext != null && webContext.startsWith("/") == false)
+ webContext = "/" + webContext;
+
+ // Get the war URL
+ URL warURL = unit.getDeploymentContext().getRoot().toURL();
+
+ log.debug("webContext: " + webContext);
+ log.debug("warURL: " + warURL);
+
+ /* TODO: this needs to be coming from the metadata parsing
+ inherit the security setup from jboss-app.xml
+ if (di.parent != null && di.parent.metaData instanceof J2eeApplicationMetaData)
+ {
+ J2eeApplicationMetaData appMetaData = (J2eeApplicationMetaData) di.parent.metaData;
+
+ if (metaData.getSecurityDomain() == null)
+ metaData.setSecurityDomain(appMetaData.getSecurityDomain());
+
+ metaData.mergeSecurityRoles(appMetaData.getSecurityRoles());
+ }
+ */
+
+ // Register the permissions with the JACC layer
+ String contextID = unit.getName();
+ metaData.setJaccContextID(contextID);
+ PolicyConfigurationFactory pcFactory = PolicyConfigurationFactory.getPolicyConfigurationFactory();
+ PolicyConfiguration pc = pcFactory.getPolicyConfiguration(contextID, true);
+ createPermissions(metaData, pc);
+ // Link this to the parent PC
+ DeploymentContext current = unit.getDeploymentContext();
+ while (current.getParent() != null)
+ current = current.getParent();
+ PolicyConfiguration parentPC =
+ current.getTransientAttachments().getAttachment(PolicyConfiguration.class);
+ if (parentPC != null && parentPC != pc)
+ parentPC.linkConfiguration(pc);
+
+ // Commit the policy configuration
+ pc.commit();
+ // Allow the policy to incorporate the policy configs
+ Policy.getPolicy().refresh();
+
+ warInfo = new WebApplication(metaData);
+ warInfo.setClassLoader(warLoader);
+ warInfo.setDeployerConfig(config);
+ performDeploy(unit, warInfo, warURL.toString());
+ }
+ catch (Exception e)
+ {
+ throw DeploymentException.rethrowAsDeploymentException("Error creating war deployment " + unit.getName(), e);
+ }
+ finally
+ {
+ thread.setContextClassLoader(appClassLoader);
+ }
}
+ protected void performDeploy(DeploymentUnit unit, WebApplication warInfo, String warUrl)
+ throws Exception
+ {
+ WebMetaData metaData = warInfo.getMetaData();
+ // TODO: Need to remove the dependency on MBeanServer
+ MBeanServer server = MBeanServerLocator.locateJBoss();
+ String hostName = null;
+ // Get any jboss-web/virtual-hosts
+ Iterator vhostNames = metaData.getVirtualHosts();
+ // Map the virtual hosts onto the configured hosts
+ Iterator hostNames = mapVirtualHosts(server, warInfo, vhostNames);
+ if (hostNames.hasNext())
+ {
+ hostName = hostNames.next().toString();
+ }
+ performDeployInternal(unit, hostName, warInfo, warUrl);
+ while (hostNames.hasNext())
+ {
+ String additionalHostName = hostNames.next().toString();
+ performDeployInternal(unit, additionalHostName, warInfo, warUrl);
+ }
+ }
+
+ protected void performDeployInternal(DeploymentUnit unit, String hostName,
+ WebApplication warInfo, String warUrl)
+ throws Exception
+ {
+ log.debug("performDeployInternal, hostName="+hostName);
+ try
+ {
+ ServiceMetaData warDeployment = new ServiceMetaData();
+ String name = getObjectName(warInfo, hostName);
+ ObjectName objectName = new ObjectName(name);
+ warDeployment.setObjectName(objectName);
+ warDeployment.setCode(TomcatDeployment.class.getName());
+ ServiceConstructorMetaData constructor = new ServiceConstructorMetaData();
+ constructor.setSignature(new String[] { WebApplication.class.getName(),
+ "java.lang.String", "java.lang.String"});
+ constructor.setParameters(new Object[] { warInfo, hostName, warUrl});
+ warDeployment.setConstructor(constructor);
+
+ List<ServiceAttributeMetaData> attributes = new ArrayList<ServiceAttributeMetaData>();
+ ServiceAttributeMetaData attribute = null;
+ // ORB
+ {
+ attribute = new ServiceAttributeMetaData();
+ attribute.setName("ORB");
+ attribute.setValue(new ServiceInjectionValueMetaData(Container.ORB_NAME));
+ attributes.add(attribute);
+ }
+ if( attributes.isEmpty() == false )
+ warDeployment.setAttributes(attributes);
+
+ // TODO component
+ unit.addAttachment(ServiceMetaData.class, warDeployment);
+ }
+ catch (Exception e)
+ {
+ throw DeploymentException.rethrowAsDeploymentException("Error creating rar deployment " + unit.getName(), e);
+ }
+
+ }
+
@Override
public void undeploy(DeploymentUnit unit, WebMetaData deployment)
{
log.debug("undeploy, deployment="+deployment);
+ try
+ {
+ // TODO: Need to remove the dependency on MBeanServer
+ MBeanServer server = MBeanServerLocator.locateJBoss();
+ URL warURL = unit.getDeploymentContext().getRoot().toURL();
+ String warUrl = warURL.toString();
+ WebApplication webApp = unit.getAttachment(WebApplication.class);
+ performUndeploy(server, warUrl, webApp);
+ // Unregister the permissions with the JACC layer
+ WebMetaData metaData = webApp.getMetaData();
+ String contextID = metaData.getJaccContextID();
+ PolicyConfigurationFactory pcFactory = PolicyConfigurationFactory.getPolicyConfigurationFactory();
+ PolicyConfiguration pc = pcFactory.getPolicyConfiguration(contextID, true);
+ pc.delete();
+ //Unregister any xacml policies
+ String prefixedSecurityDomain = webApp.getMetaData().getSecurityDomain();
+ if(prefixedSecurityDomain != null)
+ {
+ AuthorizationManager authzmgr =
+ org.jboss.security.Util.getAuthorizationManager(prefixedSecurityDomain);
+ if(authzmgr instanceof PolicyRegistration)
+ {
+ PolicyRegistration xam = (PolicyRegistration)authzmgr;
+ xam.deRegisterPolicy(contextID);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ log.error("Error during deploy", e);
+ }
}
+ /**
+ * Called as part of the undeploy() method template to ask the
+ * subclass for perform the web container specific undeployment steps.
+ */
+ protected void performUndeploy(MBeanServer server, String warUrl, WebApplication appInfo)
+ throws Exception
+ {
+ if (appInfo == null)
+ {
+ log.debug("performUndeploy, no WebApplication found for URL "
+ + warUrl);
+ return;
+ }
+ log.info("undeploy, ctxPath=" + appInfo.getMetaData().getContextRoot()
+ + ", warUrl=" + warUrl);
+
+ WebMetaData metaData = appInfo.getMetaData();
+ String hostName = null;
+ Iterator hostNames = metaData.getVirtualHosts();
+ if (hostNames.hasNext())
+ {
+ hostName = hostNames.next().toString();
+ }
+ performUndeployInternal(server, hostName, warUrl, appInfo);
+ while (hostNames.hasNext())
+ {
+ String additionalHostName = hostNames.next().toString();
+ performUndeployInternal(server, additionalHostName, warUrl, appInfo);
+ }
+
+ }
+
+ protected void performUndeployInternal(MBeanServer server, String hostName,
+ String warUrl, WebApplication appInfo)
+ throws Exception
+ {
+
+ WebMetaData metaData = appInfo.getMetaData();
+ String ctxPath = metaData.getContextRoot();
+
+ // If the server is gone, all apps were stopped already
+ if (server == null)
+ return;
+
+ ObjectName objectName = new ObjectName(appInfo.getDomain()
+ + ":j2eeType=WebModule,name=//" +
+ ((hostName == null) ? "localhost" : hostName)
+ + ctxPath + ",J2EEApplication=none,J2EEServer=none");
+
+ if (server.isRegistered(objectName))
+ {
+ // Contexts should be stopped by the host already
+ server.invoke(objectName, "destroy", new Object[]{},
+ new String[]{});
+ }
+
+ }
+
+
+ /**
+ * Create the JACC permission based on the security constraints obtained from
+ * the web.xml metadata.
+ * @param metaData
+ * @param pc
+ * @throws PolicyContextException
+ */
+ protected void createPermissions(WebMetaData metaData, PolicyConfiguration pc)
+ throws PolicyContextException
+ {
+ WebPermissionMapping.createPermissions(metaData, pc);
+ }
+
+ /**
+ *
+ * @param unit
+ * @param cmd
+ * @return
+ */
+ protected String getObjectName(WebApplication warInfo, String hostName)
+ {
+ String ctxPath = warInfo.getMetaData().getContextRoot();
+ String objectName = warInfo.getDomain()
+ + ":j2eeType=WebModule,name=//" +
+ ((hostName == null) ? "localhost" : hostName)
+ + ctxPath + ",J2EEApplication=none,J2EEServer=none";
+
+ return objectName;
+ }
+
+ /**
+ * Resolve the input virtual host names to the names of the configured Hosts
+ * @param vhostNames Iterator<String> for the jboss-web/virtual-host elements
+ * @return Iterator<String> of the unique Host names
+ * @throws Exception
+ */
+ protected synchronized Iterator mapVirtualHosts(MBeanServer server, WebApplication config, Iterator vhostNames)
+ throws Exception
+ {
+ Map vhostToHostNames = config.getVhostToHostNames();
+ if (vhostToHostNames.size() == 0)
+ {
+ // Query the configured Host mbeans
+ String hostQuery = config.getDomain() + ":type=Host,*";
+ ObjectName query = new ObjectName(hostQuery);
+ Set hosts = server.queryNames(query, null);
+ Iterator iter = hosts.iterator();
+ while (iter.hasNext())
+ {
+ ObjectName host = (ObjectName)iter.next();
+ String name = host.getKeyProperty("host");
+ if (name != null)
+ {
+ vhostToHostNames.put(name, name);
+ String[] aliases = (String[])
+ server.invoke(host, "findAliases", null, null);
+ int count = aliases != null ? aliases.length : 0;
+ for (int n = 0; n < count; n++)
+ {
+ vhostToHostNames.put(aliases[n], name);
+ }
+ }
+ }
+ }
+
+ // Map the virtual host names to the hosts
+ HashSet hosts = new HashSet();
+ while (vhostNames.hasNext())
+ {
+ String vhost = (String)vhostNames.next();
+ String host = (String)vhostToHostNames.get(vhost);
+ if (host == null)
+ {
+ log.warn("Failed to map vhost: " + vhost);
+ // This will cause a new host to be created
+ host = vhost;
+ }
+ hosts.add(host);
+ }
+ return hosts.iterator();
+ }
+
}
More information about the jboss-cvs-commits
mailing list