All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mortbay.jetty.plugin.AbstractJettyMojo Maven / Gradle / Ivy

There is a newer version: 7.0.0.pre5
Show newest version
//========================================================================
//$Id: AbstractJettyMojo.java 5511 2009-09-08 03:25:47Z janb $
//Copyright 2000-2004 Mort Bay Consulting Pty. Ltd.
//------------------------------------------------------------------------
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//http://www.apache.org/licenses/LICENSE-2.0
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
//========================================================================


package org.mortbay.jetty.plugin;


import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.plugin.util.ConsoleScanner;
import org.mortbay.jetty.plugin.util.JettyPluginServer;
import org.mortbay.jetty.plugin.util.PluginLog;
import org.mortbay.jetty.plugin.util.SystemProperties;
import org.mortbay.jetty.plugin.util.SystemProperty;
import org.mortbay.util.Scanner;



/**
 * AbstractJettyMojo
 *
 *
 */
public abstract class AbstractJettyMojo extends AbstractMojo
{
    /**
     * The proxy for the Server object
     */
    protected JettyPluginServer server;


    /**
     * The "virtual" webapp created by the plugin
     * @parameter
     */
    protected Jetty6PluginWebAppContext webAppConfig;



    /**
     * The maven project.
     *
     * @parameter expression="${executedProject}"
     * @required
     * @readonly
     */
    protected MavenProject project;



    /**
     * The context path for the webapp. Defaults to the
     * name of the webapp's artifact.
     *
     * @parameter expression="/${project.artifactId}"
     * @required
     */
    protected String contextPath;


    /**
     * The temporary directory to use for the webapp.
     * Defaults to target/jetty-tmp
     *
     * @parameter expression="${project.build.directory}/work"
     * @required
     */
    protected File tmpDirectory;



    /**
     * A webdefault.xml file to use instead
     * of the default for the webapp. Optional.
     *
     * @parameter
     */
    protected File webDefaultXml;


    /**
     * A web.xml file to be applied AFTER
     * the webapp's web.xml file. Useful for
     * applying different build profiles, eg
     * test, production etc. Optional.
     * @parameter
     */
    protected File overrideWebXml;
    
    /**
     * The interval in seconds to scan the webapp for changes 
     * and restart the context if necessary. Ignored if reload
     * is enabled. Disabled by default.
     * 
     * @parameter expression="${jetty.scanIntervalSeconds}" default-value="0"
     * @required
     */
    protected int scanIntervalSeconds;
    
    
    /**
     * reload can be set to either 'automatic' or 'manual'
     *
     * if 'manual' then the context can be reloaded by a linefeed in the console
     * if 'automatic' then traditional reloading on changed files is enabled.
     * 
     * @parameter expression="${jetty.reload}" default-value="automatic"
     */
    protected String reload;
    
    /**
     * File containing system properties to be set before execution
     * 
     * Note that these properties will NOT override System properties
     * that have been set on the command line, by the JVM, or directly 
     * in the POM via systemProperties. Optional.
     * 
     * @parameter expression="${jetty.systemPropertiesFile}"
     */
    protected File systemPropertiesFile;

    /**
     * System properties to set before execution. 
     * Note that these properties will NOT override System properties 
     * that have been set on the command line or by the JVM. They WILL 
     * override System properties that have been set via systemPropertiesFile.
     * Optional.
     * @parameter
     */
    protected SystemProperties systemProperties;
    
    
    
    /**
     * Location of a jetty xml configuration file whose contents 
     * will be applied before any plugin configuration. Optional.
     * @parameter
     */
    protected File jettyConfig;
    
    /**
     * Port to listen to stop jetty on executing -DSTOP.PORT=<stopPort> 
     * -DSTOP.KEY=<stopKey> -jar start.jar --stop
     * @parameter
     */
    protected int stopPort;
    
    /**
     * Key to provide when stopping jetty on executing java -DSTOP.KEY=<stopKey> 
     * -DSTOP.PORT=<stopPort> -jar start.jar --stop
     * @parameter
     */
    protected String stopKey;

    /**
 	 * 

* Determines whether or not the server blocks when started. The default * behavior (daemon = false) will cause the server to pause other processes * while it continues to handle web requests. This is useful when starting the * server with the intent to work with it interactively. *

* Often, it is desirable to let the server start and continue running subsequent * processes in an automated build environment. This can be facilitated by setting * daemon to true. *

* @parameter expression="${jetty.daemon}" default-value="false" */ protected boolean daemon; /** * A scanner to check for changes to the webapp */ protected Scanner scanner; /** * List of files and directories to scan */ protected ArrayList scanList; /** * List of Listeners for the scanner */ protected ArrayList scannerListeners; /** * A scanner to check ENTER hits on the console */ protected Thread consoleScanner; public String PORT_SYSPROPERTY = "jetty.port"; /** * @return Returns the realms configured in the pom */ public abstract Object[] getConfiguredUserRealms(); /** * @return Returns the connectors configured in the pom */ public abstract Object[] getConfiguredConnectors(); public abstract Object getConfiguredRequestLog(); public abstract void checkPomConfiguration() throws MojoExecutionException; public abstract void configureScanner () throws MojoExecutionException; public abstract void applyJettyXml () throws Exception; /** * create a proxy that wraps a particular jetty version Server object * @return */ public abstract JettyPluginServer createServer() throws Exception; public abstract void finishConfigurationBeforeStart() throws Exception; public MavenProject getProject() { return this.project; } public File getTmpDirectory() { return this.tmpDirectory; } public File getWebDefaultXml() { return this.webDefaultXml; } public File getOverrideWebXml() { return this.overrideWebXml; } /** * @return Returns the contextPath. */ public String getContextPath() { return this.contextPath; } /** * @return Returns the scanIntervalSeconds. */ public int getScanIntervalSeconds() { return this.scanIntervalSeconds; } /** * @return returns the path to the systemPropertiesFile */ public File getSystemPropertiesFile() { return this.systemPropertiesFile; } public void setSystemPropertiesFile(File file) throws Exception { this.systemPropertiesFile = file; FileInputStream propFile = new FileInputStream(systemPropertiesFile); Properties properties = new Properties(); properties.load(propFile); if (this.systemProperties == null ) this.systemProperties = new SystemProperties(); for (Enumeration keys = properties.keys(); keys.hasMoreElements(); ) { String key = (String)keys.nextElement(); if ( ! systemProperties.containsSystemProperty(key) ) { SystemProperty prop = new SystemProperty(); prop.setKey(key); prop.setValue(properties.getProperty(key)); this.systemProperties.setSystemProperty(prop); } } } public void setSystemProperties(SystemProperties systemProperties) { if (this.systemProperties == null) this.systemProperties = systemProperties; else { Iterator itor = systemProperties.getSystemProperties().iterator(); while (itor.hasNext()) { SystemProperty prop = (SystemProperty)itor.next(); this.systemProperties.setSystemProperty(prop); } } } public File getJettyXmlFile () { return this.jettyConfig; } public JettyPluginServer getServer () { return this.server; } public void setServer (JettyPluginServer server) { this.server = server; } public void setScanList (ArrayList list) { this.scanList = new ArrayList(list); } public ArrayList getScanList () { return this.scanList; } public void setScannerListeners (ArrayList listeners) { this.scannerListeners = new ArrayList(listeners); } public ArrayList getScannerListeners () { return this.scannerListeners; } public Scanner getScanner () { return scanner; } public void execute() throws MojoExecutionException, MojoFailureException { getLog().info("Configuring Jetty for project: " + getProject().getName()); PluginLog.setLog(getLog()); checkPomConfiguration(); startJetty(); } public void startJetty () throws MojoExecutionException { try { getLog().debug("Starting Jetty Server ..."); printSystemProperties(); setServer(createServer()); //apply any config from a jetty.xml file first which is able to //be overwritten by config in the pom.xml applyJettyXml (); JettyPluginServer plugin=getServer(); // if the user hasn't configured their project's pom to use a // different set of connectors, // use the default Object[] configuredConnectors = getConfiguredConnectors(); plugin.setConnectors(configuredConnectors); Object[] connectors = plugin.getConnectors(); if (connectors == null|| connectors.length == 0) { //if a SystemProperty -Djetty.port= has been supplied, use that as the default port configuredConnectors = new Object[] { plugin.createDefaultConnector(System.getProperty(PORT_SYSPROPERTY, null)) }; plugin.setConnectors(configuredConnectors); } //set up a RequestLog if one is provided if (getConfiguredRequestLog() != null) getServer().setRequestLog(getConfiguredRequestLog()); //set up the webapp and any context provided getServer().configureHandlers(); configureWebApplication(); getServer().addWebApplication(webAppConfig); // set up security realms Object[] configuredRealms = getConfiguredUserRealms(); for (int i = 0; (configuredRealms != null) && i < configuredRealms.length; i++) getLog().debug(configuredRealms[i].getClass().getName() + ": "+ configuredRealms[i].toString()); plugin.setUserRealms(configuredRealms); //do any other configuration required by the //particular Jetty version finishConfigurationBeforeStart(); // start Jetty server.start(); getLog().info("Started Jetty Server"); if(stopPort>0 && stopKey!=null) { org.mortbay.jetty.plugin.util.Monitor monitor = new org.mortbay.jetty.plugin.util.Monitor(stopPort, stopKey, new Server[]{(Server)server.getProxiedObject()}, !daemon); monitor.start(); } // start the scanner thread (if necessary) on the main webapp configureScanner (); startScanner(); // start the new line scanner thread if necessary startConsoleScanner(); // keep the thread going if not in daemon mode if (!daemon) { server.join(); } } catch (Exception e) { throw new MojoExecutionException("Failure", e); } finally { if (!daemon) { getLog().info("Jetty server exiting."); } } } public abstract void restartWebApp(boolean reconfigureScanner) throws Exception; /** * Subclasses should invoke this to setup basic info * on the webapp * * @throws MojoExecutionException */ public void configureWebApplication () throws Exception { //use EITHER a element or the now deprecated , , , //way of doing things if (webAppConfig == null) { webAppConfig = new Jetty6PluginWebAppContext(); webAppConfig.setContextPath((getContextPath().startsWith("/") ? getContextPath() : "/"+ getContextPath())); if (getTmpDirectory() != null) webAppConfig.setTempDirectory(getTmpDirectory()); if (getWebDefaultXml() != null) webAppConfig.setDefaultsDescriptor(getWebDefaultXml().getCanonicalPath()); if (getOverrideWebXml() != null) webAppConfig.setOverrideDescriptor(getOverrideWebXml().getCanonicalPath()); } if (webAppConfig.getContextPath() == null) { webAppConfig.setContextPath((getContextPath().startsWith("/") ? getContextPath() : "/"+ getContextPath())); } getLog().info("Context path = " + webAppConfig.getContextPath()); getLog().info("Tmp directory = "+ " determined at runtime"); getLog().info("Web defaults = "+(webAppConfig.getDefaultsDescriptor()==null?" jetty default":webAppConfig.getDefaultsDescriptor())); getLog().info("Web overrides = "+(webAppConfig.getOverrideDescriptor()==null?" none":webAppConfig.getOverrideDescriptor())); } /** * Run a scanner thread on the given list of files and directories, calling * stop/start on the given list of LifeCycle objects if any of the watched * files change. * */ private void startScanner() { // check if scanning is enabled if (getScanIntervalSeconds() <= 0) return; // check if reload is manual. It disables file scanning if ( "manual".equalsIgnoreCase( reload ) ) { // issue a warning if both scanIntervalSeconds and reload // are enabled getLog().warn("scanIntervalSeconds is set to " + scanIntervalSeconds + " but will be IGNORED due to manual reloading"); return; } scanner = new Scanner(); scanner.setReportExistingFilesOnStartup(false); scanner.setScanInterval(getScanIntervalSeconds()); scanner.setScanDirs(getScanList()); scanner.setRecursive(true); List listeners = getScannerListeners(); Iterator itor = (listeners==null?null:listeners.iterator()); while (itor!=null && itor.hasNext()) scanner.addListener((Scanner.Listener)itor.next()); getLog().info("Starting scanner at interval of " + getScanIntervalSeconds()+ " seconds."); scanner.start(); } /** * Run a thread that monitors the console input to detect ENTER hits. */ protected void startConsoleScanner() { if ( "manual".equalsIgnoreCase( reload ) ) { getLog().info("Console reloading is ENABLED. Hit ENTER on the console to restart the context."); consoleScanner = new ConsoleScanner(this); consoleScanner.start(); } } private void printSystemProperties () { // print out which system properties were set up if (getLog().isDebugEnabled()) { if (systemProperties != null) { Iterator itor = systemProperties.getSystemProperties().iterator(); while (itor.hasNext()) { SystemProperty prop = (SystemProperty)itor.next(); getLog().debug("Property "+prop.getName()+"="+prop.getValue()+" was "+ (prop.isSet() ? "set" : "skipped")); } } } } /** * Try and find a jetty-web.xml file, using some * historical naming conventions if necessary. * @param webInfDir * @return */ public File findJettyWebXmlFile (File webInfDir) { if (webInfDir == null) return null; if (!webInfDir.exists()) return null; File f = new File (webInfDir, "jetty-web.xml"); if (f.exists()) return f; //try some historical alternatives f = new File (webInfDir, "web-jetty.xml"); if (f.exists()) return f; f = new File (webInfDir, "jetty6-web.xml"); if (f.exists()) return f; return null; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy