JETTY-796 jetty ant plugin improvements

This commit is contained in:
Jan Bartel 2012-12-07 16:25:26 +11:00
parent 53892b1d31
commit e612c19eb7
38 changed files with 1752 additions and 1164 deletions

View File

@ -0,0 +1,596 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Sabre Holdings.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.ant;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.servlet.Servlet;
import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.FileSet;
import org.eclipse.jetty.annotations.AnnotationConfiguration;
import org.eclipse.jetty.ant.types.Attribute;
import org.eclipse.jetty.ant.types.Attributes;
import org.eclipse.jetty.ant.types.FileMatchingConfiguration;
import org.eclipse.jetty.ant.utils.TaskLog;
import org.eclipse.jetty.plus.webapp.EnvConfiguration;
import org.eclipse.jetty.plus.webapp.PlusConfiguration;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.servlet.Holder;
import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.FragmentConfiguration;
import org.eclipse.jetty.webapp.JettyWebXmlConfiguration;
import org.eclipse.jetty.webapp.MetaInfConfiguration;
import org.eclipse.jetty.webapp.TagLibConfiguration;
import org.eclipse.jetty.webapp.WebAppClassLoader;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.webapp.WebInfConfiguration;
import org.eclipse.jetty.webapp.WebXmlConfiguration;
import org.eclipse.jetty.xml.XmlConfiguration;
/**
* AntWebAppContext
*
* Extension of WebAppContext to allow configuration via Ant environment.
*
*/
public class AntWebAppContext extends WebAppContext
{
public final AntWebInfConfiguration antWebInfConfiguration = new AntWebInfConfiguration();
public final WebXmlConfiguration webXmlConfiguration = new WebXmlConfiguration();
public final MetaInfConfiguration metaInfConfiguration = new MetaInfConfiguration();
public final FragmentConfiguration fragmentConfiguration = new FragmentConfiguration();
public final EnvConfiguration envConfiguration = new EnvConfiguration();
public final PlusConfiguration plusConfiguration = new PlusConfiguration();
public final AnnotationConfiguration annotationConfiguration = new AnnotationConfiguration();
public final JettyWebXmlConfiguration jettyWebXmlConfiguration = new JettyWebXmlConfiguration();
public final TagLibConfiguration tagLibConfiguration = new TagLibConfiguration();
public final Configuration[] DEFAULT_CONFIGURATIONS =
{
antWebInfConfiguration,
webXmlConfiguration,
metaInfConfiguration,
fragmentConfiguration,
envConfiguration,
plusConfiguration,
annotationConfiguration,
jettyWebXmlConfiguration,
tagLibConfiguration
};
public final static String DEFAULT_CONTAINER_INCLUDE_JAR_PATTERN =
".*/.*jsp-api-[^/]*\\.jar$|.*/.*jsp-[^/]*\\.jar$|.*/.*taglibs[^/]*\\.jar$|.*/.*jstl[^/]*\\.jar$|.*/.*jsf-impl-[^/]*\\.jar$|.*/.*javax.faces-[^/]*\\.jar$|.*/.*myfaces-impl-[^/]*\\.jar$";
/** Location of jetty-env.xml file. */
private File jettyEnvXml;
/** List of web application libraries. */
private List libraries = new ArrayList();
/** List of web application class directories. */
private List classes = new ArrayList();
/** context xml file to apply to the webapp */
private File contextXml;
/** List of extra scan targets for this web application. */
private FileSet scanTargets;
/** context attributes to set **/
private Attributes attributes;
private Project project;
private List<File> scanFiles;
/** Extra scan targets. */
private FileMatchingConfiguration extraScanTargetsConfiguration;
private FileMatchingConfiguration librariesConfiguration;
public static void dump(ClassLoader loader)
{
while (loader != null)
{
System.err.println(loader);
if (loader instanceof URLClassLoader)
{
URL[] urls = ((URLClassLoader)loader).getURLs();
if (urls != null)
{
for (URL u:urls)
System.err.println("\t"+u+"\n");
}
}
loader = loader.getParent();
}
}
/**
* AntServletHolder
*
*
*/
public static class AntServletHolder extends ServletHolder
{
public AntServletHolder()
{
super();
}
public AntServletHolder(Class<? extends Servlet> servlet)
{
super(servlet);
}
public AntServletHolder(Servlet servlet)
{
super(servlet);
}
public AntServletHolder(String name, Class<? extends Servlet> servlet)
{
super(name, servlet);
}
public AntServletHolder(String name, Servlet servlet)
{
super(name, servlet);
}
@Override
protected void initJspServlet() throws Exception
{
//super.initJspServlet();
ContextHandler ch = ContextHandler.getContextHandler(getServletHandler().getServletContext());
/* Set the webapp's classpath for Jasper */
ch.setAttribute("org.apache.catalina.jsp_classpath", ch.getClassPath());
/* Set the system classpath for Jasper */
String sysClassPath = getSystemClassPath(ch.getClassLoader().getParent());
setInitParameter("com.sun.appserv.jsp.classpath", sysClassPath);
/* Set up other classpath attribute */
if ("?".equals(getInitParameter("classpath")))
{
String classpath = ch.getClassPath();
if (classpath != null)
setInitParameter("classpath", classpath);
}
}
protected String getSystemClassPath (ClassLoader loader) throws Exception
{
StringBuilder classpath=new StringBuilder();
while (loader != null)
{
if (loader instanceof URLClassLoader)
{
URL[] urls = ((URLClassLoader)loader).getURLs();
if (urls != null)
{
for (int i=0;i<urls.length;i++)
{
Resource resource = Resource.newResource(urls[i]);
File file=resource.getFile();
if (file!=null && file.exists())
{
if (classpath.length()>0)
classpath.append(File.pathSeparatorChar);
classpath.append(file.getAbsolutePath());
}
}
}
}
else if (loader instanceof AntClassLoader)
{
classpath.append(((AntClassLoader)loader).getClasspath());
}
loader = loader.getParent();
}
return classpath.toString();
}
}
/**
* AntServletHandler
*
*
*/
public static class AntServletHandler extends ServletHandler
{
@Override
public ServletHolder newServletHolder(Holder.Source source)
{
return new AntServletHolder();
}
}
/**
* Default constructor. Takes application name as an argument
*
* @param name web application name.
*/
public AntWebAppContext(Project project) throws Exception
{
super();
this.project = project;
setConfigurations(DEFAULT_CONFIGURATIONS);
setAttribute(WebInfConfiguration.CONTAINER_JAR_PATTERN, DEFAULT_CONTAINER_INCLUDE_JAR_PATTERN);
setParentLoaderPriority(true);
}
/**
* Adds a new Ant's attributes tag object if it have not been created yet.
*/
public void addAttributes(Attributes atts)
{
if (this.attributes != null)
{
throw new BuildException("Only one <attributes> tag is allowed!");
}
this.attributes = atts;
}
public void addLib(FileSet lib)
{
libraries.add(lib);
}
public void addClasses(FileSet classes)
{
this.classes.add(classes);
}
@Override
protected ServletHandler newServletHandler()
{
return new AntServletHandler();
}
public void setJettyEnvXml(File jettyEnvXml)
{
this.jettyEnvXml = jettyEnvXml;
TaskLog.log("jetty-env.xml file: = " + (jettyEnvXml == null ? null : jettyEnvXml.getAbsolutePath()));
}
public File getJettyEnvXml ()
{
return this.jettyEnvXml;
}
public List getLibraries()
{
return librariesConfiguration.getBaseDirectories();
}
public void addScanTargets(FileSet scanTargets)
{
if (this.scanTargets != null)
{
throw new BuildException("Only one <scanTargets> tag is allowed!");
}
this.scanTargets = scanTargets;
}
public List getScanTargetFiles ()
{
if (this.scanTargets == null)
return null;
FileMatchingConfiguration configuration = new FileMatchingConfiguration();
configuration.addDirectoryScanner(scanTargets.getDirectoryScanner(project));
return configuration.getBaseDirectories();
}
public List<File> getScanFiles()
{
if (scanFiles == null)
scanFiles = initScanFiles();
return scanFiles;
}
public boolean isScanned (File file)
{
List<File> files = getScanFiles();
if (files == null || files.isEmpty())
return false;
return files.contains(file);
}
public List<File> initScanFiles ()
{
List<File> scanList = new ArrayList<File>();
if (getDescriptor() != null)
{
try
{
Resource r = Resource.newResource(getDescriptor());
scanList.add(r.getFile());
}
catch (IOException e)
{
throw new BuildException(e);
}
}
if (getJettyEnvXml() != null)
{
try
{
Resource r = Resource.newResource(getJettyEnvXml());
scanList.add(r.getFile());
}
catch (IOException e)
{
throw new BuildException("Problem configuring scanner for jetty-env.xml", e);
}
}
if (getDefaultsDescriptor() != null)
{
try
{
if (!AntWebAppContext.WEB_DEFAULTS_XML.equals(getDefaultsDescriptor()))
{
Resource r = Resource.newResource(getDefaultsDescriptor());
scanList.add(r.getFile());
}
}
catch (IOException e)
{
throw new BuildException("Problem configuring scanner for webdefaults.xml", e);
}
}
if (getOverrideDescriptor() != null)
{
try
{
Resource r = Resource.newResource(getOverrideDescriptor());
scanList.add(r.getFile());
}
catch (IOException e)
{
throw new BuildException("Problem configuring scanner for webdefaults.xml", e);
}
}
//add any extra classpath and libs
List<File> cpFiles = getClassPathFiles();
if (cpFiles != null)
scanList.addAll(cpFiles);
//any extra scan targets
@SuppressWarnings("unchecked")
List<File> scanFiles = (List<File>)getScanTargetFiles();
if (scanFiles != null)
scanList.addAll(scanFiles);
return scanList;
}
@Override
public void setWar(String path)
{
super.setWar(path);
try
{
Resource war = Resource.newResource(path);
if (war.exists() && war.isDirectory() && getDescriptor() == null)
{
Resource webXml = war.addPath("WEB-INF/web.xml");
setDescriptor(webXml.toString());
}
}
catch (IOException e)
{
throw new BuildException(e);
}
}
/**
* @see WebApplicationProxy#start()
*/
public void doStart()
{
try
{
TaskLog.logWithTimestamp("Starting web application "+this.getDescriptor());
if (jettyEnvXml != null && jettyEnvXml.exists())
envConfiguration.setJettyEnvXml(Resource.toURL(jettyEnvXml));
setClassLoader(new WebAppClassLoader(this.getClass().getClassLoader(), this));
if (attributes != null && attributes.getAttributes() != null)
{
for (Attribute a:attributes.getAttributes())
setAttribute(a.getName(), a.getValue());
}
//apply a context xml file if one was supplied
if (contextXml != null)
{
XmlConfiguration xmlConfiguration = new XmlConfiguration(Resource.toURL(contextXml));
TaskLog.log("Applying context xml file "+contextXml);
xmlConfiguration.configure(this);
}
super.doStart();
}
catch (Exception e)
{
TaskLog.log(e.toString());
}
}
/**
* @see WebApplicationProxy#stop()
*/
public void doStop()
{
try
{
scanFiles = null;
TaskLog.logWithTimestamp("Stopping web application "+this);
Thread.currentThread().sleep(500L);
super.doStop();
}
catch (InterruptedException e)
{
TaskLog.log(e.toString());
}
catch (Exception e)
{
TaskLog.log(e.toString());
}
}
/**
* @return a list of classpath files (libraries and class directories).
*/
public List<File> getClassPathFiles()
{
List<File> classPathFiles = new ArrayList<File>();
Iterator classesIterator = classes.iterator();
while (classesIterator.hasNext())
{
FileSet clazz = (FileSet) classesIterator.next();
classPathFiles.add(clazz.getDirectoryScanner(project).getBasedir());
}
Iterator iterator = libraries.iterator();
while (iterator.hasNext())
{
FileSet library = (FileSet) iterator.next();
String[] includedFiles = library.getDirectoryScanner(project).getIncludedFiles();
File baseDir = library.getDirectoryScanner(project).getBasedir();
for (int i = 0; i < includedFiles.length; i++)
{
classPathFiles.add(new File(baseDir, includedFiles[i]));
}
}
return classPathFiles;
}
/**
* @return a <code>FileMatchingConfiguration</code> object describing the
* configuration of all libraries added to this particular web app
* (both classes and libraries).
*/
public FileMatchingConfiguration getLibrariesConfiguration()
{
FileMatchingConfiguration config = new FileMatchingConfiguration();
Iterator classesIterator = classes.iterator();
while (classesIterator.hasNext())
{
FileSet clazz = (FileSet) classesIterator.next();
config.addDirectoryScanner(clazz.getDirectoryScanner(project));
}
Iterator librariesIterator = libraries.iterator();
while (librariesIterator.hasNext())
{
FileSet library = (FileSet) librariesIterator.next();
config.addDirectoryScanner(library.getDirectoryScanner(project));
}
return config;
}
public File getContextXml()
{
return contextXml;
}
public void setContextXml(File contextXml)
{
this.contextXml = contextXml;
}
}

View File

@ -29,8 +29,10 @@ import java.util.regex.Pattern;
import org.apache.tools.ant.AntClassLoader;
import org.eclipse.jetty.util.PatternMatcher;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.WebAppClassLoader;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.webapp.WebInfConfiguration;
import org.eclipse.jetty.webapp.WebXmlConfiguration;
public class AntWebInfConfiguration extends WebInfConfiguration
{
@ -98,7 +100,7 @@ public class AntWebInfConfiguration extends WebInfConfiguration
}
else if (loader instanceof AntClassLoader)
{
AntClassLoader antLoader = (AntClassLoader)loader;
AntClassLoader antLoader = (AntClassLoader)loader;
String[] paths = antLoader.getClasspath().split(new String(new char[]{File.pathSeparatorChar}));
if (paths != null)
{
@ -142,5 +144,29 @@ public class AntWebInfConfiguration extends WebInfConfiguration
webInfJarNameMatcher.match(webInfPattern, uris, true); //null is inclusive, no pattern == all jars match
}
/**
* Adds classpath files into web application classloader, and
* sets web.xml and base directory for the configured web application.
*
* @see WebXmlConfiguration#configure(WebAppContext)
*/
public void configure(WebAppContext context) throws Exception
{
if (context instanceof AntWebAppContext)
{
List<File> classPathFiles = ((AntWebAppContext)context).getClassPathFiles();
if (classPathFiles != null)
{
for (File cpFile:classPathFiles)
{
if (cpFile.exists())
{
((WebAppClassLoader) context.getClassLoader()).addClassPath(cpFile.getCanonicalPath());
}
}
}
}
super.configure(context);
}
}

View File

@ -48,23 +48,10 @@ public class AntWebXmlConfiguration extends WebXmlConfiguration
/** Web application root directory. */
private File webAppBaseDir;
/** Web application web.xml file. */
private File webXmlFile;
private File webDefaultXmlFile;
public AntWebXmlConfiguration() throws ClassNotFoundException
public AntWebXmlConfiguration()
{
}
public File getWebDefaultXmlFile()
{
return this.webDefaultXmlFile;
}
public void setWebDefaultXmlFile(File webDefaultXmlfile)
{
this.webDefaultXmlFile = webDefaultXmlfile;
super();
}
public void setClassPathFiles(List classPathFiles)
@ -77,48 +64,6 @@ public class AntWebXmlConfiguration extends WebXmlConfiguration
this.webAppBaseDir = webAppBaseDir;
}
public void setWebXmlFile(File webXmlFile)
{
this.webXmlFile = webXmlFile;
if (webXmlFile.exists())
{
TaskLog.log("web.xml file = " + webXmlFile);
}
}
/**
* Adds classpath files into web application classloader, and
* sets web.xml and base directory for the configured web application.
*
* @see WebXmlConfiguration#configure(WebAppContext)
*/
public void configure(WebAppContext context) throws Exception
{
if (context.isStarted())
{
TaskLog.log("Cannot configure webapp after it is started");
return;
}
if (webXmlFile.exists())
{
context.setDescriptor(webXmlFile.getCanonicalPath());
}
super.configure(context);
Iterator filesIterator = classPathFiles.iterator();
while (filesIterator.hasNext())
{
File classPathFile = (File) filesIterator.next();
if (classPathFile.exists())
{
((WebAppClassLoader) context.getClassLoader())
.addClassPath(classPathFile.getCanonicalPath());
}
}
}
}

View File

@ -26,14 +26,15 @@ import java.util.List;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.Property;
import org.eclipse.jetty.ant.types.Connector;
import org.eclipse.jetty.ant.types.Connectors;
import org.eclipse.jetty.ant.types.ContextHandlers;
import org.eclipse.jetty.ant.types.LoginServices;
import org.eclipse.jetty.ant.types.SystemProperties;
import org.eclipse.jetty.ant.types.WebApp;
import org.eclipse.jetty.ant.utils.ServerProxy;
import org.eclipse.jetty.ant.utils.TaskLog;
import org.eclipse.jetty.security.LoginService;
import org.eclipse.jetty.server.RequestLog;
import org.eclipse.jetty.util.Scanner;
import org.eclipse.jetty.webapp.WebAppContext;
/**
* Ant task for running a Jetty server.
@ -41,11 +42,14 @@ import org.eclipse.jetty.util.Scanner;
public class JettyRunTask extends Task
{
private int scanIntervalSeconds;
/** Temporary files directory. */
private File tempDirectory;
/** List of web applications to be deployed. */
private List webapps = new ArrayList();
private List<AntWebAppContext> webapps = new ArrayList<AntWebAppContext>();
/** Location of jetty.xml file. */
private File jettyXml;
@ -61,9 +65,21 @@ public class JettyRunTask extends Task
/** List of system properties to be set. */
private SystemProperties systemProperties;
/** List of other contexts to deploy */
private ContextHandlers contextHandlers;
/** Port Jetty will use for the default connector */
private int jettyPort = 8080;
private int stopPort;
private String stopKey;
private boolean daemon;
public JettyRunTask()
@ -75,10 +91,12 @@ public class JettyRunTask extends Task
* Creates a new <code>WebApp</code> Ant object.
*
*/
public void addWebApp(WebApp webapp)
public void addWebApp(AntWebAppContext webapp)
{
webapps.add(webapp);
webapps.add(webapp);
}
/**
* Adds a new Ant's connector tag object if it have not been created yet.
@ -86,61 +104,73 @@ public class JettyRunTask extends Task
public void addConnectors(Connectors connectors)
{
if (this.connectors != null)
{
throw new BuildException("Only one <connectors> tag is allowed!");
}
this.connectors = connectors;
}
/**
* @deprecated
*/
public void addUserRealms(Object o)
{
TaskLog.log("User realms are deprecated.");
}
/**
* @param services
*/
public void addLoginServices(LoginServices services)
{
if (this.loginServices != null )
{
throw new BuildException("Only one <loginServices> tag is allowed!");
}
throw new BuildException("Only one <loginServices> tag is allowed!");
this.loginServices = services;
}
public void addSystemProperties(SystemProperties systemProperties)
{
if (this.systemProperties != null)
{
throw new BuildException("Only one <systemProperties> tag is allowed!");
}
this.systemProperties = systemProperties;
}
/**
* @param handlers
*/
public void addContextHandlers (ContextHandlers handlers)
{
if (this.contextHandlers != null)
throw new BuildException("Only one <contextHandlers> tag is allowed!");
this.contextHandlers = handlers;
}
/**
* @return
*/
public File getTempDirectory()
{
return tempDirectory;
}
/**
* @param tempDirectory
*/
public void setTempDirectory(File tempDirectory)
{
this.tempDirectory = tempDirectory;
}
/**
* @return
*/
public File getJettyXml()
{
return jettyXml;
}
/**
* @param jettyXml
*/
public void setJettyXml(File jettyXml)
{
this.jettyXml = jettyXml;
}
/**
* @param className
*/
public void setRequestLog(String className)
{
try
@ -161,6 +191,9 @@ public class JettyRunTask extends Task
}
}
/**
* @return
*/
public String getRequestLog()
{
if (requestLog != null)
@ -191,42 +224,34 @@ public class JettyRunTask extends Task
{
TaskLog.log("Configuring Jetty for project: " + getProject().getName());
WebApplicationProxyImpl.setBaseTempDirectory(tempDirectory);
setSystemProperties();
List connectorsList = null;
List<Connector> connectorsList = null;
if (connectors != null)
{
connectorsList = connectors.getConnectors();
}
else
{
connectorsList = new Connectors(jettyPort,30000).getDefaultConnectors();
}
List loginServicesList = (loginServices != null?loginServices.getLoginServices():new ArrayList());
ServerProxy server = new ServerProxyImpl(connectorsList,loginServicesList,requestLog,jettyXml);
List<LoginService> loginServicesList = (loginServices != null?loginServices.getLoginServices():new ArrayList<LoginService>());
ServerProxyImpl server = new ServerProxyImpl();
server.setConnectors(connectorsList);
server.setLoginServices(loginServicesList);
server.setRequestLog(requestLog);
server.setJettyXml(jettyXml);
server.setDaemon(daemon);
server.setStopPort(stopPort);
server.setStopKey(stopKey);
server.setContextHandlers(contextHandlers);
server.setTempDirectory(tempDirectory);
server.setScanIntervalSecs(scanIntervalSeconds);
try
{
Iterator iterator = webapps.iterator();
while (iterator.hasNext())
for (WebAppContext webapp: webapps)
{
WebApp webAppConfiguration = (WebApp)iterator.next();
WebApplicationProxyImpl webApp = new WebApplicationProxyImpl(webAppConfiguration.getName());
webApp.setSourceDirectory(webAppConfiguration.getWarFile());
webApp.setContextPath(webAppConfiguration.getContextPath());
webApp.setWebXml(webAppConfiguration.getWebXmlFile());
webApp.setJettyEnvXml(webAppConfiguration.getJettyEnvXml());
webApp.setClassPathFiles(webAppConfiguration.getClassPathFiles());
webApp.setLibrariesConfiguration(webAppConfiguration.getLibrariesConfiguration());
webApp.setExtraScanTargetsConfiguration(webAppConfiguration.getScanTargetsConfiguration());
webApp.setContextHandlers(webAppConfiguration.getContextHandlers());
webApp.setAttributes(webAppConfiguration.getAttributes());
webApp.setWebDefaultXmlFile(webAppConfiguration.getWebDefaultXmlFile());
server.addWebApplication(webApp,webAppConfiguration.getScanIntervalSeconds());
server.addWebApplication((AntWebAppContext)webapp);
}
}
catch (Exception e)
@ -237,77 +262,64 @@ public class JettyRunTask extends Task
server.start();
}
/**
* Starts a new thread which scans project files and automatically reloads a
* container on any changes.
*
* @param scanIntervalSeconds
*
* @param webapp
* @param appContext
*/
static void startScanner(final WebApplicationProxyImpl webApp, int scanIntervalSeconds) throws Exception
public int getStopPort()
{
List scanList = new ArrayList();
scanList.add(webApp.getWebXmlFile());
scanList.addAll(webApp.getLibraries());
scanList.addAll(webApp.getExtraScanTargets());
Scanner.Listener changeListener = new Scanner.BulkListener()
{
public void filesChanged(List changedFiles)
{
if (hasAnyFileChanged(changedFiles))
{
try
{
webApp.stop();
webApp.applyConfiguration();
webApp.start();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
/**
* Checks if any file in this particular application has changed.
* This is not that easy, because some applications may use the same
* class'es directory.
*
* @param changedFiles list of changed files.
* @return true if any of passed files has changed, false otherwise.
*/
private boolean hasAnyFileChanged(List changedFiles)
{
Iterator changes = changedFiles.iterator();
while (changes.hasNext())
{
String className = (String) changes.next();
if (webApp.isFileScanned(className))
{
return true;
}
}
return false;
}
};
TaskLog.log("Web application '" + webApp.getName() + "': starting scanner at interval of "
+ scanIntervalSeconds + " seconds.");
Scanner scanner = new Scanner();
scanner.setScanInterval(scanIntervalSeconds);
scanner.addListener(changeListener);
scanner.setScanDirs(scanList);
scanner.setReportExistingFilesOnStartup(false);
scanner.start();
return stopPort;
}
public void setStopPort(int stopPort)
{
this.stopPort = stopPort;
TaskLog.log("stopPort="+stopPort);
}
public String getStopKey()
{
return stopKey;
}
public void setStopKey(String stopKey)
{
this.stopKey = stopKey;
TaskLog.log("stopKey="+stopKey);
}
/**
* @return the daemon
*/
public boolean isDaemon()
{
return daemon;
}
/**
* @param daemon the daemon to set
*/
public void setDaemon(boolean daemon)
{
this.daemon = daemon;
TaskLog.log("Daemon="+daemon);
}
/**
* @return
*/
public int getScanIntervalSeconds()
{
return scanIntervalSeconds;
}
/**
* @param secs
*/
public void setScanIntervalSeconds(int secs)
{
scanIntervalSeconds = secs;
TaskLog.log("scanIntervalSecs="+secs);
}
/**
* Sets the system properties.
*/
@ -323,4 +335,5 @@ public class JettyRunTask extends Task
}
}
}
}

View File

@ -0,0 +1,128 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.ant;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.Socket;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.eclipse.jetty.ant.utils.TaskLog;
/**
* JettyStopTask
*
*
*/
public class JettyStopTask extends Task
{
private int stopPort;
private String stopKey;
private int stopWait;
/**
*
*/
public JettyStopTask()
{
TaskLog.setTask(this);
}
/**
* @see org.apache.tools.ant.Task#execute()
*/
public void execute() throws BuildException
{
try
{
Socket s = new Socket(InetAddress.getByName("127.0.0.1"),stopPort);
if (stopWait > 0)
s.setSoTimeout(stopWait*1000);
try
{
OutputStream out = s.getOutputStream();
out.write((stopKey + "\r\nstop\r\n").getBytes());
out.flush();
if (stopWait > 0)
{
TaskLog.log("Waiting"+(stopWait > 0 ? (" "+stopWait+"sec") : "")+" for jetty to stop");
LineNumberReader lin = new LineNumberReader(new InputStreamReader(s.getInputStream()));
String response=lin.readLine();
if ("Stopped".equals(response))
System.err.println("Stopped");
}
}
finally
{
s.close();
}
}
catch (ConnectException e)
{
TaskLog.log("Jetty not running!");
}
catch (Exception e)
{
TaskLog.log(e.getMessage());
}
}
public int getStopPort()
{
return stopPort;
}
public void setStopPort(int stopPort)
{
this.stopPort = stopPort;
}
public String getStopKey()
{
return stopKey;
}
public void setStopKey(String stopKey)
{
this.stopKey = stopKey;
}
public int getStopWait()
{
return stopWait;
}
public void setStopWait(int stopWait)
{
this.stopWait = stopWait;
}
}

View File

