311550 The WebAppProvider should allow setTempDirectory
git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@2000 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
parent
02b3db3727
commit
c9db2c9620
|
@ -1,4 +1,5 @@
|
|||
jetty-7.1.5-SNAPSHOT
|
||||
+ 311550 The WebAppProvider should allow setTempDirectory
|
||||
+ 316449 Websocket disconnect fix
|
||||
|
||||
jetty-7.1.4.v20100610
|
||||
|
@ -27,7 +28,7 @@ jetty-7.1.4.v20100610
|
|||
+ 316334 Breaking change on org.eclipse.jetty.client.HttpExchange
|
||||
+ 316399 Debug output in MultiPartFilter
|
||||
+ 316413 Restarting webapp for packed war fails
|
||||
+ 316557 OSGi HttpService is not available because context handlers files are not deployed
|
||||
+ 316557 OSGi HttpService failure due to undeployed context handlers
|
||||
+ JETTY-547 Delay close after shutdown until request read
|
||||
+ JETTY-1231 Support context request log handler
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import org.eclipse.jetty.server.handler.ContextHandler;
|
|||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.webapp.WebInfConfiguration;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -27,6 +28,7 @@ public class WebAppProvider extends ScanningAppProvider
|
|||
private boolean _parentLoaderPriority = false;
|
||||
private String _defaultsDescriptor;
|
||||
private Filter _filter;
|
||||
private File _tempDirectory;
|
||||
private String[] _configurationClasses;
|
||||
|
||||
private static class Filter implements FilenameFilter
|
||||
|
@ -36,13 +38,17 @@ public class WebAppProvider extends ScanningAppProvider
|
|||
public boolean accept(File dir, String name)
|
||||
{
|
||||
if (!dir.exists())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
String lowername = name.toLowerCase();
|
||||
|
||||
File file = new File(dir,name);
|
||||
// is it not a directory and not a war ?
|
||||
if (!file.isDirectory() && !lowername.endsWith(".war"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// is it a directory for an existing war file?
|
||||
if (file.isDirectory() &&
|
||||
|
@ -57,7 +63,9 @@ public class WebAppProvider extends ScanningAppProvider
|
|||
{
|
||||
String context=name;
|
||||
if (!file.isDirectory())
|
||||
{
|
||||
context=context.substring(0,context.length()-4);
|
||||
}
|
||||
if (new File(_contexts,context+".xml").exists() ||
|
||||
new File(_contexts,context+".XML").exists() )
|
||||
{
|
||||
|
@ -112,7 +120,7 @@ public class WebAppProvider extends ScanningAppProvider
|
|||
{
|
||||
_parentLoaderPriority = parentLoaderPriority;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Get the defaultsDescriptor.
|
||||
* @return the defaultsDescriptor
|
||||
|
@ -156,7 +164,7 @@ public class WebAppProvider extends ScanningAppProvider
|
|||
}
|
||||
catch (MalformedURLException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
|
@ -183,6 +191,27 @@ public class WebAppProvider extends ScanningAppProvider
|
|||
return _configurationClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Work directory where unpacked WAR files are managed from.
|
||||
* <p>
|
||||
* Default is the same as the <code>java.io.tmpdir</code> System Property.
|
||||
*
|
||||
* @param directory the new work directory
|
||||
*/
|
||||
public void setTempDir(File directory)
|
||||
{
|
||||
_tempDirectory = directory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user supplied Work Directory.
|
||||
*
|
||||
* @return the user supplied work directory (null if user has not set Temp Directory yet)
|
||||
*/
|
||||
public File getTempDir()
|
||||
{
|
||||
return _tempDirectory;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public ContextHandler createContextHandler(final App app) throws Exception
|
||||
|
@ -203,31 +232,54 @@ public class WebAppProvider extends ScanningAppProvider
|
|||
// Context Path is the same as the archive.
|
||||
context = context.substring(0,context.length() - 4);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
throw new IllegalStateException("unable to create ContextHandler for "+app);
|
||||
}
|
||||
|
||||
// special case of archive (or dir) named "root" is / context
|
||||
if (context.equalsIgnoreCase("root") || context.equalsIgnoreCase("root/"))
|
||||
if (context.equalsIgnoreCase("root") || context.equalsIgnoreCase("root/"))
|
||||
{
|
||||
context = URIUtil.SLASH;
|
||||
}
|
||||
|
||||
// Ensure "/" is Prepended to all context paths.
|
||||
if (context.charAt(0) != '/')
|
||||
if (context.charAt(0) != '/')
|
||||
{
|
||||
context = "/" + context;
|
||||
}
|
||||
|
||||
// Ensure "/" is Not Trailing in context paths.
|
||||
if (context.endsWith("/") && context.length() > 0)
|
||||
if (context.endsWith("/") && context.length() > 0)
|
||||
{
|
||||
context = context.substring(0,context.length() - 1);
|
||||
}
|
||||
|
||||
WebAppContext wah = new WebAppContext();
|
||||
wah.setContextPath(context);
|
||||
wah.setWar(file.getAbsolutePath());
|
||||
if (_defaultsDescriptor != null)
|
||||
if (_defaultsDescriptor != null)
|
||||
{
|
||||
wah.setDefaultsDescriptor(_defaultsDescriptor);
|
||||
}
|
||||
wah.setExtractWAR(_extractWars);
|
||||
wah.setParentLoaderPriority(_parentLoaderPriority);
|
||||
if (_configurationClasses != null)
|
||||
if (_configurationClasses != null)
|
||||
{
|
||||
wah.setConfigurationClasses(_configurationClasses);
|
||||
}
|
||||
|
||||
if (_tempDirectory != null)
|
||||
{
|
||||
/* Since the Temp Dir is really a context base temp directory,
|
||||
* Lets set the Temp Directory in a way similar to how WebInfConfiguration does it,
|
||||
* instead of setting the
|
||||
* WebAppContext.setTempDirectory(File).
|
||||
* If we used .setTempDirectory(File) all webapps will wind up in the
|
||||
* same temp / work directory, overwriting each others work.
|
||||
*/
|
||||
wah.setAttribute(WebAppContext.BASETEMPDIR,_tempDirectory);
|
||||
}
|
||||
return wah;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
package org.eclipse.jetty.deploy.providers;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.eclipse.jetty.deploy.test.XmlConfiguredJetty;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class WebAppProviderTest
|
||||
{
|
||||
private static XmlConfiguredJetty jetty;
|
||||
|
||||
@BeforeClass
|
||||
public static void setupEnvironment() throws Exception
|
||||
{
|
||||
jetty = new XmlConfiguredJetty();
|
||||
jetty.addConfiguration("jetty.xml");
|
||||
jetty.addConfiguration("jetty-deploy-wars.xml");
|
||||
|
||||
// Setup initial context
|
||||
jetty.copyContext("foo.xml","foo.xml");
|
||||
jetty.copyWebapp("foo-webapp-1.war","foo.war");
|
||||
|
||||
// Should not throw an Exception
|
||||
jetty.load();
|
||||
|
||||
// Start it
|
||||
jetty.start();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void teardownEnvironment() throws Exception
|
||||
{
|
||||
// Stop jetty.
|
||||
jetty.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartupContext()
|
||||
{
|
||||
// Check Server for Handlers
|
||||
jetty.printHandlers(System.out);
|
||||
jetty.assertWebAppContextsExists("/foo");
|
||||
|
||||
File workDir = jetty.getJettyDir("workish");
|
||||
|
||||
// Test for regressions
|
||||
assertDirNotExists("root of work directory",workDir,"webinf");
|
||||
assertDirNotExists("root of work directory",workDir,"jsp");
|
||||
|
||||
// Test for correct behavior
|
||||
Assert.assertTrue("Should have generated directory in work directory: " + workDir,hasJettyGeneratedPath(workDir,"foo.war"));
|
||||
}
|
||||
|
||||
private static boolean hasJettyGeneratedPath(File basedir, String expectedWarFilename)
|
||||
{
|
||||
for (File path : basedir.listFiles())
|
||||
{
|
||||
if (path.exists() && path.isDirectory() && path.getName().startsWith("Jetty_") && path.getName().contains(expectedWarFilename))
|
||||
{
|
||||
System.out.println("Found expected generated directory: " + path);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void assertDirNotExists(String msg, File workDir, String subdir)
|
||||
{
|
||||
File dir = new File(workDir,subdir);
|
||||
Assert.assertFalse("Should not have " + subdir + " in " + msg + " - " + workDir,dir.exists());
|
||||
}
|
||||
}
|
|
@ -59,7 +59,7 @@ public class XmlConfiguredJetty
|
|||
{
|
||||
this(MavenTestingUtils.getTestID());
|
||||
}
|
||||
|
||||
|
||||
public XmlConfiguredJetty(String testname) throws IOException
|
||||
{
|
||||
xmlConfigurations = new ArrayList<URL>();
|
||||
|
@ -69,9 +69,10 @@ public class XmlConfiguredJetty
|
|||
// Ensure we have a new (pristene) directory to work with.
|
||||
int idx = 0;
|
||||
jettyHome = new File(jettyHomeBase + "#" + idx);
|
||||
while(jettyHome.exists()) {
|
||||
idx++;
|
||||
jettyHome = new File(jettyHomeBase + "#" + idx);
|
||||
while (jettyHome.exists())
|
||||
{
|
||||
idx++;
|
||||
jettyHome = new File(jettyHomeBase + "#" + idx);
|
||||
}
|
||||
deleteContents(jettyHome);
|
||||
// Prepare Jetty.Home (Test) dir
|
||||
|
@ -91,23 +92,37 @@ public class XmlConfiguredJetty
|
|||
deleteContents(contextsDir);
|
||||
}
|
||||
contextsDir.mkdirs();
|
||||
|
||||
File webappsDir = new File(jettyHome,"webapps");
|
||||
if (webappsDir.exists())
|
||||
{
|
||||
deleteContents(webappsDir);
|
||||
}
|
||||
webappsDir.mkdirs();
|
||||
|
||||
File tmpDir = new File(jettyHome,"tmp");
|
||||
if (tmpDir.exists())
|
||||
{
|
||||
deleteContents(tmpDir);
|
||||
}
|
||||
tmpDir.mkdirs();
|
||||
|
||||
File workishDir = new File(jettyHome,"workish");
|
||||
if (workishDir.exists())
|
||||
{
|
||||
deleteContents(workishDir);
|
||||
}
|
||||
workishDir.mkdirs();
|
||||
|
||||
// Setup properties
|
||||
System.setProperty("java.io.tmpdir",tmpDir.getAbsolutePath());
|
||||
properties.setProperty("jetty.home",jettyHome.getAbsolutePath());
|
||||
System.setProperty("jetty.home",jettyHome.getAbsolutePath());
|
||||
properties.setProperty("test.basedir",MavenTestingUtils.getBasedir().getAbsolutePath());
|
||||
properties.setProperty("test.resourcesdir",MavenTestingUtils.getTestResourcesDir().getAbsolutePath());
|
||||
properties.setProperty("test.webapps",webappsDir.getAbsolutePath());
|
||||
properties.setProperty("test.webapps",workishDir.getAbsolutePath());
|
||||
properties.setProperty("test.targetdir",MavenTestingUtils.getTargetDir().getAbsolutePath());
|
||||
properties.setProperty("test.workdir",workishDir.getAbsolutePath());
|
||||
|
||||
// Write out configuration for use by ConfigurationManager.
|
||||
File testConfig = MavenTestingUtils.getTargetFile("xml-configured-jetty.properties");
|
||||
|
@ -238,11 +253,11 @@ public class XmlConfiguredJetty
|
|||
private void deleteContents(File dir)
|
||||
{
|
||||
System.out.printf("Delete (dir) %s/%n",dir);
|
||||
if(!dir.exists())
|
||||
if (!dir.exists())
|
||||
{
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for (File file : dir.listFiles())
|
||||
{
|
||||
// Safety measure. only recursively delete within target directory.
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
|
||||
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
|
||||
<Call name="addLifeCycle">
|
||||
<Arg>
|
||||
<New id="DeploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager">
|
||||
<Set name="contexts">
|
||||
<Ref id="Contexts" />
|
||||
</Set>
|
||||
|
||||
<!-- Providers of Apps -->
|
||||
<Set name="appProviders">
|
||||
<Array type="org.eclipse.jetty.deploy.AppProvider">
|
||||
<Item>
|
||||
<New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
|
||||
<Set name="monitoredDir"><SystemProperty name="jetty.home" />/webapps</Set>
|
||||
<Set name="scanInterval">1</Set>
|
||||
<Set name="tempDir"><Property name="jetty.home" default="target" />/workish</Set>
|
||||
</New>
|
||||
</Item>
|
||||
</Array>
|
||||
</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
</Configure>
|
|
@ -20,9 +20,7 @@ import java.net.URL;
|
|||
import java.security.PermissionCollection;
|
||||
import java.util.EventListener;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
import javax.servlet.http.HttpSessionActivationListener;
|
||||
import javax.servlet.http.HttpSessionAttributeListener;
|
||||
|
@ -65,6 +63,7 @@ import org.eclipse.jetty.util.resource.ResourceCollection;
|
|||
public class WebAppContext extends ServletContextHandler
|
||||
{
|
||||
public static final String TEMPDIR = "javax.servlet.context.tempdir";
|
||||
public static final String BASETEMPDIR = "org.eclipse.jetty.webapp.basetempdir";
|
||||
public final static String WEB_DEFAULTS_XML="org/eclipse/jetty/webapp/webdefault.xml";
|
||||
public final static String ERROR_PAGE="org.eclipse.jetty.server.error_page";
|
||||
public final static String SERVER_CONFIG = "org.eclipse.jetty.webapp.configuration";
|
||||
|
|
|
@ -221,61 +221,47 @@ public class WebInfConfiguration implements Configuration
|
|||
{
|
||||
//If a tmp directory is already set, we're done
|
||||
File tmpDir = context.getTempDirectory();
|
||||
if (tmpDir!=null && tmpDir.isDirectory() && tmpDir.canWrite())
|
||||
return; //Already have a suitable tmp dir configured
|
||||
if (tmpDir != null && tmpDir.isDirectory() && tmpDir.canWrite())
|
||||
{
|
||||
return; // Already have a suitable tmp dir configured
|
||||
}
|
||||
|
||||
|
||||
//None configured, try and come up with one
|
||||
//First ... see if one is configured in a context attribute
|
||||
//either as a File or name of a file
|
||||
Object t = context.getAttribute(WebAppContext.TEMPDIR);
|
||||
if (t != null)
|
||||
// No temp directory configured, try to establish one.
|
||||
// First we check the context specific, javax.servlet specified, temp directory attribute
|
||||
File servletTmpDir = asFile(context.getAttribute(WebAppContext.TEMPDIR));
|
||||
if (servletTmpDir != null && servletTmpDir.isDirectory() && servletTmpDir.canWrite())
|
||||
{
|
||||
//Is it a File?
|
||||
if (t instanceof File)
|
||||
{
|
||||
tmpDir=(File)t;
|
||||
if (tmpDir.isDirectory() && tmpDir.canWrite())
|
||||
{
|
||||
context.setTempDirectory(tmpDir);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// The context attribute specified a name not a File
|
||||
if (t instanceof String)
|
||||
{
|
||||
try
|
||||
{
|
||||
tmpDir=new File((String)t);
|
||||
|
||||
if (tmpDir.isDirectory() && tmpDir.canWrite())
|
||||
{
|
||||
context.setAttribute(context.TEMPDIR,tmpDir);
|
||||
context.setTempDirectory(tmpDir);
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Log.warn(Log.EXCEPTION,e);
|
||||
}
|
||||
}
|
||||
// Use as tmpDir
|
||||
tmpDir = servletTmpDir;
|
||||
// Ensure Attribute has File object
|
||||
context.setAttribute(WebAppContext.TEMPDIR,tmpDir);
|
||||
// Set as TempDir in context.
|
||||
context.setTempDirectory(tmpDir);
|
||||
return;
|
||||
}
|
||||
|
||||
// Second ... make a tmp directory, in a work directory if one exists
|
||||
String temp = getCanonicalNameForWebAppTmpDir(context);
|
||||
|
||||
try
|
||||
{
|
||||
//Put the tmp dir in the work directory if we had one
|
||||
// Put the tmp dir in the work directory if we had one
|
||||
File work = new File(System.getProperty("jetty.home"),"work");
|
||||
if (!work.exists() || !work.canWrite() || !work.isDirectory())
|
||||
work = null;
|
||||
|
||||
if (work!=null)
|
||||
if (work.exists() && work.canWrite() && work.isDirectory())
|
||||
{
|
||||
makeTempDirectory(work, context, false); //make a tmp dir inside work, don't delete if it exists
|
||||
}
|
||||
else
|
||||
makeTempDirectory(new File(System.getProperty("java.io.tmpdir")), context, true); //make a tmpdir, delete if it already exists
|
||||
{
|
||||
File baseTemp = asFile(context.getAttribute(WebAppContext.BASETEMPDIR));
|
||||
if (baseTemp != null && baseTemp.isDirectory() && baseTemp.canWrite())
|
||||
{
|
||||
// Use baseTemp directory (allow the funky Jetty_0_0_0_0.. subdirectory logic to kick in
|
||||
makeTempDirectory(baseTemp,context,false);
|
||||
}
|
||||
else
|
||||
{
|
||||
makeTempDirectory(new File(System.getProperty("java.io.tmpdir")),context,true); //make a tmpdir, delete if it already exists
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
|
@ -304,7 +290,31 @@ public class WebInfConfiguration implements Configuration
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Given an Object, return File reference for object.
|
||||
* Typically used to convert anonymous Object from getAttribute() calls to a File object.
|
||||
* @param fileattr the file attribute to analyze and return from (supports type File and type String, all others return null)
|
||||
* @return the File object, null if null, or null if not a File or String
|
||||
*/
|
||||
private File asFile(Object fileattr)
|
||||
{
|
||||
if (fileattr == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (fileattr instanceof File)
|
||||
{
|
||||
return (File)fileattr;
|
||||
}
|
||||
if (fileattr instanceof String)
|
||||
{
|
||||
return new File((String)fileattr);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void makeTempDirectory (File parent, WebAppContext context, boolean deleteExisting)
|
||||
throws IOException
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue