//======================================================================== //$Id: $ //JBoss Jetty Integration //------------------------------------------------------------------------ //Licensed under LGPL. //See license terms at http://www.gnu.org/licenses/lgpl.html //======================================================================== package org.jboss.jetty; import java.lang.reflect.Method; import javax.management.MBeanRegistration; import javax.management.MBeanServer; import javax.management.ObjectName; import org.jboss.deployment.DeploymentException; import org.jboss.deployment.DeploymentInfo; import org.jboss.deployment.SubDeployerExt; import org.jboss.mx.util.MBeanProxyExt; import org.jboss.system.ServiceControllerMBean; import org.jboss.web.AbstractWebContainer; import org.jboss.web.AbstractWebDeployer; import org.jboss.web.WebApplication; import org.w3c.dom.Element; //------------------------------------------------------------------------------ /** * JettyService * A service to launch jetty as the webserver for JBoss. * * * @jmx:mbean name="jboss.jetty:service=Jetty" * extends="org.jboss.web.AbstractWebContainerMBean" * * @todo convert to use JMXDoclet... * */ public class JettyService extends AbstractWebContainer implements JettyServiceMBean, MBeanRegistration { public static final String NAME = "Jetty"; protected MBeanServer _server = null; protected Jetty _jetty = null; protected Element _jettyConfig = null; protected boolean _supportJSR77; protected String _webDefaultResource; protected SubDeployerExt subDeployerProxy = null; /** * ConfigurationData * * Holds info that the jboss API sets on the * AbstractWebContainer but is needed by the * AbstractWebDeployer. */ public static class ConfigurationData { private boolean _loaderCompliance; private boolean _unpackWars; private boolean _lenientEjbLink; private String _subjectAttributeName; private String _defaultSecurityDomain; private boolean _acceptNonWarDirs; private String _webDefaultResource; private boolean _supportJSR77; private String _mbeanDomain; /** * @return the _webDefaultResource */ public String getWebDefaultResource() { return _webDefaultResource; } /** * @param defaultResource the _webDefaultResource to set */ public void setWebDefaultResource(String defaultResource) { _webDefaultResource = defaultResource; } public void setJava2ClassLoadingCompliance(boolean loaderCompliance) { _loaderCompliance=loaderCompliance; } public boolean getJava2ClassLoadingCompliance() { return _loaderCompliance; } public boolean getUnpackWars() { return _unpackWars; } public void setUnpackWars(boolean unpackWars) { _unpackWars=unpackWars; } public void setLenientEjbLink (boolean lenientEjbLink) { _lenientEjbLink=lenientEjbLink; } public boolean getLenientEjbLink() { return _lenientEjbLink; } public String getSubjectAttributeName() { return _subjectAttributeName; } /** * @jmx:managed-attribute */ public void setSubjectAttributeName(String subjectAttributeName) { _subjectAttributeName=subjectAttributeName; } /** * @return the _defaultSecurityDomain */ public String getDefaultSecurityDomain() { return _defaultSecurityDomain; } /** * @param securityDomain the _defaultSecurityDomain to set */ public void setDefaultSecurityDomain(String securityDomain) { _defaultSecurityDomain = securityDomain; } /** * @return the _acceptNonWarDirs */ public boolean getAcceptNonWarDirs() { return _acceptNonWarDirs; } /** * @param nonWarDirs the _acceptNonWarDirs to set */ public void setAcceptNonWarDirs(boolean nonWarDirs) { _acceptNonWarDirs = nonWarDirs; } /** * @return the _supportJSR77 */ public boolean getSupportJSR77() { return _supportJSR77; } /** * @param _supportjsr77 the _supportJSR77 to set */ public void setSupportJSR77(boolean _supportjsr77) { _supportJSR77 = _supportjsr77; } /** * @return the _mbeanDomain */ public String getMBeanDomain() { return _mbeanDomain; } /** * @param domain the _mbeanDomain to set */ public void setMBeanDomain(String domain) { _mbeanDomain = domain; } } /** * Constructor */ public JettyService() { super(); _jetty = new Jetty(this); } /** * Listen for our registration as an mbean and remember our name. * @see org.jboss.system.ServiceMBeanSupport#preRegister(javax.management.MBeanServer, javax.management.ObjectName) */ public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception { super.preRegister(server, name); name = getObjectName(server, name); _server = server; return name; } /** * Listen for post-mbean registration and set up the jetty * mbean infrastructure so it can generate mbeans according * to the elements contained in the <configuration> element * of the jboss-service.xml file. * @see org.jboss.system.ServiceMBeanSupport#postRegister(java.lang.Boolean) */ public void postRegister(Boolean done) { super.postRegister(done); try { log.debug("Setting up mbeanlistener on Jetty"); _jetty.getContainer().addEventListener(new JBossMBeanContainer(_server)); } catch (Throwable e) { log.error("could not create MBean peers", e); } } /** * @see org.jboss.system.ServiceMBeanSupport#getName() */ public String getName() { return NAME; } /** * @see org.jboss.deployment.SubDeployerSupport#createService() */ public void createService() throws Exception { super.createService(); if (_jettyConfig != null) _jetty.setConfigurationElement(_jettyConfig); } /** * Start up the jetty service. Also, as we need to be able * to have interceptors injected into us to support jboss.ws:service=WebService, * we need to create a proxy to ourselves and register that proxy with the * mainDeployer. * See <a href="http://wiki.jboss.org/wiki/Wiki.jsp?page=SubDeployerInterceptorSupport">SubDeployerInterceptorSupport</a> * @see org.jboss.web.AbstractWebContainer#startService() */ public void startService() throws Exception { //do what AbstractWebContainer.startService() would have done serviceController = (ServiceControllerMBean) MBeanProxyExt.create(ServiceControllerMBean.class, ServiceControllerMBean.OBJECT_NAME, server); //instead of calling mainDeployer.addDeployer(this) as SubDeployerSupport super class does, //we register instead a proxy to oursevles so we can support dynamic addition of interceptors subDeployerProxy = (SubDeployerExt)MBeanProxyExt.create(SubDeployerExt.class, super.getServiceName(), super.getServer()); mainDeployer.addDeployer(subDeployerProxy); _jetty.start(); } public void stopService() throws Exception { mainDeployer.removeDeployer(subDeployerProxy); _jetty.stop(); } public void destroyService() throws Exception { super.destroyService(); _jetty.stop(); _jetty = null; } /** * @jmx:managed-attribute */ public boolean getSupportJSR77() { return _supportJSR77; } /** * @jmx:managed-attribute */ public void setSupportJSR77(boolean supportJSR77) { if (log.isDebugEnabled()) log.debug("set SupportJSR77 to " + supportJSR77); _supportJSR77=supportJSR77; } /** * Get the custom webdefault.xml file. * @jmx:managed-attribute */ public String getWebDefaultResource() { return _webDefaultResource; } /** * Set a custom webdefault.xml file. * @jmx:managed-attribute */ public void setWebDefaultResource(String webDefaultResource) { if (log.isDebugEnabled()) log.debug("set WebDefaultResource to " + webDefaultResource); _webDefaultResource=webDefaultResource; } /** * Get the extended Jetty configuration XML fragment * * @jmx:managed-attribute * @return Jetty XML fragment embedded in jboss-service.xml */ public Element getConfigurationElement() { return _jettyConfig; } /** * Configure Jetty * * @param configElement XML fragment from jboss-service.xml * @jmx:managed-attribute */ public void setConfigurationElement(Element configElement) { log.debug("Saving Configuration to xml fragment"); this._jettyConfig = configElement; } /** * Old deployment method from AbstractWebContainer. * * TODO remove this? * @param webApp * @param warUrl * @param parser * @throws DeploymentException */ public void performDeploy(WebApplication webApp, String warUrl, WebDescriptorParser parser) throws DeploymentException { //TODO: backwards compatibility? throw new UnsupportedOperationException("Backward compatibility not implemented"); } /** * Old undeploy method from AbstractWebContainer. * * TODO remove? * @param warUrl * @throws DeploymentException */ public void performUndeploy(String warUrl) throws DeploymentException { //TODO backwards compatibility? throw new UnsupportedOperationException("Backward compatibility not implemented"); } /** * @see org.jboss.web.AbstractWebContainer#getDeployer(org.jboss.deployment.DeploymentInfo) */ public AbstractWebDeployer getDeployer(DeploymentInfo di) throws Exception { JettyDeployer deployer = new JettyDeployer(_jetty, di); ConfigurationData configData = new ConfigurationData(); configData.setMBeanDomain("jboss.jetty"); configData.setAcceptNonWarDirs(getAcceptNonWarDirs()); configData.setJava2ClassLoadingCompliance(getJava2ClassLoadingCompliance()); configData.setLenientEjbLink(getLenientEjbLink()); configData.setSubjectAttributeName(getSubjectAttributeName()); configData.setSupportJSR77(getSupportJSR77()); configData.setUnpackWars(getUnpackWars()); configData.setWebDefaultResource(getWebDefaultResource()); //defaultSecurityDomain was added at a certain point, so do it //this way so we have backwards compatibility try { Method method = AbstractWebContainer.class.getDeclaredMethod("getDefaultSecurityDomain", new Class[0]); String defaultSecurityDomain = (String) method.invoke(JettyService.this, new Object[0]); configData.setDefaultSecurityDomain(defaultSecurityDomain); } catch (Exception e) { // ignore - it means the currently executing version of jboss // does not support this method log.info("Getter/setter for DefaultSecurityDomain not available in this version of JBoss"); } deployer.setServer(_server); deployer.init(configData); return deployer; } }