@ -22,28 +22,33 @@ package org.eclipse.jetty.ant;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.tools.ant.BuildException;
import org.eclipse.jetty.ant.types.Connector;
import org.eclipse.jetty.ant.types.ContextHandlers;
import org.eclipse.jetty.ant.utils.Monitor;
import org.eclipse.jetty.ant.utils.ServerProxy;
import org.eclipse.jetty.ant.utils.TaskLog;
import org.eclipse.jetty.ant.utils.WebApplicationProxy;
import org.eclipse.jetty.security.LoginService;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.RequestLog;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.server.handler.RequestLogHandler;
import org.eclipse.jetty.util.Scanner;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.xml.XmlConfiguration;
import org.xml.sax.SAXException;
/**
* A proxy class for interaction with Jetty server object. Used to have some
* level of abstraction over standard Jetty classes.
@ -53,7 +58,10 @@ public class ServerProxyImpl implements ServerProxy
/** Proxied Jetty server object. */
private Server server;
/** Temporary files directory. */
private File tempDirectory;
/** Collection of context handlers (web application contexts). */
private ContextHandlerCollection contexts;
@ -61,83 +69,320 @@ public class ServerProxyImpl implements ServerProxy
private File jettyXml;
/** List of connectors. */
private List connectors;
private List<Connector> connectors;
/** Request logger. */
private RequestLog requestLog;
/** User realms. */
private List loginServices;
private List<LoginService> loginServices;
/** List of added web applications. */
private Map webApplications = new HashMap();
private List<AntWebAppContext> webApplications = new ArrayList<AntWebAppContext>();
/** other contexts to deploy */
private ContextHandlers contextHandlers;
/** scan interval for changed files */
private int scanIntervalSecs;
/** port to listen for stop command */
private int stopPort;
/** security key for stop command */
private String stopKey;
/** wait for all jetty threads to exit or continue */
private boolean daemon;
private Monitor monitor;
private boolean configured = false;
/**
* WebAppScannerListener
*
* Handle notifications that files we are interested in have changed
* during execution.
*
*/
public static class WebAppScannerListener implements Scanner.BulkListener
{
AntWebAppContext awc;
public WebAppScannerListener (AntWebAppContext awc)
{
this.awc = awc;
}
public void filesChanged(List<String> changedFileNames)
{
boolean isScanned = false;
try
{
Iterator<String> itor = changedFileNames.iterator();
while (!isScanned && itor.hasNext())
{
isScanned = awc.isScanned(Resource.newResource(itor.next()).getFile());
}
if (isScanned)
{
awc.stop();
awc.start();
}
}
catch (Exception e)
{
TaskLog.log(e.getMessage());
}
}
}
/**
* Default constructor. Creates a new Jetty server with a standard connector
* listening on a given port.
*
* @param connectors
* @param loginServicesList
* @param requestLog
* @param jettyXml
*/
public ServerProxyImpl(List connectors, List loginServicesList, RequestLog requestLog,
File jettyXml)
public ServerProxyImpl ()
{
server = new Server();
server.setStopAtShutdown(true);
this.connectors = connectors;
this.loginServices = loginServicesList;
this.requestLog = requestLog;
this.jettyXml = jettyXml;
configure();
}
public void addWebApplication(AntWebAppContext webApp)
{
webApplications.add(webApp);
}
public int getStopPort()
{
return stopPort;
}
public void setStopPort(int stopPort)
{
this.stopPort = stopPort;
}
public String getStopKey()
{
return stopKey;
}
public void setStopKey(String stopKey)
{
this.stopKey = stopKey;
}
public File getJettyXml()
{
return jettyXml;
}
public void setJettyXml(File jettyXml)
{
this.jettyXml = jettyXml;
}
public List<Connector> getConnectors()
{
return connectors;
}
public void setConnectors(List<Connector> connectors)
{
this.connectors = connectors;
}
public RequestLog getRequestLog()
{
return requestLog;
}
public void setRequestLog(RequestLog requestLog)
{
this.requestLog = requestLog;
}
public List<LoginService> getLoginServices()
{
return loginServices;
}
public void setLoginServices(List<LoginService> loginServices)
{
this.loginServices = loginServices;
}
public List<AntWebAppContext> getWebApplications()
{
return webApplications;
}
public void setWebApplications(List<AntWebAppContext> webApplications)
{
this.webApplications = webApplications;
}
public File getTempDirectory()
{
return tempDirectory;
}
public void setTempDirectory(File tempDirectory)
{
this.tempDirectory = tempDirectory;
}
/**
* @see org.eclipse.jetty.ant.utils.ServerProxy#addWebApplication(WebApplicationProxy,
* int)
* @see org.eclipse.jetty.ant.utils.ServerProxy#start()
*/
public void addWebApplication(WebApplicationProxy webApp, int scanIntervalSeconds)
public void start()
{
webApp.createApplicationContext(contexts);
if (scanIntervalSeconds > 0)
try
{
webApplications.put(webApp, new Integer(scanIntervalSeconds));
configure();
configureWebApps();
server.start();
System.setProperty("jetty.ant.server.port","" + ((ServerConnector)server.getConnectors()[0]).getLocalPort());
String host = ((ServerConnector)server.getConnectors()[0]).getHost();
if (host == null)
{
System.setProperty("jetty.ant.server.host", "localhost");
}
else
{
System.setProperty("jetty.ant.server.host", host);
}
startMonitor();
startScanners();
TaskLog.log("Jetty AntTask Started");
if (!daemon)
server.join();
}
catch (InterruptedException e)
{
new RuntimeException(e);
}
catch (Exception e)
{
new RuntimeException(e);
}
}
/**
* @see org.eclipse.jetty.ant.utils.ServerProxy#getProxiedObject()
*/
public Object getProxiedObject()
{
return server;
}
/**
* @return the daemon
*/
public boolean isDaemon()
{
return daemon;
}
/**
* @param daemon the daemon to set
*/
public void setDaemon(boolean daemon)
{
this.daemon = daemon;
}
/**
* @return the contextHandlers
*/
public ContextHandlers getContextHandlers()
{
return contextHandlers;
}
/**
* @param contextHandlers the contextHandlers to set
*/
public void setContextHandlers (ContextHandlers contextHandlers)
{
this.contextHandlers = contextHandlers;
}
public int getScanIntervalSecs()
{
return scanIntervalSecs;
}
public void setScanIntervalSecs(int scanIntervalSecs)
{
this.scanIntervalSecs = scanIntervalSecs;
}
/**
* Configures Jetty server before adding any web applications to it.
*/
private void configure()
{
if (configured)
return;
configured = true;
if (tempDirectory != null && !tempDirectory.exists())
tempDirectory.mkdirs();
// Applies external configuration via jetty.xml
applyJettyXml();
// Configures connectors for this server instance.
Iterator<Connector> connectorIterator = connectors.iterator();
while (connectorIterator.hasNext())
if (connectors != null)
{
Connector jettyConnector = (Connector) connectorIterator.next();
ServerConnector jc = new ServerConnector(server);
jc.setPort(jettyConnector.getPort());
jc.setIdleTimeout(jettyConnector.getMaxIdleTime());
server.addConnector(jc);
for (Connector c:connectors)
{
ServerConnector jc = new ServerConnector(server);
jc.setPort(c.getPort());
jc.setIdleTimeout(c.getMaxIdleTime());
server.addConnector(jc);
}
}
// Configures login services
Iterator servicesIterator = loginServices.iterator();
while (servicesIterator.hasNext())
if (loginServices != null)
{
LoginService service = (LoginService) servicesIterator.next();
server.addBean(service);
for (LoginService ls:loginServices)
{
server.addBean(ls);
}
}
// Does not cache resources, to prevent Windows from locking files
@ -146,14 +391,16 @@ public class ServerProxyImpl implements ServerProxy
// Set default server handlers
configureHandlers();
}
/**
*
*/
private void configureHandlers()
{
RequestLogHandler requestLogHandler = new RequestLogHandler();
if (requestLog != null)
{
requestLogHandler.setRequestLog(requestLog);
}
contexts = (ContextHandlerCollection) server
.getChildHandlerByClass(ContextHandlerCollection.class);
@ -174,8 +421,28 @@ public class ServerProxyImpl implements ServerProxy
handlers.addHandler(contexts);
}
}
//if there are any extra contexts to deploy
if (contextHandlers != null && contextHandlers.getContextHandlers() != null)
{
for (ContextHandler c:contextHandlers.getContextHandlers())
contexts.addHandler(c);
}
}
/**
* @throws Exception
*/
private void startMonitor() throws Exception
{
if (stopPort > 0 && stopKey != null && monitor == null)
{
monitor = new Monitor(stopPort, stopKey, new Server[] {server});
monitor.start();
}
}
/**
* Applies jetty.xml configuration to the Jetty server instance.
*/
@ -210,63 +477,43 @@ public class ServerProxyImpl implements ServerProxy
}
}
/**
* @see org.eclipse.jetty.ant.utils.ServerProxy#start()
*/
public void start()
{
try
{
server.start();
System.setProperty("jetty.ant.server.port","" + ((ServerConnector)server.getConnectors()[0]).getLocalPort());
String host = ((ServerConnector)server.getConnectors()[0]).getHost();
if (host == null)
{
System.setProperty("jetty.ant.server.host", "localhost");
}
else
{
System.setProperty("jetty.ant.server.host", host);
}
startScanners();
TaskLog.log("Jetty AntTask Started");
server.join();
}
catch (InterruptedException e)
{
new RuntimeException(e);
}
catch (Exception e)
{
new RuntimeException(e);
}
}
/**
* Starts web applications' scanners.
*/
private void startScanners() throws Exception
{
Iterator i = webApplications.keySet().iterator();
while (i.hasNext())
for (AntWebAppContext awc:webApplications)
{
WebApplicationProxyImpl webApp = (WebApplicationProxyImpl) i.next();
Integer scanIntervalSeconds = (Integer) webApplications.get(webApp);
JettyRunTask.startScanner(webApp, scanIntervalSeconds.intValue());
if (scanIntervalSecs <= 0)
return;
List<File> scanList = awc.getScanFiles();
TaskLog.log("Web application '" + awc + "': starting scanner at interval of "
+ scanIntervalSecs + " seconds.");
Scanner.Listener changeListener = new WebAppScannerListener(awc);
Scanner scanner = new Scanner();
scanner.setScanInterval(scanIntervalSecs);
scanner.addListener(changeListener);
scanner.setScanDirs(scanList);
scanner.setReportExistingFilesOnStartup(false);
scanner.start();
}
}
/**
*
*/
private void configureWebApps()
{
for (AntWebAppContext awc:webApplications)
{
awc.setAttribute(AntWebAppContext.BASETEMPDIR, tempDirectory);
if (contexts != null)
contexts.addHandler(awc);
}
}
/**
* @see org.eclipse.jetty.ant.utils.ServerProxy#getProxiedObject()
*/
public Object getProxiedObject()
{
return server;
}
}

View File

@ -1,538 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Sabre Holdings.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.ant;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Iterator;
import java.util.List;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import org.apache.tools.ant.AntClassLoader;
import org.eclipse.jetty.annotations.AnnotationConfiguration;
import org.eclipse.jetty.ant.types.Attribute;
import org.eclipse.jetty.ant.types.FileMatchingConfiguration;
import org.eclipse.jetty.ant.utils.TaskLog;
import org.eclipse.jetty.ant.utils.WebApplicationProxy;
import org.eclipse.jetty.plus.webapp.EnvConfiguration;
import org.eclipse.jetty.plus.webapp.PlusConfiguration;
import org.eclipse.jetty.security.SecurityHandler;
import org.eclipse.jetty.server.HandlerContainer;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.ErrorHandler;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.servlet.Holder;
import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.FragmentConfiguration;
import org.eclipse.jetty.webapp.JettyWebXmlConfiguration;
import org.eclipse.jetty.webapp.MetaInfConfiguration;
import org.eclipse.jetty.webapp.TagLibConfiguration;
import org.eclipse.jetty.webapp.WebAppClassLoader;
import org.eclipse.jetty.webapp.WebAppContext;
/**
* An abstraction layer over Jetty WebAppContext.
*
*/
public class WebApplicationProxyImpl implements WebApplicationProxy
{
/** Common root temp directory for all web applications. */
static File baseTempDirectory = new File(".");
/** Name of this web application. */
private String name;
/** Location of WAR file (either expanded or not). */
private File warFile;
/** Application context path. */
private String contextPath;
/** Location of web.xml file. */
private File webXmlFile;
/** Location of jetty-env.xml file. */
private File jettyEnvXml;
/** List of classpath files. */
private List classPathFiles;
/** Jetty Web Application Context. */
private WebAppContext webAppContext;
/** Extra scan targets. */
private FileMatchingConfiguration extraScanTargetsConfiguration;
/** Extra context handlers. */
private List contextHandlers;
private List attributes;
Configuration[] configurations;
private FileMatchingConfiguration librariesConfiguration;
public static void setBaseTempDirectory(File tempDirectory)
{
baseTempDirectory = tempDirectory;
}
public static class AntServletHolder extends ServletHolder
{
public AntServletHolder()
{
super();
}
public AntServletHolder(Class<? extends Servlet> servlet)
{
super(servlet);
}
public AntServletHolder(Servlet servlet)
{
super(servlet);
}
public AntServletHolder(String name, Class<? extends Servlet> servlet)
{
super(name, servlet);
}
public AntServletHolder(String name, Servlet servlet)
{
super(name, servlet);
}
@Override
protected void initJspServlet() throws Exception
{
//super.initJspServlet();
ContextHandler ch = ContextHandler.getContextHandler(getServletHandler().getServletContext());
/* Set the webapp's classpath for Jasper */
ch.setAttribute("org.apache.catalina.jsp_classpath", ch.getClassPath());
/* Set the system classpath for Jasper */
String sysClassPath = getSystemClassPath(ch.getClassLoader().getParent());
setInitParameter("com.sun.appserv.jsp.classpath", sysClassPath);
/* Set up other classpath attribute */
if ("?".equals(getInitParameter("classpath")))
{
String classpath = ch.getClassPath();
if (classpath != null)
setInitParameter("classpath", classpath);
}
}
protected String getSystemClassPath (ClassLoader loader) throws Exception
{
StringBuilder classpath=new StringBuilder();
while (loader != null)
{
if (loader instanceof URLClassLoader)
{
URL[] urls = ((URLClassLoader)loader).getURLs();
if (urls != null)
{
for (int i=0;i<urls.length;i++)
{
Resource resource = Resource.newResource(urls[i]);
File file=resource.getFile();
if (file!=null && file.exists())
{
if (classpath.length()>0)
classpath.append(File.pathSeparatorChar);
classpath.append(file.getAbsolutePath());
}
}
}
}
else if (loader instanceof AntClassLoader)
{
classpath.append(((AntClassLoader)loader).getClasspath());
}
loader = loader.getParent();
}
return classpath.toString();
}
}
public static class AntServletHandler extends ServletHandler
{
@Override
public ServletHolder newServletHolder(Holder.Source source)
{
return new AntServletHolder();
}
}
public static class AntWebAppContext extends WebAppContext
{
public AntWebAppContext()
{
super();
}
public AntWebAppContext(HandlerContainer parent, String webApp, String contextPath)
{
super(parent, webApp, contextPath);
}
public AntWebAppContext(SessionHandler sessionHandler, SecurityHandler securityHandler, ServletHandler servletHandler, ErrorHandler errorHandler)
{
super(sessionHandler, securityHandler, servletHandler, errorHandler);
}
public AntWebAppContext(String webApp, String contextPath)
{
super(webApp, contextPath);
}
@Override
protected ServletHandler newServletHandler()
{
return new AntServletHandler();
}
}
/**
* Default constructor. Takes application name as an argument
*
* @param name web application name.
*/
public WebApplicationProxyImpl(String name) throws Exception
{
this.name = name;
TaskLog.log("\nConfiguring Jetty for web application: " + name);
this.configurations = new Configuration[]
{ new AntWebInfConfiguration(),
new AntWebXmlConfiguration(),
new MetaInfConfiguration(),
new FragmentConfiguration(),
new EnvConfiguration(),
new PlusConfiguration(),
new AnnotationConfiguration(),
new JettyWebXmlConfiguration(),
new TagLibConfiguration() };
}
public List getClassPathFiles()
{
return classPathFiles;
}
public String getContextPath()
{
return contextPath;
}
public String getName()
{
return name;
}
public File getSourceDirectory()
{
return warFile;
}
public File getWebXmlFile()
{
return webXmlFile;
}
public void setSourceDirectory(File warFile)
{
this.warFile = warFile;
TaskLog.log("Webapp source directory = " + warFile);
}
public void setContextPath(String contextPath)
{
if (!contextPath.startsWith("/"))
{
contextPath = "/" + contextPath;
}
this.contextPath = contextPath;
TaskLog.log("Context path = " + contextPath);
}
public void setWebXml(File webXmlFile)
{
this.webXmlFile = webXmlFile;
}
public void setJettyEnvXml(File jettyEnvXml)
{
this.jettyEnvXml = jettyEnvXml;
if (this.jettyEnvXml != null)
{
TaskLog.log("jetty-env.xml file: = " + jettyEnvXml.getAbsolutePath());
}
}
public void setClassPathFiles(List classPathFiles)
{
this.classPathFiles = classPathFiles;
TaskLog.log("Classpath = " + classPathFiles);
}
/**
* Checks if a given file is scanned according to the internal
* configuration. This may be difficult due to use of 'includes' and
* 'excludes' statements.
*
* @param pathToFile a fully qualified path to file.
* @return true if file is being scanned, false otherwise.
*/
public boolean isFileScanned(String pathToFile)
{
return librariesConfiguration.isIncluded(pathToFile)
|| extraScanTargetsConfiguration.isIncluded(pathToFile);
}
public void setLibrariesConfiguration(FileMatchingConfiguration classesConfiguration)
{
TaskLog.log("Default scanned paths = " + classesConfiguration.getBaseDirectories());
this.librariesConfiguration = classesConfiguration;
}
public List getLibraries()
{
return librariesConfiguration.getBaseDirectories();
}
public void setExtraScanTargetsConfiguration(
FileMatchingConfiguration extraScanTargetsConfiguration)
{
this.extraScanTargetsConfiguration = extraScanTargetsConfiguration;
TaskLog.log("Extra scan targets = " + extraScanTargetsConfiguration.getBaseDirectories());
}
public void setAttributes(List attributes)
{
this.attributes = attributes;
}
public List getExtraScanTargets()
{
return extraScanTargetsConfiguration.getBaseDirectories();
}
public List getContextHandlers()
{
return contextHandlers;
}
public void setContextHandlers(List contextHandlers)
{
this.contextHandlers = contextHandlers;
}
/**
* @see WebApplicationProxy#getProxiedObject()
*/
public Object getProxiedObject()
{
return webAppContext;
}
/**
* @see WebApplicationProxy#start()
*/
public void start()
{
try
{
TaskLog.logWithTimestamp("Starting web application " + name + " ...\n");
webAppContext.start();
}
catch (Exception e)
{
TaskLog.log(e.toString());
}
}
/**
* @see WebApplicationProxy#stop()
*/
public void stop()
{
try
{
TaskLog.logWithTimestamp("Stopping web application " + name + " ...");
Thread.currentThread().sleep(500L);
webAppContext.stop();
}
catch (InterruptedException e)
{
TaskLog.log(e.toString());
}
catch (Exception e)
{
TaskLog.log(e.toString());
}
}
/**
* @see WebApplicationProxy#createApplicationContext(org.eclipse.jetty.server.handler.ContextHandlerCollection)
*/
public void createApplicationContext(ContextHandlerCollection contexts)
{
webAppContext = new AntWebAppContext(contexts, warFile.getAbsolutePath(), contextPath);
webAppContext.setDisplayName(name);
configurePaths();
if ( !attributes.isEmpty() )
{
for ( Iterator i = attributes.iterator(); i.hasNext(); )
{
Attribute attr = (Attribute) i.next();
webAppContext.setAttribute(attr.getName(),attr.getValue());
}
}
configureHandlers(contexts);
applyConfiguration();
}
private void configureHandlers(ContextHandlerCollection contexts)
{
// adding extra context handlers
Iterator handlersIterator = contextHandlers.iterator();
while (handlersIterator.hasNext())
{
ContextHandler contextHandler = (ContextHandler) handlersIterator.next();
contexts.addHandler(contextHandler);
}
}
private void configurePaths()
{
// configuring temp directory
File tempDir = new File(baseTempDirectory, contextPath);
if (!tempDir.exists())
{
tempDir.mkdirs();
}
webAppContext.setTempDirectory(tempDir);
tempDir.deleteOnExit();
TaskLog.log("Temp directory = " + tempDir.getAbsolutePath());
// configuring WAR directory for packaged web applications
if (warFile.isFile())
{
warFile = new File(tempDir, "webapp");
webXmlFile = new File(new File(warFile, "WEB-INF"), "web.xml");
}
}
/**
* Applies web application configuration at the end of configuration process
* or after application restart.
*/
void applyConfiguration()
{
for (int i = 0; i < configurations.length; i++)
{
if (configurations[i] instanceof EnvConfiguration)
{
try
{
if (jettyEnvXml != null && jettyEnvXml.exists())
{
((EnvConfiguration) configurations[i]).setJettyEnvXml(Resource.toURL(jettyEnvXml));
}
}
catch (MalformedURLException e)
{
throw new RuntimeException(e);
}
}
else if (configurations[i] instanceof AntWebXmlConfiguration)
{
((AntWebXmlConfiguration) configurations[i]).setClassPathFiles(classPathFiles);
((AntWebXmlConfiguration) configurations[i]).setWebAppBaseDir(warFile);
((AntWebXmlConfiguration) configurations[i]).setWebXmlFile(webXmlFile);
((AntWebXmlConfiguration) configurations[i]).setWebDefaultXmlFile(webDefaultXmlFile);
}
}
try
{
ClassLoader loader = new WebAppClassLoader(this.getClass().getClassLoader(),
webAppContext);
webAppContext.setParentLoaderPriority(true);
webAppContext.setClassLoader(loader);
if (webDefaultXmlFile != null)
webAppContext.setDefaultsDescriptor(webDefaultXmlFile.getCanonicalPath());
}
catch (IOException e)
{
TaskLog.log(e.toString());
}
webAppContext.setConfigurations(configurations);
}
private File webDefaultXmlFile;
public File getWebDefaultXmlFile()
{
return this.webDefaultXmlFile;
}
public void setWebDefaultXmlFile(File webDefaultXmlfile)
{
this.webDefaultXmlFile = webDefaultXmlfile;
}
}

View File

@ -24,14 +24,14 @@ import java.util.List;
public class Attributes
{
List _attributes = new ArrayList();
List<Attribute> _attributes = new ArrayList<Attribute>();
public void addAttribute(Attribute attr )
{
_attributes.add(attr);
}
public List getAttributes()
public List<Attribute> getAttributes()
{
return _attributes;
}

View File

@ -18,6 +18,11 @@
package org.eclipse.jetty.ant.types;
/**
* Connector
*
*
*/
public class Connector
{
private int port;

View File

@ -23,6 +23,9 @@ import java.util.ArrayList;
import java.util.List;
/**
*
* Connectors
*
* Specifies a jetty configuration <connectors/> element for Ant build file.
*
*/

View File

@ -31,14 +31,14 @@ import org.eclipse.jetty.server.handler.ContextHandler;
public class ContextHandlers
{
private List contextHandlers = new ArrayList();
private List<ContextHandler> contextHandlers = new ArrayList<ContextHandler>();
public void add(ContextHandler handler)
{
contextHandlers.add(handler);
}
public List getContextHandlers()
public List<ContextHandler> getContextHandlers()
{
return contextHandlers;
}

View File

@ -25,20 +25,22 @@ import java.util.List;
import org.eclipse.jetty.security.LoginService;
/**
* LoginServices
*
* Specifies a jetty configuration <loginServices/> element for Ant build file.
*
*/
public class LoginServices
{
private List loginServices = new ArrayList();
private List<LoginService> loginServices = new ArrayList<LoginService>();
public void add(LoginService service)
{
loginServices.add(service);
}
public List getLoginServices()
public List<LoginService> getLoginServices()
{
return loginServices;
}

View File

@ -26,6 +26,8 @@ import org.apache.tools.ant.taskdefs.Property;
import org.eclipse.jetty.ant.utils.TaskLog;
/**
* SystemProperties
*
* Ant <systemProperties/> tag definition.
*
*/

View File

@ -1,291 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Sabre Holdings.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.ant.types;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.FileSet;
/**
* Ant's WebApp object definition.
*
*/
public class WebApp
{
/** List of web application libraries. */
private List libraries = new ArrayList();
/** List of web application class directories. */
private List classes = new ArrayList();
/** Reference to Ant project variable. */
private Project project;
/** Application context path. */
private String contextPath;
/** Application name. */
private String name;
/** Application war file (either exploded or not). */
private File warFile;
/** Location of application web.xml file. */
private File webXmlFile;
/** Location of jetty-env.xml file. */
private File jettyEnvXml;
/** List of extra scan targets for this web application. */
private FileSet scanTargets;
/** List of the attributes to set to webapp context */
private Attributes attributes;
/** List of optional context handlers. */
private ContextHandlers contextHandlers;
private File webDefaultXmlFile;
/**
* Length of interval in which application will be scanned for changes (0
* means scanner wouldn't be created).
*/
private int scanIntervalSeconds = 0;
public WebApp(Project project)
{
this.project = project;
}
public File getWebDefaultXmlFile()
{
return this.webDefaultXmlFile;
}
public void setWebDefaultXmlFile(File webDefaultXmlfile)
{
this.webDefaultXmlFile = webDefaultXmlfile;
}
public void addLib(FileSet lib)
{
libraries.add(lib);
}
public List getLibraries()
{
return libraries;
}
public void addClasses(FileSet classes)
{
this.classes.add(classes);
}
public List getClasses()
{
return classes;
}
public File getWarFile()
{
return warFile;
}
public void setWarFile(File warFile)
{
this.warFile = warFile;
}
public String getContextPath()
{
return contextPath;
}
public void setContextPath(String contextPath)
{
this.contextPath = contextPath;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
/**
* @return a list of classpath files (libraries and class directories).
*/
public List getClassPathFiles()
{
List classPathFiles = new ArrayList();
Iterator classesIterator = classes.iterator();
while (classesIterator.hasNext())
{
FileSet clazz = (FileSet) classesIterator.next();
classPathFiles.add(clazz.getDirectoryScanner(project).getBasedir());
}
Iterator iterator = libraries.iterator();
while (iterator.hasNext())
{
FileSet library = (FileSet) iterator.next();
String[] includedFiles = library.getDirectoryScanner(project).getIncludedFiles();
File baseDir = library.getDirectoryScanner(project).getBasedir();
for (int i = 0; i < includedFiles.length; i++)
{
classPathFiles.add(new File(baseDir, includedFiles[i]));
}
}
return classPathFiles;
}
/**
* @return a <code>FileMatchingConfiguration</code> object describing the
* configuration of all libraries added to this particular web app
* (both classes and libraries).
*/
public FileMatchingConfiguration getLibrariesConfiguration()
{
FileMatchingConfiguration config = new FileMatchingConfiguration();
Iterator classesIterator = classes.iterator();
while (classesIterator.hasNext())
{
FileSet clazz = (FileSet) classesIterator.next();
config.addDirectoryScanner(clazz.getDirectoryScanner(project));
}
Iterator librariesIterator = libraries.iterator();
while (librariesIterator.hasNext())
{
FileSet library = (FileSet) librariesIterator.next();
config.addDirectoryScanner(library.getDirectoryScanner(project));
}
return config;
}
public FileMatchingConfiguration getScanTargetsConfiguration()
{
FileMatchingConfiguration configuration = new FileMatchingConfiguration();
if (scanTargets != null)
{
configuration.addDirectoryScanner(scanTargets.getDirectoryScanner(project));
}
return configuration;
}
/**
* @return location of web.xml file (either inside WAR or on the external
* location).
*/
public File getWebXmlFile()
{
if (webXmlFile == null)
{
File webInf = new File(warFile, "WEB-INF");
return new File(webInf, "web.xml");
}
return webXmlFile;
}
public void setWebXmlFile(File webXmlFile)
{
this.webXmlFile = webXmlFile;
}
public void addScanTargets(FileSet scanTargets)
{
if (this.scanTargets != null)
{
throw new BuildException("Only one <scanTargets> tag is allowed!");
}
this.scanTargets = scanTargets;
}
public void addContextHandlers(ContextHandlers contextHandlers)
{
if (this.contextHandlers != null)
{
throw new BuildException("Only one <contextHandlers> tag is allowed!");
}
this.contextHandlers = contextHandlers;
}
public void addAttributes(Attributes attributes)
{
if (this.attributes != null)
{
throw new BuildException("Only one <attributes> tag is allowed!");
}
this.attributes = attributes;
}
public int getScanIntervalSeconds()
{
return scanIntervalSeconds;
}
public void setScanIntervalSeconds(int scanIntervalSeconds)
{
this.scanIntervalSeconds = scanIntervalSeconds;
}
public File getJettyEnvXml()
{
return jettyEnvXml;
}
public void setJettyEnvXml(File jettyEnvXml)
{
this.jettyEnvXml = jettyEnvXml;
}
public List getContextHandlers()
{
return (contextHandlers != null ? contextHandlers.getContextHandlers() : new ArrayList());
}
public List getAttributes()
{
return (attributes != null ? attributes.getAttributes() : new ArrayList());
}
}

View File

@ -0,0 +1,143 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.ant.utils;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import org.eclipse.jetty.server.Server;
/**
* Monitor
*
*
*/
public class Monitor extends Thread
{
private String stopKey;
private Server[] servers;
private ServerSocket serverSocket;
public Monitor(int port, String key, Server[] servers)
throws Exception
{
if (port <= 0) throw new IllegalStateException("Bad stop port");
if (key == null) throw new IllegalStateException("Bad stop key");
if (servers == null) throw new IllegalStateException("No servers");
this.stopKey = key;
this.servers = servers;
setName("JettyStopTaskMonitor");
setDaemon(true);
InetSocketAddress address = new InetSocketAddress("127.0.0.1", port);
serverSocket = new ServerSocket();
serverSocket.setReuseAddress(true);
try
{
serverSocket.bind(address, 1);
TaskLog.log("Jetty monitoring port 127.0.0.1:" + port);
}
catch (IOException x)
{
TaskLog.log("Error binding to stop port 127.0.0.1:" + port);
throw x;
}
}
/**
* @see java.lang.Thread#run()
*/
public void run()
{
while (serverSocket != null)
{
Socket socket = null;
try
{
socket = serverSocket.accept();
socket.setSoLinger(false, 0);
LineNumberReader lin = new LineNumberReader(new InputStreamReader(socket.getInputStream()));
String key = lin.readLine();
System.err.println("Monitor: " + key);
if (!stopKey.equals(key)) continue;
String cmd = lin.readLine();
if ("stop".equals(cmd))
{
close(serverSocket);
serverSocket = null;
for (Server s : servers)
{
try
{
TaskLog.log("Stopping server: " + s);
s.stop();
TaskLog.log("Stopped server: " + s);
}
catch (Exception e)
{
TaskLog.log(e.getMessage());
}
}
// confirm the stop
socket.getOutputStream().write("Stopped\r\n".getBytes());
}
else
TaskLog.log("Unsupported monitor operation: " + cmd);
}
catch (Exception e)
{
TaskLog.log(e.getMessage());
}
finally
{
close(socket);
socket = null;
close(serverSocket);
}
}
}
/**
* @param c
*/
private void close(Closeable c)
{
if (c == null) return;
try
{
c.close();
}
catch (Exception e)
{
TaskLog.log(e.getMessage());
}
}
}

View File

@ -19,6 +19,8 @@
package org.eclipse.jetty.ant.utils;
import org.eclipse.jetty.ant.AntWebAppContext;
public interface ServerProxy
{
@ -28,13 +30,14 @@ public interface ServerProxy
* @param webApp a WebApplicationProxy object.
* @param scanIntervalSeconds
*/
public void addWebApplication(WebApplicationProxy webApp, int scanIntervalSeconds);
public void addWebApplication(AntWebAppContext awc);
/**
* Starts this server.
*/
public void start();
public Object getProxiedObject();
}

View File

@ -1,47 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2012 Sabre Holdings.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.ant.utils;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
public interface WebApplicationProxy
{
public Object getProxiedObject();
/**
* Starts this web application context.
*/
public void start();
/**
* Stops this web application context.
*/
public void stop();
/**
* Creates a new Jetty web application context from this object.
*
* @param contexts collection of context this application should be added
* to.
*/
public void createApplicationContext(ContextHandlerCollection contexts);
}

View File

@ -1 +1,2 @@
jetty=org.eclipse.jetty.ant.JettyRunTask
jetty.run=org.eclipse.jetty.ant.JettyRunTask
jetty.stop=org.eclipse.jetty.ant.JettyStopTask

View File

@ -26,7 +26,7 @@
classpathref="jetty.plugin.classpath" loaderref="jetty.loader" />
<target name="jetty.run">
<jetty tempDirectory="jetty-temp">
<jetty.run tempDirectory="jetty-temp">
<loginServices>
<hashLoginService name="Test Realm" config="realm.properties"/>
</loginServices>
@ -38,6 +38,6 @@
<attribute name="org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern" value=".*/.*jsp-api-[^/]*\.jar$|.*/.*jsp-[^/]*\.jar$|.*/.*taglibs[^/]*\.jar$"/>
</attributes>
</webApp>
</jetty>
</jetty.run>
</target>
</project>

View File

@ -24,13 +24,14 @@ import java.net.URI;
import junit.framework.Assert;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.junit.Ignore;
import org.junit.Test;
public class JettyAntTaskTest
{
@Test
@Ignore
//@Test
public void testConnectorTask() throws Exception
{
AntBuild build = new AntBuild(MavenTestingUtils.getTestResourceFile("connector-test.xml").getAbsolutePath());
@ -47,5 +48,26 @@ public class JettyAntTaskTest
build.stop();
}
@Test
public void testWebApp () throws Exception
{
AntBuild build = new AntBuild(MavenTestingUtils.getTestResourceFile("webapp-test.xml").getAbsolutePath());
build.start();
URI uri = new URI("http://" + build.getJettyHost() + ":" + build.getJettyPort() + "/");
HttpURLConnection connection = (HttpURLConnection)uri.toURL().openConnection();
connection.connect();
Assert.assertEquals(200,connection.getResponseCode());
System.err.println("Stop build!");
build.stop();
}
}

View File

@ -6,15 +6,14 @@
<taskdef classpathref="jetty.plugin.classpath" resource="tasks.properties" loaderref="jetty.loader" />
<typedef name="connector" classname="org.eclipse.jetty.ant.types.Connector"
classpathref="jetty.plugin.classpath" loaderref="jetty.loader" />
<target name="jetty.run">
<jetty>
<jetty.run>
<connectors>
<connector port="0"/>
</connectors>
</jetty>
</jetty.run>
</target>
</project>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>acme</short-name>
<uri>http://www.acme.com/taglib</uri>
<description>taglib example</description>
<listener>
<listener-class>com.acme.TagListener</listener-class>
</listener>
<tag>
<name>date</name>
<tag-class>com.acme.DateTag</tag-class>
<body-content>TAGDEPENDENT</body-content>
<description>Display Date</description>
<attribute>
<name>tz</name>
<required>false</required>
</attribute>
</tag>
</taglib>

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd"
version="2.0">
<description>Acme JSP2 tags</description>
<tlib-version>1.0</tlib-version>
<short-name>acme2</short-name>
<uri>http://www.acme.com/taglib2</uri>
<tag>
<description>Simple Date formatting</description>
<name>date2</name>
<tag-class>com.acme.Date2Tag</tag-class>
<body-content>scriptless</body-content>
<variable>
<description>Day of the Month</description>
<name-given>day</name-given>
</variable>
<variable>
<description>Month of the Year</description>
<name-given>month</name-given>
</variable>
<variable>
<description>Year</description>
<name-given>year</name-given>
</variable>
<attribute>
<name>format</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>

View File

@ -0,0 +1,17 @@
<%--
- Copyright (c) 2002 The Apache Software Foundation. All rights
- reserved.
--%>
<%@ attribute name="color" %>
<%@ attribute name="bgcolor" %>
<%@ attribute name="title" %>
<table border="1" bgcolor="${color}">
<tr>
<td><b>${title}</b></td>
</tr>
<tr>
<td bgcolor="${bgcolor}">
<jsp:doBody/>
</td>
</tr>
</table>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<display-name>Test WebApp</display-name>
<context-param>
<param-name>org.eclipse.jetty.server.context.ManagedAttributes</param-name>
<param-value>QoSFilter,TransparentProxy.ThreadPool,TransparentProxy.HttpClient</param-value>
</context-param>
<servlet>
<servlet-name>foo.jsp</servlet-name>
<jsp-file>/jsp/foo/foo.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>foo.jsp</servlet-name>
<url-pattern>/jsp/foo/</url-pattern>
</servlet-mapping>
</web-app>

View File

@ -0,0 +1,5 @@
<html>
<body>
<h1>INDEX!</h1>
</body>
</html>

View File

@ -0,0 +1,15 @@
<html>
<%@ page session="true"%>
<body>
<jsp:useBean id='counter' scope='session' class='com.acme.Counter' type="com.acme.Counter" />
<h1>JSP1.2 Beans: 1</h1>
Counter accessed <jsp:getProperty name="counter" property="count"/> times.<br/>
Counter last accessed by <jsp:getProperty name="counter" property="last"/><br/>
<jsp:setProperty name="counter" property="last" value="<%= request.getRequestURI()%>"/>
<a href="bean2.jsp">Goto bean2.jsp</a>
</body>
</html>

View File

@ -0,0 +1,15 @@
<html>
<%@ page session="true"%>
<body>
<jsp:useBean id='counter' scope='session' class='com.acme.Counter' type="com.acme.Counter" />
<h1>JSP1.2 Beans: 2</h1>
Counter accessed <jsp:getProperty name="counter" property="count"/> times.<br/>
Counter last accessed by <jsp:getProperty name="counter" property="last"/><br/>
<jsp:setProperty name="counter" property="last" value="<%= request.getRequestURI()%>"/>
<a href="bean1.jsp">Goto bean1.jsp</a>
</body>
</html>

View File

@ -0,0 +1,23 @@
<html><head>
<%@ page import="java.util.Enumeration" %>
</head><body>
<h1>JSP Dump</h1>
<table border="1">
<tr><th>Request URI:</th><td><%= request.getRequestURI() %></td></tr>
<tr><th>ServletPath:</th><td><%= request.getServletPath() %></td></tr>
<tr><th>PathInfo:</th><td><%= request.getPathInfo() %></td></tr>
<%
Enumeration e =request.getParameterNames();
while(e.hasMoreElements())
{
String name = (String)e.nextElement();
%>
<tr>
<th>getParameter("<%= name %>")</th>
<td><%= request.getParameter(name) %></td></tr>
<% } %>
</table>
</body></html>

View File

@ -0,0 +1,23 @@
<html>
<h1>JSP2.0 Expressions</h1>
<table border="1">
<tr><th>Expression</th><th>Result</th></tr>
<tr>
<td>\${param["A"]}</td>
<td>${param["A"]}&nbsp;</td>
</tr><tr>
<td>\${header["host"]}</td>
<td>${header["host"]}</td>
</tr><tr>
<td>\${header["user-agent"]}</td>
<td>${header["user-agent"]}</td>
</tr><tr>
<td>\${1+1}</td>
<td>${1+1}</td>
</tr><tr>
<td>\${param["A"] * 2}</td>
<td>${param["A"] * 2}&nbsp;</td>
</tr>
</table>
</html>

View File

@ -0,0 +1,15 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
</head>
<body>
<h1>FOO Example</h1>
<hr>
<p>A trivial FOO example
<hr>
<c:forEach var="i" begin="1" end="10" step="1">
<c:out value="${i}" />
<br />
</c:forEach>
</body>
</html>

View File

@ -0,0 +1,20 @@
<html>
<body>
<h1>JSP Examples</h1>
<ul>
<li><a href="dump.jsp">JSP 1.2 embedded java</a><br/>
<li><a href="bean1.jsp">JSP 1.2 Bean demo</a><br/>
<li><a href="tag.jsp">JSP 1.2 BodyTag demo</a><br/>
<li><a href="tag2.jsp">JSP 2.0 SimpleTag demo</a><br/>
<li><a href="tagfile.jsp">JSP 2.0 Tag File demo</a><br/>
<li><a href="expr.jsp?A=1">JSP 2.0 Tag Expression</a><br/>
<li><a href="jstl.jsp">JSTL Expression</a><br/>
<li><a href="foo/">Mapping to &lt;jsp-file&gt;</a><br/>
</ul>
<a href="/">Main Menu</a>
</body>
</html>

View File

@ -0,0 +1,15 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
</head>
<body>
<h1>JSTL Example</h1>
<hr>
<p>A trivial jstl example
<hr>
<c:forEach var="i" begin="1" end="10" step="1">
<c:out value="${i}" />
<br />
</c:forEach>
</body>
</html>

View File

@ -0,0 +1,16 @@
<html>
<body>
<%@ taglib uri="http://www.acme.com/taglib" prefix="acme" %>
<small>&lt;acme:date tz="GMT"&gt;EEE, dd/MMM/yyyy HH:mm:ss ZZZ&lt;/acme:date&gt;
==&gt;</small>
<acme:date tz="GMT">EEE, dd/MMM/yyyy HH:mm:ss ZZZ</acme:date>
<br/>
<small>&lt;acme:date tz="EST"&gt;EEE, dd-MMM-yyyy HH:mm:ss ZZZ&lt;/acme:date&gt;
==&gt;</small>
<acme:date tz="EST">EEE, dd-MMM-yyyy HH:mm:ss ZZZ</acme:date>
<br/>
</body>
</html>

View File

@ -0,0 +1,19 @@
<html>
<body>
<%@ taglib uri="http://www.acme.com/taglib2" prefix="acme" %>
<acme:date2 format="long">
On ${day} of ${month} in the year ${year}
</acme:date2>
<br/>
<acme:date2 format="short">
${day} - ${month} - ${year}
</acme:date2>
<br/>
</body>
</html>

View File

@ -0,0 +1,37 @@
<%@ taglib prefix="acme" tagdir="/WEB-INF/tags" %>
<html>
<head>
</head>
<body>
<h1>JSP 2.0 Tag File Example</h1>
<hr>
<p>Panel tag created from JSP fragment file in WEB-INF/tags
<hr>
<table border="0">
<tr valign="top">
<td>
<acme:panel color="#ff8080" bgcolor="#ffc0c0" title="Panel 1">
First panel.<br/>
</acme:panel>
</td>
<td>
<acme:panel color="#80ff80" bgcolor="#c0ffc0" title="Panel 2">
Second panel.<br/>
Second panel.<br/>
Second panel.<br/>
Second panel.<br/>
</acme:panel>
</td>
<td>
<acme:panel color="#8080ff" bgcolor="#c0c0ff" title="Panel 3">
Third panel.<br/>
<acme:panel color="#ff80ff" bgcolor="#ffc0ff" title="Inner">
A panel in a panel.
</acme:panel>
Third panel.<br/>
</acme:panel>
</td>
</tr>
</table>
</body>
</html>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<project name="Jetty-Ant integration test" basedir="." >
<path id="jetty.plugin.classpath">
<fileset dir="target/test-lib" includes="*.jar"/>
</path>
<taskdef classpathref="jetty.plugin.classpath" resource="tasks.properties" loaderref="jetty.loader" />
<typedef name="webapp" classname="org.eclipse.jetty.ant.AntWebAppContext"
classpathref="jetty.plugin.classpath" loaderref="jetty.loader" />
<target name="jetty.run">
<jetty.run daemon="true" scanIntervalSeconds="10">
<webapp war="${basedir}/src/test/resources/foo" contextpath="/" />
</jetty.run>
</target>
</project>

View File

@ -117,7 +117,8 @@ public class TagLibConfiguration extends AbstractConfiguration
loader = getClass().getClassLoader();
else
loader = loader.getParent();
Class<?> clazz = loader.loadClass("org.apache.jasper.compiler.TldLocationsCache");
//Choose a class that should be present if tlds are in use
Class<?> clazz = loader.loadClass("org.apache.jasper.compiler.TagFileProcessor");
assert clazz!=null;
Collection<Resource> tld_resources = (Collection<Resource>)_context.getAttribute(TLD_RESOURCES);