Jetty 12.0.x deployment (#8208)
Deploy webapps for different environments from the same webapps directory. The maximal environment known to the AppProviders is used as the default environment. An explicit environment can be set in a properties file for an application, which is also used for property substitution in any context xml file.
This commit is contained in:
parent
5304233b15
commit
ea5bedf072
|
@ -90,6 +90,11 @@
|
|||
<artifactId>jetty-deploy</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-ee</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.fcgi</groupId>
|
||||
<artifactId>fcgi-client</artifactId>
|
||||
|
|
|
@ -56,5 +56,9 @@
|
|||
<artifactId>jetty-test-helper</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-ee</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
@ -15,11 +15,6 @@
|
|||
<Set name="contexts">
|
||||
<Ref refid="Contexts" />
|
||||
</Set>
|
||||
<!-- TODO move this to an environment -->
|
||||
<Call name="setContextAttribute">
|
||||
<Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg>
|
||||
<Arg>.*/jetty-jakarta-servlet-api-[^/]*\.jar$|.*/.*jakarta.servlet.jsp.jstl-.*\.jar$</Arg>
|
||||
</Call>
|
||||
|
||||
<!-- Add a customize step to the deployment lifecycle -->
|
||||
<!-- uncomment and replace DebugBinding with your extended AppLifeCycle.Binding class
|
||||
|
|
|
@ -10,18 +10,3 @@ lib/jetty-deploy-${jetty.version}.jar
|
|||
[xml]
|
||||
etc/jetty-deploy.xml
|
||||
|
||||
[ini-template]
|
||||
# Monitored directory name (relative to $jetty.base)
|
||||
# jetty.deploy.monitoredDir=webapps
|
||||
# - OR -
|
||||
# Monitored directory path (fully qualified)
|
||||
# jetty.deploy.monitoredPath=/var/www/webapps
|
||||
|
||||
# Defaults Descriptor for all deployed webapps
|
||||
# jetty.deploy.defaultsDescriptorPath=${jetty.base}/etc/webdefault.xml
|
||||
|
||||
# Monitored directory scan period (seconds)
|
||||
# jetty.deploy.scanInterval=1
|
||||
|
||||
# Whether to extract *.war files
|
||||
# jetty.deploy.extractWars=true
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
module org.eclipse.jetty.deploy
|
||||
{
|
||||
requires java.xml;
|
||||
requires org.eclipse.jetty.ee;
|
||||
requires org.eclipse.jetty.xml;
|
||||
requires org.eclipse.jetty.server;
|
||||
requires org.slf4j;
|
||||
|
|
|
@ -13,36 +13,59 @@
|
|||
|
||||
package org.eclipse.jetty.deploy;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.eclipse.jetty.deploy.util.FileID;
|
||||
import org.eclipse.jetty.ee.Deployable;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.util.Attributes;
|
||||
|
||||
/**
|
||||
* The information about an App that is managed by the {@link DeploymentManager}
|
||||
* The information about an App that is managed by the {@link DeploymentManager}.
|
||||
*/
|
||||
public class App
|
||||
{
|
||||
private final DeploymentManager _manager;
|
||||
private final AppProvider _provider;
|
||||
private final String _environment;
|
||||
private final String _filename;
|
||||
private final Map<String, String> _properties = new HashMap<>();
|
||||
private ContextHandler _context;
|
||||
|
||||
/**
|
||||
* Create an App with specified Origin ID and archivePath
|
||||
*
|
||||
* <p>
|
||||
* Any properties file that exists with the same {@link FileID#getDot3Basename(String)} as the
|
||||
* filename passed will be used to initialize the properties returned by {@link #getProperties()}.
|
||||
* @param manager the deployment manager
|
||||
* @param provider the app provider
|
||||
* @param environment the name of the environment or null for the server environment.
|
||||
* @param filename the filename of the base resource of the application
|
||||
* @see App#getFilename()
|
||||
* @see App#getContextPath()
|
||||
*/
|
||||
public App(DeploymentManager manager, AppProvider provider, String environment, String filename)
|
||||
public App(DeploymentManager manager, AppProvider provider, String filename)
|
||||
{
|
||||
_manager = manager;
|
||||
_provider = provider;
|
||||
_environment = environment;
|
||||
_filename = filename;
|
||||
|
||||
try
|
||||
{
|
||||
String basename = FileID.getDot3Basename(filename);
|
||||
File properties = new File(basename + ".properties");
|
||||
if (properties.exists())
|
||||
{
|
||||
Properties p = new Properties();
|
||||
p.load(new FileInputStream(properties));
|
||||
p.keySet().stream().map(Object::toString).forEach(k -> _properties.put(k, p.getProperty(k)));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -61,6 +84,11 @@ public class App
|
|||
return _provider;
|
||||
}
|
||||
|
||||
public Map<String, String> getProperties()
|
||||
{
|
||||
return _properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ContextHandler for the App.
|
||||
*
|
||||
|
@ -74,19 +102,7 @@ public class App
|
|||
public ContextHandler getContextHandler() throws Exception
|
||||
{
|
||||
if (_context == null)
|
||||
{
|
||||
_context = getAppProvider().createContextHandler(this);
|
||||
|
||||
Attributes.Mapped attributes = _manager.getContextAttributes();
|
||||
if (attributes != null && attributes.size() > 0)
|
||||
{
|
||||
// Merge the manager attributes under the existing attributes
|
||||
for (String name : attributes.getAttributeNameSet())
|
||||
{
|
||||
_context.setAttribute(name, attributes.getAttribute(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
return _context;
|
||||
}
|
||||
|
||||
|
@ -117,9 +133,16 @@ public class App
|
|||
return _context == null ? null : _context.getContextPath();
|
||||
}
|
||||
|
||||
public String getEnvironment()
|
||||
/**
|
||||
* Get the environment name.
|
||||
* If the property "environment" exists, then that is returned as the environment, otherwise
|
||||
* the {@link DeploymentManager#getDefaultEnvironmentName()} is returned.
|
||||
* @return The {@link org.eclipse.jetty.util.component.Environment} name for the application.
|
||||
*/
|
||||
public String getEnvironmentName()
|
||||
{
|
||||
return _environment;
|
||||
String name = getProperties().get(Deployable.ENVIRONMENT);
|
||||
return name == null ? _manager.getDefaultEnvironmentName() : name;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -135,6 +158,6 @@ public class App
|
|||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "App[" + _context + "," + _filename + "]";
|
||||
return "App@%x[%s,%s,%s]".formatted(hashCode(), getEnvironmentName(), _context, _filename);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,4 +40,10 @@ public interface AppProvider extends LifeCycle
|
|||
* @throws Exception if unable to create context
|
||||
*/
|
||||
ContextHandler createContextHandler(App app) throws Exception;
|
||||
|
||||
/**
|
||||
*
|
||||
* @return The name of the {@link org.eclipse.jetty.util.component.Environment} this provider is for.
|
||||
*/
|
||||
String getEnvironmentName();
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
package org.eclipse.jetty.deploy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
@ -32,18 +31,17 @@ import org.eclipse.jetty.deploy.bindings.StandardUndeployer;
|
|||
import org.eclipse.jetty.deploy.graph.Edge;
|
||||
import org.eclipse.jetty.deploy.graph.Node;
|
||||
import org.eclipse.jetty.deploy.graph.Path;
|
||||
import org.eclipse.jetty.ee.Deployable;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||
import org.eclipse.jetty.util.Attributes;
|
||||
import org.eclipse.jetty.util.MultiException;
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.eclipse.jetty.util.annotation.ManagedOperation;
|
||||
import org.eclipse.jetty.util.annotation.Name;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.component.Environment;
|
||||
import org.eclipse.jetty.util.thread.AutoLock;
|
||||
import org.eclipse.jetty.xml.XmlConfiguration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -125,11 +123,26 @@ public class DeploymentManager extends ContainerLifeCycle
|
|||
private final List<AppProvider> _providers = new ArrayList<AppProvider>();
|
||||
private final AppLifeCycle _lifecycle = new AppLifeCycle();
|
||||
private final Queue<AppEntry> _apps = new ConcurrentLinkedQueue<AppEntry>();
|
||||
private Attributes.Mapped _contextAttributes = new Attributes.Mapped();
|
||||
private ContextHandlerCollection _contexts;
|
||||
private boolean _useStandardBindings = true;
|
||||
private String _defaultLifeCycleGoal = AppLifeCycle.STARTED;
|
||||
|
||||
/**
|
||||
* Get the default {@link Environment} name for deployed applications.
|
||||
* @return The name of environment known to the {@link AppProvider}s returned from
|
||||
* {@link #getAppProviders()} that matches {@link Deployable#EE_ENVIRONMENT_NAME}.
|
||||
* If multiple names match, then the maximal name, according to {@link Deployable#EE_ENVIRONMENT_COMPARATOR}
|
||||
* is returned.
|
||||
*/
|
||||
public String getDefaultEnvironmentName()
|
||||
{
|
||||
return _providers.stream()
|
||||
.map(AppProvider::getEnvironmentName)
|
||||
.filter(Deployable.EE_ENVIRONMENT_NAME)
|
||||
.max(Deployable.EE_ENVIRONMENT_COMPARATOR)
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive an app for processing.
|
||||
*
|
||||
|
@ -139,7 +152,7 @@ public class DeploymentManager extends ContainerLifeCycle
|
|||
*/
|
||||
public void addApp(App app)
|
||||
{
|
||||
LOG.debug("Deployable added: {}", app.getFilename());
|
||||
LOG.info("addApp: {}", app);
|
||||
AppEntry entry = new AppEntry();
|
||||
entry.app = app;
|
||||
entry.setLifeCycleNode(_lifecycle.getNodeByName("undeployed"));
|
||||
|
@ -373,22 +386,6 @@ public class DeploymentManager extends ContainerLifeCycle
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a contextAttribute that will be set for every Context deployed by this provider.
|
||||
*
|
||||
* @param name context attribute name
|
||||
* @return the context attribute value
|
||||
*/
|
||||
public Object getContextAttribute(String name)
|
||||
{
|
||||
return _contextAttributes.getAttribute(name);
|
||||
}
|
||||
|
||||
public Attributes.Mapped getContextAttributes()
|
||||
{
|
||||
return _contextAttributes;
|
||||
}
|
||||
|
||||
@ManagedAttribute("Deployed Contexts")
|
||||
public ContextHandlerCollection getContexts()
|
||||
{
|
||||
|
@ -421,6 +418,7 @@ public class DeploymentManager extends ContainerLifeCycle
|
|||
*/
|
||||
public void removeApp(App app)
|
||||
{
|
||||
LOG.info("removeApp: {}", app);
|
||||
Iterator<AppEntry> it = _apps.iterator();
|
||||
while (it.hasNext())
|
||||
{
|
||||
|
@ -430,7 +428,6 @@ public class DeploymentManager extends ContainerLifeCycle
|
|||
if (!AppLifeCycle.UNDEPLOYED.equals(entry.lifecyleNode.getName()))
|
||||
requestAppGoal(entry.app, AppLifeCycle.UNDEPLOYED);
|
||||
it.remove();
|
||||
LOG.debug("Deployable removed: {}", entry.app);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -450,16 +447,6 @@ public class DeploymentManager extends ContainerLifeCycle
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a contextAttribute that will be set for every Context deployed by this provider.
|
||||
*
|
||||
* @param name the context attribute name
|
||||
*/
|
||||
public void removeContextAttribute(String name)
|
||||
{
|
||||
_contextAttributes.removeAttribute(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move an {@link App} through the {@link AppLifeCycle} to the desired {@link Node}, executing each lifecycle step
|
||||
* in the process to reach the desired state.
|
||||
|
@ -571,23 +558,6 @@ public class DeploymentManager extends ContainerLifeCycle
|
|||
requestAppGoal(appentry, nodeName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a contextAttribute that will be set for every Context deployed by this provider.
|
||||
*
|
||||
* @param name the context attribute name
|
||||
* @param value the context attribute value
|
||||
*/
|
||||
public void setContextAttribute(String name, Object value)
|
||||
{
|
||||
_contextAttributes.setAttribute(name, value);
|
||||
}
|
||||
|
||||
public void setContextAttributes(Attributes contextAttributes)
|
||||
{
|
||||
this._contextAttributes.clearAttributes();
|
||||
this._contextAttributes.addAll(contextAttributes);
|
||||
}
|
||||
|
||||
public void setContexts(ContextHandlerCollection contexts)
|
||||
{
|
||||
this._contexts = contexts;
|
||||
|
@ -634,10 +604,4 @@ public class DeploymentManager extends ContainerLifeCycle
|
|||
{
|
||||
return _lifecycle.getNodes();
|
||||
}
|
||||
|
||||
public void scope(XmlConfiguration xmlc, Resource webapp)
|
||||
throws IOException
|
||||
{
|
||||
xmlc.setJettyStandardIdsAndProperties(getServer(), webapp);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,114 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.deploy;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.eclipse.jetty.util.annotation.ManagedOperation;
|
||||
import org.eclipse.jetty.util.annotation.Name;
|
||||
import org.eclipse.jetty.util.component.Dumpable;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
|
||||
/**
|
||||
* FileConfigurationManager
|
||||
*
|
||||
* Supplies properties defined in a file.
|
||||
*/
|
||||
@ManagedObject("Configure deployed webapps via properties")
|
||||
public class PropertiesConfigurationManager implements ConfigurationManager, Dumpable
|
||||
{
|
||||
private String _properties;
|
||||
private final Map<String, String> _map = new HashMap<>();
|
||||
|
||||
public PropertiesConfigurationManager(String properties)
|
||||
{
|
||||
if (properties != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
setFile(properties);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public PropertiesConfigurationManager()
|
||||
{
|
||||
this(null);
|
||||
}
|
||||
|
||||
public void setFile(String resource) throws IOException
|
||||
{
|
||||
_properties = resource;
|
||||
_map.clear();
|
||||
loadProperties(_properties);
|
||||
}
|
||||
|
||||
@ManagedAttribute("A file or URL of properties")
|
||||
public String getFile()
|
||||
{
|
||||
return _properties;
|
||||
}
|
||||
|
||||
@ManagedOperation("Set a property")
|
||||
public void put(@Name("name") String name, @Name("value") String value)
|
||||
{
|
||||
_map.put(name, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getProperties()
|
||||
{
|
||||
return _map;
|
||||
}
|
||||
|
||||
private void loadProperties(String resource) throws FileNotFoundException, IOException
|
||||
{
|
||||
Resource file = Resource.newResource(resource);
|
||||
if (file != null && file.exists())
|
||||
{
|
||||
Properties properties = new Properties();
|
||||
properties.load(file.getInputStream());
|
||||
for (Map.Entry<Object, Object> entry : properties.entrySet())
|
||||
_map.put(entry.getKey().toString(), String.valueOf(entry.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("%s@%x{%s}", this.getClass(), hashCode(), _properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dump()
|
||||
{
|
||||
return Dumpable.dump(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
Dumpable.dumpObjects(out, indent, toString(), _map);
|
||||
}
|
||||
}
|
|
@ -15,27 +15,23 @@ package org.eclipse.jetty.deploy.providers;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.eclipse.jetty.deploy.App;
|
||||
import org.eclipse.jetty.deploy.ConfigurationManager;
|
||||
import org.eclipse.jetty.deploy.util.FileID;
|
||||
import org.eclipse.jetty.ee.Deployable;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.Loader;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.eclipse.jetty.util.component.Environment;
|
||||
import org.eclipse.jetty.util.resource.JarResource;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.xml.XmlConfiguration;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -55,6 +51,7 @@ import org.slf4j.LoggerFactory;
|
|||
* implements some heuristics to ignore some files found in the scans: <ul>
|
||||
* <li>Hidden files (starting with ".") are ignored</li>
|
||||
* <li>Directories with names ending in ".d" are ignored</li>
|
||||
* <li>Property files with names ending in ".properties" are not deployed.</li>
|
||||
* <li>If a directory and a WAR file exist ( eg foo/ and foo.war) then the directory is assumed to be
|
||||
* the unpacked WAR and only the WAR is deployed (which may reused the unpacked directory)</li>
|
||||
* <li>If a directory and a matching XML file exist ( eg foo/ and foo.xml) then the directory is assumed to be
|
||||
|
@ -62,20 +59,23 @@ import org.slf4j.LoggerFactory;
|
|||
* <li>If a WAR file and a matching XML exist (eg foo.war and foo.xml) then the WAR is assumed to
|
||||
* be configured by the XML and only the XML is deployed.
|
||||
* </ul>
|
||||
* <p>
|
||||
* Only {@link App}s discovered that report {@link App#getEnvironmentName()} matching this providers
|
||||
* {@link #getEnvironmentName()} will be deployed.
|
||||
* </p>
|
||||
* <p>For XML configured contexts, the ID map will contain a reference to the {@link Server} instance called "Server" and
|
||||
* properties for the webapp file as "jetty.webapp" and directory as "jetty.webapps".
|
||||
* properties for the webapp file such as "jetty.webapp" and directory as "jetty.webapps".
|
||||
* The properties will be initialized with:<ul>
|
||||
* <li>The properties set on the application via {@link App#getProperties()}; otherwise:</li>
|
||||
* <li>The properties set on this provider via {@link #getProperties()}</li>
|
||||
* </ul>
|
||||
*/
|
||||
@ManagedObject("Provider for start-up deployement of webapps based on presence in directory")
|
||||
@ManagedObject("Provider for start-up deployment of webapps based on presence in directory")
|
||||
public class ContextProvider extends ScanningAppProvider
|
||||
{
|
||||
private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(ContextProvider.class);
|
||||
|
||||
private boolean _extract = false;
|
||||
private boolean _parentLoaderPriority = false;
|
||||
private ConfigurationManager _configurationManager;
|
||||
private String _defaultsDescriptor;
|
||||
private File _tempDirectory;
|
||||
private String[] _configurationClasses;
|
||||
private final Map<String, String> _properties = new HashMap<>();
|
||||
|
||||
public class Filter implements FilenameFilter
|
||||
{
|
||||
|
@ -87,8 +87,8 @@ public class ContextProvider extends ScanningAppProvider
|
|||
|
||||
String lowerName = name.toLowerCase(Locale.ENGLISH);
|
||||
|
||||
// TODO close resource!
|
||||
Resource resource = Resource.newResource(new File(dir, name));
|
||||
try (Resource resource = Resource.newResource(new File(dir, name)))
|
||||
{
|
||||
if (getMonitoredResources().stream().anyMatch(resource::isSame))
|
||||
return false;
|
||||
|
||||
|
@ -96,6 +96,10 @@ public class ContextProvider extends ScanningAppProvider
|
|||
if (lowerName.startsWith("."))
|
||||
return false;
|
||||
|
||||
// ignore property files
|
||||
if (lowerName.endsWith(".properties"))
|
||||
return false;
|
||||
|
||||
// Ignore some directories
|
||||
if (resource.isDirectory())
|
||||
{
|
||||
|
@ -114,6 +118,7 @@ public class ContextProvider extends ScanningAppProvider
|
|||
//is it a sccs dir?
|
||||
return !"cvs".equals(lowerName) && !"cvsroot".equals(lowerName); // OK to deploy it then
|
||||
}
|
||||
}
|
||||
|
||||
// else is it a war file
|
||||
if (lowerName.endsWith(".war"))
|
||||
|
@ -131,161 +136,186 @@ public class ContextProvider extends ScanningAppProvider
|
|||
setScanInterval(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the extractWars.
|
||||
*
|
||||
* @return the extractWars
|
||||
* @deprecated use {@link #isExtract()}
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean isExtractWars()
|
||||
public Map<String, String> getProperties()
|
||||
{
|
||||
return isExtract();
|
||||
return _properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if WAR and JAR are extraced on deploy.
|
||||
* Get the extractWars.
|
||||
* This is equivalent to getting the {@link Deployable#EXTRACT_WARS} property.
|
||||
*
|
||||
* @return the extractWars
|
||||
*/
|
||||
@ManagedAttribute("extract WAR and JAR files")
|
||||
public boolean isExtract()
|
||||
@ManagedAttribute("extract war files")
|
||||
public boolean isExtractWars()
|
||||
{
|
||||
return _extract;
|
||||
return Boolean.parseBoolean(_properties.get(Deployable.EXTRACT_WARS));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the extractWars.
|
||||
* This is equivalent to setting the {@link Deployable#EXTRACT_WARS} property.
|
||||
*
|
||||
* @param extract the extractWars to set
|
||||
* @deprecated use {@link #setExtract(boolean)}
|
||||
* @param extractWars the extractWars to set
|
||||
*/
|
||||
@Deprecated
|
||||
public void setExtractWars(boolean extract)
|
||||
public void setExtractWars(boolean extractWars)
|
||||
{
|
||||
setExtract(extract);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to extract WAR and JAR files.
|
||||
*
|
||||
* @param extract the extractWars to set
|
||||
*/
|
||||
public void setExtract(boolean extract)
|
||||
{
|
||||
_extract = extract;
|
||||
_properties.put(Deployable.EXTRACT_WARS, Boolean.toString(extractWars));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parentLoaderPriority.
|
||||
* This is equivalent to getting the {@link Deployable#PARENT_LOADER_PRIORITY} property.
|
||||
*
|
||||
* @return the parentLoaderPriority
|
||||
*/
|
||||
@ManagedAttribute("parent classloader has priority")
|
||||
public boolean isParentLoaderPriority()
|
||||
{
|
||||
return _parentLoaderPriority;
|
||||
return Boolean.parseBoolean(_properties.get(Deployable.PARENT_LOADER_PRIORITY));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the parentLoaderPriority.
|
||||
* This is equivalent to setting the {@link Deployable#PARENT_LOADER_PRIORITY} property.
|
||||
*
|
||||
* @param parentLoaderPriority the parentLoaderPriority to set
|
||||
*/
|
||||
public void setParentLoaderPriority(boolean parentLoaderPriority)
|
||||
{
|
||||
_parentLoaderPriority = parentLoaderPriority;
|
||||
_properties.put(Deployable.PARENT_LOADER_PRIORITY, Boolean.toString(parentLoaderPriority));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the defaultsDescriptor.
|
||||
* This is equivalent to getting the {@link Deployable#DEFAULTS_DESCRIPTOR} property.
|
||||
*
|
||||
* @return the defaultsDescriptor
|
||||
*/
|
||||
@ManagedAttribute("default descriptor for webapps")
|
||||
public String getDefaultsDescriptor()
|
||||
{
|
||||
return _defaultsDescriptor;
|
||||
return _properties.get(Deployable.DEFAULTS_DESCRIPTOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the defaultsDescriptor.
|
||||
* This is equivalent to setting the {@link Deployable#DEFAULTS_DESCRIPTOR} property.
|
||||
*
|
||||
* @param defaultsDescriptor the defaultsDescriptor to set
|
||||
*/
|
||||
public void setDefaultsDescriptor(String defaultsDescriptor)
|
||||
{
|
||||
_defaultsDescriptor = defaultsDescriptor;
|
||||
}
|
||||
|
||||
public ConfigurationManager getConfigurationManager()
|
||||
{
|
||||
return _configurationManager;
|
||||
_properties.put(Deployable.DEFAULTS_DESCRIPTOR, defaultsDescriptor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the configurationManager.
|
||||
*
|
||||
* @param configurationManager the configurationManager to set
|
||||
* This is equivalent to setting the {@link Deployable#CONFIGURATION_CLASSES} property.
|
||||
* @param configurations The configuration class names as a comma separated list
|
||||
*/
|
||||
public void setConfigurationManager(ConfigurationManager configurationManager)
|
||||
public void setConfigurationClasses(String configurations)
|
||||
{
|
||||
updateBean(_configurationManager, configurationManager);
|
||||
_configurationManager = configurationManager;
|
||||
setConfigurationClasses(StringUtil.isBlank(configurations) ? null : configurations.split(","));
|
||||
}
|
||||
|
||||
/**
|
||||
* This is equivalent to setting the {@link Deployable#CONFIGURATION_CLASSES} property.
|
||||
* @param configurations The configuration class names.
|
||||
*/
|
||||
public void setConfigurationClasses(String[] configurations)
|
||||
{
|
||||
_configurationClasses = configurations == null ? null : configurations.clone();
|
||||
}
|
||||
|
||||
@ManagedAttribute("configuration classes for webapps to be processed through")
|
||||
public String[] getConfigurationClasses()
|
||||
{
|
||||
return _configurationClasses;
|
||||
_properties.put(Deployable.CONFIGURATION_CLASSES, (configurations == null)
|
||||
? null
|
||||
: String.join(",", configurations));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Work directory where unpacked WAR files are managed from.
|
||||
*
|
||||
* This is equivalent to getting the {@link Deployable#CONFIGURATION_CLASSES} property.
|
||||
* @return The configuration class names.
|
||||
*/
|
||||
@ManagedAttribute("configuration classes for webapps to be processed through")
|
||||
public String[] getConfigurationClasses()
|
||||
{
|
||||
String cc = _properties.get(Deployable.CONFIGURATION_CLASSES);
|
||||
return cc == null ? new String[0] : cc.split(",");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the temporary directory for deployment.
|
||||
* <p>
|
||||
* Default is the same as the <code>java.io.tmpdir</code> System Property.
|
||||
* This is equivalent to setting the {@link Deployable#BASE_TEMP_DIR} property.
|
||||
* If not set, then the <code>java.io.tmpdir</code> System Property is used.
|
||||
*
|
||||
* @param directory the new work directory
|
||||
*/
|
||||
public void setTempDir(String directory)
|
||||
{
|
||||
_properties.put(Deployable.BASE_TEMP_DIR, directory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the temporary directory for deployment.
|
||||
* <p>
|
||||
* This is equivalent to setting the {@link Deployable#BASE_TEMP_DIR} property.
|
||||
* If not set, then the <code>java.io.tmpdir</code> System Property is used.
|
||||
*
|
||||
* @param directory the new work directory
|
||||
*/
|
||||
public void setTempDir(File directory)
|
||||
{
|
||||
_tempDirectory = directory;
|
||||
_properties.put(Deployable.BASE_TEMP_DIR, directory.getAbsolutePath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user supplied Work Directory.
|
||||
* Get the temporary directory for deployment.
|
||||
* <p>
|
||||
* This is equivalent to getting the {@link Deployable#BASE_TEMP_DIR} property.
|
||||
*
|
||||
* @return the user supplied work directory (null if user has not set Temp Directory yet)
|
||||
*/
|
||||
@ManagedAttribute("temp directory for use, null if no user set temp directory")
|
||||
public File getTempDir()
|
||||
{
|
||||
return _tempDirectory;
|
||||
String tmpDir = _properties.get(Deployable.BASE_TEMP_DIR);
|
||||
return tmpDir == null ? null : new File(tmpDir);
|
||||
}
|
||||
|
||||
protected void initializeWebAppContextDefaults(ContextHandler webapp)
|
||||
protected ContextHandler initializeContextHandler(Object context, File file, Map<String, String> properties)
|
||||
{
|
||||
if (_defaultsDescriptor != null)
|
||||
webapp.setAttribute("defaultsDescriptor", _defaultsDescriptor);
|
||||
|
||||
if (_tempDirectory != null)
|
||||
// find the ContextHandler
|
||||
ContextHandler contextHandler;
|
||||
if (context instanceof ContextHandler handler)
|
||||
contextHandler = handler;
|
||||
else if (Supplier.class.isAssignableFrom(context.getClass()))
|
||||
{
|
||||
// TODO work out temp directory
|
||||
// TODO set if the temp directory is persistent
|
||||
webapp.setAttribute(Server.BASE_TEMP_DIR_ATTR, _tempDirectory);
|
||||
@SuppressWarnings("unchecked")
|
||||
Supplier<ContextHandler> provider = (Supplier<ContextHandler>)context;
|
||||
contextHandler = provider.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalStateException("No ContextHandler for " + context);
|
||||
}
|
||||
|
||||
assert contextHandler != null;
|
||||
|
||||
initializeContextPath(contextHandler, file.getName());
|
||||
|
||||
if (file.isDirectory())
|
||||
contextHandler.setBaseResource(Resource.newResource(file));
|
||||
|
||||
if (context instanceof Deployable deployable)
|
||||
deployable.initializeDefaults(properties);
|
||||
|
||||
return contextHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextHandler createContextHandler(final App app) throws Exception
|
||||
{
|
||||
Environment environment = Environment.get(app.getEnvironment());
|
||||
Environment environment = Environment.get(app.getEnvironmentName());
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("createContextHandler {} in {}", app, environment);
|
||||
|
@ -295,52 +325,31 @@ public class ContextProvider extends ScanningAppProvider
|
|||
{
|
||||
Thread.currentThread().setContextClassLoader(environment.getClassLoader());
|
||||
|
||||
Resource resource = Resource.newResource(app.getFilename());
|
||||
if (!resource.exists())
|
||||
throw new IllegalStateException("App resource does not exist " + resource);
|
||||
resource = unpack(resource); // TODO move unpacking to below.
|
||||
// Create de-aliased file
|
||||
File file = new File(app.getFilename()).toPath().toRealPath().toFile().getCanonicalFile().getAbsoluteFile();
|
||||
if (!file.exists())
|
||||
throw new IllegalStateException("App resource does not exist " + file);
|
||||
|
||||
File file = resource.getFile();
|
||||
|
||||
|
||||
final String contextName = file.getName();
|
||||
|
||||
// Resource aliases (after getting name) to ensure baseResource is not an alias
|
||||
if (resource.isAlias())
|
||||
{
|
||||
file = new File(resource.getAlias()).toPath().toRealPath().toFile();
|
||||
resource = Resource.newResource(file);
|
||||
if (!resource.exists())
|
||||
throw new IllegalStateException("App resource does not exist " + resource);
|
||||
}
|
||||
// prepare properties
|
||||
Map<String, String> properties = new HashMap<>();
|
||||
properties.putAll(getProperties());
|
||||
properties.putAll(app.getProperties());
|
||||
|
||||
// Handle a context XML file
|
||||
if (resource.exists() && FileID.isXmlFile(file))
|
||||
if (FileID.isXmlFile(file))
|
||||
{
|
||||
XmlConfiguration xmlc = new XmlConfiguration(resource)
|
||||
XmlConfiguration xmlc = new XmlConfiguration(file, null, properties)
|
||||
{
|
||||
@Override
|
||||
public void initializeDefaults(Object context)
|
||||
{
|
||||
super.initializeDefaults(context);
|
||||
|
||||
// If the XML created object is a ContextHandler
|
||||
if (context instanceof ContextHandler contextHandler)
|
||||
{
|
||||
initializeWebAppContextDefaults(contextHandler);
|
||||
initializeContextPath(contextHandler, contextName, true);
|
||||
|
||||
// TODO look for associated WAR file or directory
|
||||
// TODO if it is a WAR file, then perhaps unpack it
|
||||
// TODO set as default baseResource
|
||||
}
|
||||
ContextProvider.this.initializeContextHandler(context, file, properties);
|
||||
}
|
||||
};
|
||||
|
||||
xmlc.getIdMap().put("Environment", environment);
|
||||
getDeploymentManager().scope(xmlc, resource);
|
||||
if (getConfigurationManager() != null)
|
||||
xmlc.getProperties().putAll(getConfigurationManager().getProperties());
|
||||
xmlc.setJettyStandardIdsAndProperties(getDeploymentManager().getServer(), file);
|
||||
|
||||
Object context = xmlc.configure();
|
||||
if (context instanceof ContextHandler contextHandler)
|
||||
|
@ -367,24 +376,10 @@ public class ContextProvider extends ScanningAppProvider
|
|||
Class<?> contextHandlerClass = Loader.loadClass(contextHandlerClassName);
|
||||
if (contextHandlerClass == null)
|
||||
throw new IllegalStateException("Unknown ContextHandler class " + contextHandlerClassName + " for " + app);
|
||||
ContextHandler contextHandler;
|
||||
if (Supplier.class.isAssignableFrom(contextHandlerClass))
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
Supplier<ContextHandler> provider = (Supplier<ContextHandler>)contextHandlerClass.getDeclaredConstructor().newInstance();
|
||||
contextHandler = provider.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
contextHandler = (ContextHandler)contextHandlerClass.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
initializeWebAppContextDefaults(contextHandler);
|
||||
initializeContextPath(contextHandler, contextName, !file.isDirectory());
|
||||
|
||||
// TODO unpack here (after temp directory is known)
|
||||
contextHandler.setBaseResource(Resource.newResource(file.getAbsoluteFile()));
|
||||
|
||||
return contextHandler;
|
||||
Object context = contextHandlerClass.getDeclaredConstructor().newInstance();
|
||||
properties.put(Deployable.WAR, file.getCanonicalPath());
|
||||
return initializeContextHandler(context, file, properties);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -392,13 +387,10 @@ public class ContextProvider extends ScanningAppProvider
|
|||
}
|
||||
}
|
||||
|
||||
protected void initializeContextPath(ContextHandler context, String contextName, boolean stripExtension)
|
||||
protected void initializeContextPath(ContextHandler context, String contextName)
|
||||
{
|
||||
String contextPath = contextName;
|
||||
|
||||
// Strip any 3 char extension from non directories
|
||||
if (stripExtension && contextPath.length() > 4 && contextPath.charAt(contextPath.length() - 4) == '.')
|
||||
contextPath = contextPath.substring(0, contextPath.length() - 4);
|
||||
String contextPath = FileID.getDot3Basename(contextName);
|
||||
|
||||
// Ensure "/" is Not Trailing in context paths.
|
||||
if (contextPath.endsWith("/") && contextPath.length() > 1)
|
||||
|
@ -566,90 +558,4 @@ public class ContextProvider extends ScanningAppProvider
|
|||
|
||||
super.fileRemoved(filename);
|
||||
}
|
||||
|
||||
public Resource unpack(Resource resourceBase) throws IOException
|
||||
{
|
||||
// Accept aliases for WAR files
|
||||
if (resourceBase.isAlias())
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("{} anti-aliased to {}", resourceBase, resourceBase.getAlias());
|
||||
URI alias = resourceBase.getAlias();
|
||||
resourceBase.close();
|
||||
resourceBase = Resource.newResource(alias);
|
||||
}
|
||||
|
||||
if (!isExtract() || resourceBase.isDirectory() || resourceBase.getFile() == null)
|
||||
return resourceBase;
|
||||
|
||||
// is the extension a known extension
|
||||
if (!resourceBase.getFile().getName().toLowerCase().endsWith(".war") &&
|
||||
!resourceBase.getFile().getName().toLowerCase().endsWith(".jar"))
|
||||
return resourceBase;
|
||||
|
||||
// Track the original web_app Resource, as this could be a PathResource.
|
||||
// Later steps force the Resource to be a JarFileResource, which introduces
|
||||
// URLConnection caches in such a way that it prevents Hot Redeployment
|
||||
// on MS Windows.
|
||||
Resource originalResource = resourceBase;
|
||||
|
||||
// Look for unpacked directory
|
||||
Path path = resourceBase.getPath();
|
||||
String name = path.getName(path.getNameCount() - 1).toString();
|
||||
name = name.substring(0, name.length() - 4);
|
||||
Path directory = path.getParent(); // TODO support unpacking to temp or work directory
|
||||
File unpacked = directory.resolve(name).toFile();
|
||||
File extractLock = directory.resolve(".extract_lock").toFile();
|
||||
|
||||
if (!Files.isWritable(directory))
|
||||
{
|
||||
LOG.warn("!Writable {} -> {}", resourceBase, directory);
|
||||
return resourceBase;
|
||||
}
|
||||
|
||||
// Does the directory already exist and is newer than the packed file?
|
||||
if (unpacked.exists())
|
||||
{
|
||||
// If it is not a directory, then we can't unpack
|
||||
if (!unpacked.isDirectory())
|
||||
{
|
||||
LOG.warn("Unusable {} -> {}", resourceBase, unpacked);
|
||||
return resourceBase;
|
||||
}
|
||||
|
||||
// If it is newer than the resource base and there is no partial extraction, then use it.
|
||||
if (Files.getLastModifiedTime(directory).toMillis() >= resourceBase.lastModified() && !extractLock.exists())
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Reuse {} -> {}", resourceBase, unpacked);
|
||||
resourceBase.close();
|
||||
return Resource.newResource(unpacked);
|
||||
}
|
||||
|
||||
extractLock.createNewFile();
|
||||
IO.delete(unpacked);
|
||||
}
|
||||
else
|
||||
{
|
||||
extractLock.createNewFile();
|
||||
}
|
||||
|
||||
if (!unpacked.mkdir())
|
||||
{
|
||||
LOG.warn("Cannot Create {} -> {}", resourceBase, unpacked);
|
||||
extractLock.delete();
|
||||
return resourceBase;
|
||||
}
|
||||
|
||||
LOG.debug("Unpack {} -> {}", resourceBase, unpacked);
|
||||
try (Resource jar = JarResource.newJarResource(resourceBase))
|
||||
{
|
||||
jar.copyTo(unpacked);
|
||||
}
|
||||
|
||||
extractLock.delete();
|
||||
resourceBase.close();
|
||||
|
||||
return Resource.newResource(unpacked);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
|||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.eclipse.jetty.util.annotation.ManagedOperation;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.eclipse.jetty.util.component.Environment;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -49,7 +50,7 @@ public abstract class ScanningAppProvider extends ContainerLifeCycle implements
|
|||
private int _scanInterval = 10;
|
||||
private Scanner _scanner;
|
||||
private boolean _useRealPaths;
|
||||
private String _defaultEnvironment = "ee9"; // TODO null or ee10?
|
||||
private String _environmentName;
|
||||
|
||||
private final Scanner.DiscreteListener _scannerListener = new Scanner.DiscreteListener()
|
||||
{
|
||||
|
@ -83,14 +84,15 @@ public abstract class ScanningAppProvider extends ContainerLifeCycle implements
|
|||
addBean(_appMap);
|
||||
}
|
||||
|
||||
public String getDefaultEnvironment()
|
||||
@Override
|
||||
public String getEnvironmentName()
|
||||
{
|
||||
return _defaultEnvironment;
|
||||
return _environmentName;
|
||||
}
|
||||
|
||||
public void setDefaultEnvironment(String defaultEnvironment)
|
||||
public void setEnvironmentName(String environmentName)
|
||||
{
|
||||
_defaultEnvironment = defaultEnvironment;
|
||||
_environmentName = environmentName;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -135,10 +137,17 @@ public abstract class ScanningAppProvider extends ContainerLifeCycle implements
|
|||
*/
|
||||
protected App createApp(String filename)
|
||||
{
|
||||
// TODO otherways to work out the environment????
|
||||
String environment = getDefaultEnvironment();
|
||||
App app = new App(_deploymentManager, this, filename);
|
||||
|
||||
return new App(_deploymentManager, this, environment, filename);
|
||||
// Only deploy apps for this environment
|
||||
if (app.getEnvironmentName().equals(getEnvironmentName()))
|
||||
return app;
|
||||
|
||||
boolean appProvider4env = _deploymentManager.getAppProviders().stream()
|
||||
.map(AppProvider::getEnvironmentName).anyMatch(app.getEnvironmentName()::equals);
|
||||
if (!appProvider4env)
|
||||
LOG.warn("No AppProvider with environment {} for {}", app.getEnvironmentName(), app);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -148,8 +157,19 @@ public abstract class ScanningAppProvider extends ContainerLifeCycle implements
|
|||
LOG.debug("{}.doStart()", this.getClass().getSimpleName());
|
||||
if (_monitored.size() == 0)
|
||||
throw new IllegalStateException("No configuration dir specified");
|
||||
if (_environmentName == null)
|
||||
{
|
||||
List<Environment> nonCore = Environment.getAll().stream().filter(environment -> !environment.equals(Environment.CORE)).toList();
|
||||
if (nonCore.size() != 1)
|
||||
throw new IllegalStateException("No environment configured");
|
||||
_environmentName = nonCore.get(0).getName();
|
||||
}
|
||||
|
||||
LOG.info("Deployment monitor {}", _monitored);
|
||||
Environment environment = Environment.get(_environmentName);
|
||||
if (environment == null)
|
||||
throw new IllegalStateException("Unknown environment " + _environmentName);
|
||||
|
||||
LOG.info("Deployment monitor {} in {} at intervals {}s", getEnvironmentName(), _monitored, getScanInterval());
|
||||
List<File> files = new ArrayList<>();
|
||||
for (Resource resource : _monitored)
|
||||
{
|
||||
|
@ -191,9 +211,10 @@ public abstract class ScanningAppProvider extends ContainerLifeCycle implements
|
|||
|
||||
protected void fileAdded(String filename) throws Exception
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("added {}", filename);
|
||||
App app = ScanningAppProvider.this.createApp(filename);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("fileAdded {}: {}", filename, app);
|
||||
|
||||
if (app != null)
|
||||
{
|
||||
_appMap.put(filename, app);
|
||||
|
@ -203,14 +224,12 @@ public abstract class ScanningAppProvider extends ContainerLifeCycle implements
|
|||
|
||||
protected void fileChanged(String filename) throws Exception
|
||||
{
|
||||
App oldApp = _appMap.remove(filename);
|
||||
if (oldApp != null)
|
||||
_deploymentManager.removeApp(oldApp);
|
||||
App app = ScanningAppProvider.this.createApp(filename);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("changed {}", filename);
|
||||
App app = _appMap.remove(filename);
|
||||
if (app != null)
|
||||
{
|
||||
_deploymentManager.removeApp(app);
|
||||
}
|
||||
app = ScanningAppProvider.this.createApp(filename);
|
||||
LOG.debug("fileChanged {}: {}", filename, app);
|
||||
if (app != null)
|
||||
{
|
||||
_appMap.put(filename, app);
|
||||
|
@ -220,9 +239,9 @@ public abstract class ScanningAppProvider extends ContainerLifeCycle implements
|
|||
|
||||
protected void fileRemoved(String filename) throws Exception
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("removed {}", filename);
|
||||
App app = _appMap.remove(filename);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("fileRemoved {}: {}", filename, app);
|
||||
if (app != null)
|
||||
_deploymentManager.removeApp(app);
|
||||
}
|
||||
|
|
|
@ -22,41 +22,18 @@ import java.util.Locale;
|
|||
*/
|
||||
public class FileID
|
||||
{
|
||||
/**
|
||||
* Is the path a Web Archive?
|
||||
*
|
||||
* @param path the path to test.
|
||||
* @return True if a .war or .jar or exploded web directory
|
||||
* @see FileID#isWebArchiveFile(File)
|
||||
*/
|
||||
public static boolean isWebArchive(File path)
|
||||
{
|
||||
if (path.isFile())
|
||||
{
|
||||
String name = path.getName().toLowerCase(Locale.ENGLISH);
|
||||
return (name.endsWith(".war") || name.endsWith(".jar"));
|
||||
}
|
||||
|
||||
File webInf = new File(path, "WEB-INF");
|
||||
File webXml = new File(webInf, "web.xml");
|
||||
return webXml.exists() && webXml.isFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the path a Web Archive File (not directory)
|
||||
*
|
||||
* @param path the path to test.
|
||||
* @param file the path to test.
|
||||
* @return True if a .war or .jar file.
|
||||
* @see FileID#isWebArchive(File)
|
||||
*/
|
||||
public static boolean isWebArchiveFile(File path)
|
||||
{
|
||||
if (!path.isFile())
|
||||
public static boolean isWebArchiveFile(File file)
|
||||
{
|
||||
if (!file.isFile())
|
||||
return false;
|
||||
}
|
||||
|
||||
String name = path.getName().toLowerCase(Locale.ENGLISH);
|
||||
String name = file.getName().toLowerCase(Locale.ENGLISH);
|
||||
return (name.endsWith(".war") || name.endsWith(".jar"));
|
||||
}
|
||||
|
||||
|
@ -70,4 +47,16 @@ public class FileID
|
|||
String name = path.getName().toLowerCase(Locale.ENGLISH);
|
||||
return name.endsWith(".xml");
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove any 3 character suffix (e.g. ".war") from a path
|
||||
* @param path The string path
|
||||
* @return The path without the suffix or the original path
|
||||
*/
|
||||
public static String getDot3Basename(String path)
|
||||
{
|
||||
if (path == null || path.length() <= 4 || path.charAt(path.length() - 4) != '.')
|
||||
return path;
|
||||
return path.substring(0, path.length() - 4);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,10 +20,14 @@ import org.eclipse.jetty.deploy.test.XmlConfiguredJetty;
|
|||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||
import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;
|
||||
import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension;
|
||||
import org.eclipse.jetty.util.component.Environment;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
|
@ -77,6 +81,57 @@ public class DeploymentManagerTest
|
|||
assertEquals(1, deploybindings.size(), "'deploying' Bindings.size");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultEnvironment()
|
||||
{
|
||||
DeploymentManager depman = new DeploymentManager();
|
||||
assertThat(depman.getDefaultEnvironmentName(), Matchers.nullValue());
|
||||
|
||||
Environment.ensure("ee7");
|
||||
depman.addAppProvider(new MockAppProvider()
|
||||
{
|
||||
@Override
|
||||
public String getEnvironmentName()
|
||||
{
|
||||
return "ee7";
|
||||
}
|
||||
});
|
||||
assertThat(depman.getDefaultEnvironmentName(), is("ee7"));
|
||||
|
||||
Environment.ensure("ee12");
|
||||
depman.addAppProvider(new MockAppProvider()
|
||||
{
|
||||
@Override
|
||||
public String getEnvironmentName()
|
||||
{
|
||||
return "ee12";
|
||||
}
|
||||
});
|
||||
assertThat(depman.getDefaultEnvironmentName(), is("ee12"));
|
||||
|
||||
Environment.ensure("ee10");
|
||||
depman.addAppProvider(new MockAppProvider()
|
||||
{
|
||||
@Override
|
||||
public String getEnvironmentName()
|
||||
{
|
||||
return "ee12";
|
||||
}
|
||||
});
|
||||
assertThat(depman.getDefaultEnvironmentName(), is("ee12"));
|
||||
|
||||
Environment.ensure("somethingElse");
|
||||
depman.addAppProvider(new MockAppProvider()
|
||||
{
|
||||
@Override
|
||||
public String getEnvironmentName()
|
||||
{
|
||||
return "ee12";
|
||||
}
|
||||
});
|
||||
assertThat(depman.getDefaultEnvironmentName(), is("ee12"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled // TODO
|
||||
public void testXmlConfigured() throws Exception
|
||||
|
|
|
@ -20,12 +20,19 @@ import org.eclipse.jetty.server.handler.ContextHandler;
|
|||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
import org.eclipse.jetty.util.component.Environment;
|
||||
|
||||
public class MockAppProvider extends AbstractLifeCycle implements AppProvider
|
||||
{
|
||||
private DeploymentManager deployMan;
|
||||
private File webappsDir;
|
||||
|
||||
@Override
|
||||
public String getEnvironmentName()
|
||||
{
|
||||
return Environment.ensure("mock").getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeploymentManager(DeploymentManager deploymentManager)
|
||||
{
|
||||
|
@ -40,7 +47,7 @@ public class MockAppProvider extends AbstractLifeCycle implements AppProvider
|
|||
|
||||
public void findWebapp(String name)
|
||||
{
|
||||
App app = new App(deployMan, this, null, "mock-" + name);
|
||||
App app = new App(deployMan, this, "mock-" + name);
|
||||
this.deployMan.addApp(app);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-core</artifactId>
|
||||
<version>12.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-ee</artifactId>
|
||||
<name>Jetty Core :: EE Utility Classes</name>
|
||||
<properties>
|
||||
<bundle-symbolic-name>${project.groupId}.ee</bundle-symbolic-name>
|
||||
<spotbugs.onlyAnalyze>org.eclipse.jetty.ee.*</spotbugs.onlyAnalyze>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<argLine>
|
||||
@{argLine} ${jetty.surefire.argLine} --add-reads org.eclipse.jetty.io=org.eclipse.jetty.logging
|
||||
</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-io</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-jmx</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-slf4j-impl</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.toolchain</groupId>
|
||||
<artifactId>jetty-test-helper</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -11,16 +11,14 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.deploy;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* ConfigurationManager
|
||||
*
|
||||
* Type for allow injection of property values for replacement in jetty xml files during deployment.
|
||||
*/
|
||||
public interface ConfigurationManager
|
||||
module org.eclipse.jetty.ee
|
||||
{
|
||||
public Map<String, String> getProperties();
|
||||
requires org.slf4j;
|
||||
|
||||
requires transitive org.eclipse.jetty.io;
|
||||
|
||||
// Only required if using JMX.
|
||||
requires static org.eclipse.jetty.jmx;
|
||||
|
||||
exports org.eclipse.jetty.ee;
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.ee;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public interface Deployable
|
||||
{
|
||||
Pattern EE_ENVIRONMENT_NAME_PATTERN = Pattern.compile("ee(\\d*)");
|
||||
|
||||
Predicate<String> EE_ENVIRONMENT_NAME = s -> EE_ENVIRONMENT_NAME_PATTERN.matcher(s).matches();
|
||||
|
||||
Comparator<String> EE_ENVIRONMENT_COMPARATOR = (e1, e2) ->
|
||||
{
|
||||
Matcher m1 = EE_ENVIRONMENT_NAME_PATTERN.matcher(e1);
|
||||
Matcher m2 = EE_ENVIRONMENT_NAME_PATTERN.matcher(e2);
|
||||
|
||||
if (m1.matches() && m2.matches())
|
||||
{
|
||||
int n1 = Integer.parseInt(m1.group(1));
|
||||
int n2 = Integer.parseInt(m2.group(1));
|
||||
return Integer.compare(n1, n2);
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
String ENVIRONMENT = "environment";
|
||||
|
||||
String WAR = "jetty.deploy.war";
|
||||
String BASE_TEMP_DIR = "jetty.deploy.tempDir";
|
||||
String CONFIGURATION_CLASSES = "jetty.deploy.configurationClasses";
|
||||
String CONTAINER_SCAN_JARS = "jetty.deploy.containerScanJarPattern";
|
||||
String DEFAULTS_DESCRIPTOR = "jetty.deploy.defaultsDescriptor";
|
||||
String EXTRACT_WARS = "jetty.deploy.extractWars";
|
||||
String PARENT_LOADER_PRIORITY = "jetty.deploy.parentLoaderPriority";
|
||||
String SCI_EXCLUSION_PATTERN = "jetty.deploy.servletContainerInitializerExclusionPattern";
|
||||
String SCI_ORDER = "jetty.deploy.servletContainerInitializerOrder";
|
||||
String WEBINF_SCAN_JARS = "jetty.deploy.webInfScanJarPattern";
|
||||
|
||||
void initializeDefaults(Map<String, String> properties);
|
||||
}
|
|
@ -19,6 +19,7 @@ lib/jetty-server-${jetty.version}.jar
|
|||
lib/jetty-xml-${jetty.version}.jar
|
||||
lib/jetty-util-${jetty.version}.jar
|
||||
lib/jetty-io-${jetty.version}.jar
|
||||
lib/jetty-ee-${jetty.version}.jar
|
||||
|
||||
[xml]
|
||||
etc/jetty.xml
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
package org.eclipse.jetty.xml;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.annotation.Annotation;
|
||||
|
@ -157,7 +159,7 @@ public class XmlConfiguration
|
|||
* @param server The Server object to set
|
||||
* @param webapp The webapps Resource
|
||||
*/
|
||||
public void setJettyStandardIdsAndProperties(Object server, Resource webapp)
|
||||
public void setJettyStandardIdsAndProperties(Object server, File webapp)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -174,7 +176,7 @@ public class XmlConfiguration
|
|||
|
||||
if (webapp != null)
|
||||
{
|
||||
Path webappPath = webapp.getFile().toPath().toAbsolutePath();
|
||||
Path webappPath = webapp.toPath().toAbsolutePath();
|
||||
getProperties().put("jetty.webapp", webappPath.toString());
|
||||
getProperties().put("jetty.webapps", webappPath.getParent().toString());
|
||||
getProperties().put("jetty.webapps.uri", normalizeURI(webappPath.getParent().toUri().toString()));
|
||||
|
@ -193,8 +195,8 @@ public class XmlConfiguration
|
|||
return uri;
|
||||
}
|
||||
|
||||
private final Map<String, Object> _idMap = new HashMap<>();
|
||||
private final Map<String, String> _propertyMap = new HashMap<>();
|
||||
private final Map<String, Object> _idMap;
|
||||
private final Map<String, String> _propertyMap;
|
||||
private final Resource _location;
|
||||
private final String _dtd;
|
||||
private ConfigurationProcessor _processor;
|
||||
|
@ -216,11 +218,27 @@ public class XmlConfiguration
|
|||
*/
|
||||
public XmlConfiguration(Resource resource) throws SAXException, IOException
|
||||
{
|
||||
try (ConfigurationParser parser = getParser(); InputStream inputStream = resource.getInputStream())
|
||||
this(resource.getFile(), null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads and parses the XML configuration file.
|
||||
*
|
||||
* @param file the XML configuration
|
||||
* @param idMap Map of objects with IDs
|
||||
* @param properties Map of properties
|
||||
* @throws IOException if the configuration could not be read
|
||||
* @throws SAXException if the configuration could not be parsed
|
||||
*/
|
||||
public XmlConfiguration(File file, Map<String, Object> idMap, Map<String, String> properties) throws SAXException, IOException
|
||||
{
|
||||
_location = resource;
|
||||
try (ConfigurationParser parser = getParser(); InputStream inputStream = new FileInputStream(file))
|
||||
{
|
||||
_location = Resource.newResource(file);
|
||||
setConfig(parser.parse(inputStream));
|
||||
_dtd = parser.getDTD();
|
||||
_idMap = idMap == null ? new HashMap<>() : idMap;
|
||||
_propertyMap = properties == null ? new HashMap<>() : properties;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1609,7 +1609,7 @@ public class XmlConfigurationTest
|
|||
" </Set>" +
|
||||
"</Configure>");
|
||||
|
||||
configuration.setJettyStandardIdsAndProperties(null, Resource.newResource(war));
|
||||
configuration.setJettyStandardIdsAndProperties(null, war.toFile());
|
||||
|
||||
TestConfiguration tc = new TestConfiguration();
|
||||
configuration.configure(tc);
|
||||
|
@ -1724,7 +1724,7 @@ public class XmlConfigurationTest
|
|||
|
||||
try
|
||||
{
|
||||
configuration.setJettyStandardIdsAndProperties(null, Resource.newResource(war));
|
||||
configuration.setJettyStandardIdsAndProperties(null, war.toFile());
|
||||
configuration.getProperties().put("jetty.base", jettyBasePath);
|
||||
if (configValue != null)
|
||||
configuration.getProperties().put("jetty.sslContext.keyStorePath", configValue);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
<module>jetty-bom</module>
|
||||
<module>jetty-client</module>
|
||||
<module>jetty-deploy</module>
|
||||
<module>jetty-ee</module>
|
||||
<module>jetty-fcgi</module>
|
||||
<module>jetty-http</module>
|
||||
<module>jetty-http2</module>
|
||||
|
|
|
@ -14,5 +14,5 @@ webapp
|
|||
ee10-deploy
|
||||
|
||||
[files]
|
||||
maven://org.eclipse.jetty.ee10.demos/ee10-demo-async-rest-webapp/${jetty.version}/war|webapps-ee10/ee10-demo-async-rest.war
|
||||
maven://org.eclipse.jetty.ee10.demos/jetty-ee10-demo-async-rest-webapp/${jetty.version}/war|webapps/ee10-demo-async-rest.war
|
||||
|
||||
|
|
|
@ -19,10 +19,10 @@ ee10-annotations
|
|||
ext
|
||||
|
||||
[files]
|
||||
basehome:modules/demo.d/ee10-demo-jaas.xml|webapps-ee10/ee10-demo-jaas.xml
|
||||
basehome:modules/demo.d/ee10-demo-jaas.xml|webapps/ee10-demo-jaas.xml
|
||||
basehome:modules/demo.d/ee10-demo-login.conf|etc/ee10-demo-login.conf
|
||||
basehome:modules/demo.d/ee10-demo-login.properties|etc/ee10-demo-login.properties
|
||||
maven://org.eclipse.jetty.ee10.demos/ee10-demo-jaas-webapp/${jetty.version}/war|webapps-ee10/ee10-demo-jaas.war
|
||||
maven://org.eclipse.jetty.ee10.demos/jetty-ee10-demo-jaas-webapp/${jetty.version}/war|webapps/ee10-demo-jaas.war
|
||||
|
||||
[ini]
|
||||
# Enable security via jaas, and configure it
|
||||
|
|
|
@ -24,6 +24,6 @@ ee10-demo-realm
|
|||
|
||||
[files]
|
||||
webapps-ee10/ee10-demo-jetty.d/
|
||||
basehome:modules/demo.d/ee10-demo-jetty.xml|webapps-ee10/ee10-demo-jetty.xml
|
||||
basehome:modules/demo.d/ee10-demo-jetty-override-web.xml|webapps-ee10/ee10-demo-jetty.d/ee10-demo-jetty-override-web.xml
|
||||
maven://org.eclipse.jetty.ee10.demos/ee10-demo-jetty-webapp/${jetty.version}/war|webapps-ee10/ee10-demo-jetty.war
|
||||
basehome:modules/demo.d/ee10-demo-jetty.xml|webapps/ee10-demo-jetty.xml
|
||||
basehome:modules/demo.d/ee10-demo-jetty-override-web.xml|webapps/ee10-demo-jetty.d/ee10-demo-jetty-override-web.xml
|
||||
maven://org.eclipse.jetty.ee10.demos/jetty-ee10-demo-jetty-webapp/${jetty.version}/war|webapps/ee10-demo-jetty.war
|
||||
|
|
|
@ -10,5 +10,5 @@ demo
|
|||
ee10-deploy
|
||||
|
||||
[files]
|
||||
basehome:modules/demo.d/ee10-demo-moved-context.xml|webapps-ee10/ee10-demo-moved-context.xml
|
||||
basehome:modules/demo.d/ee10-demo-moved-context.xml|webapps/ee10-demo-moved-context.xml
|
||||
|
||||
|
|
|
@ -18,6 +18,6 @@ ee10-plus
|
|||
ee10-demo-mock-resources
|
||||
|
||||
[files]
|
||||
basehome:modules/demo.d/ee10-demo-jndi.xml|webapps-ee10/ee10-demo-jndi.xml
|
||||
maven://org.eclipse.jetty.ee10.demos/ee10-demo-jndi-webapp/${jetty.version}/war|webapps-ee10/ee10-demo-jndi.war
|
||||
basehome:modules/demo.d/ee10-demo-jndi.xml|webapps/ee10-demo-jndi.xml
|
||||
maven://org.eclipse.jetty.ee10.demos/jetty-ee10-demo-jndi-webapp/${jetty.version}/war|webapps/ee10-demo-jndi.war
|
||||
maven://jakarta.mail/jakarta.mail-api/2.0.0/jar|lib/ext/jakarta.mail-api-2.0.0.jar
|
||||
|
|
|
@ -14,4 +14,4 @@ ee10-jstl
|
|||
ee10-deploy
|
||||
|
||||
[files]
|
||||
maven://org.eclipse.jetty.ee10.demos/ee10-demo-jsp-webapp/${jetty.version}/war|webapps-ee10/ee10-demo-jsp.war
|
||||
maven://org.eclipse.jetty.ee10.demos/jetty-ee10-demo-jsp-webapp/${jetty.version}/war|webapps/ee10-demo-jsp.war
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Bundle-SymbolicName>org.eclipse.jetty.demos.demo-mock-resources</Bundle-SymbolicName>
|
||||
<Bundle-SymbolicName>org.eclipse.jetty.ee10.demos.demo-mock-resources</Bundle-SymbolicName>
|
||||
<Bundle-Description>Mock resources used for testing</Bundle-Description>
|
||||
<Export-Package>
|
||||
org.example;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}"
|
||||
|
|
|
@ -17,4 +17,4 @@ ee10-annotations
|
|||
lib/ee10-demo-mock-resources-${jetty.version}.jar
|
||||
|
||||
[files]
|
||||
maven://org.eclipse.jetty.ee10.demos/ee10-demo-mock-resources/${jetty.version}/jar|lib/ee10-demo-mock-resources-${jetty.version}.jar
|
||||
maven://org.eclipse.jetty.ee10.demos/jetty-ee10-demo-mock-resources/${jetty.version}/jar|lib/ee10-demo-mock-resources-${jetty.version}.jar
|
||||
|
|
|
@ -14,4 +14,4 @@ webapp
|
|||
ee10-deploy
|
||||
|
||||
[files]
|
||||
maven://org.eclipse.jetty.ee10.demos/ee10-demo-proxy-webapp/${jetty.version}/war|webapps-ee10/ee10-demo-proxy.war
|
||||
maven://org.eclipse.jetty.ee10.demos/jetty-ee10-demo-proxy-webapp/${jetty.version}/war|webapps/ee10-demo-proxy.war
|
||||
|
|
|
@ -12,4 +12,4 @@ webapp
|
|||
ee10-deploy
|
||||
|
||||
[files]
|
||||
maven://org.eclipse.jetty.ee10.demos/ee10-demo-simple-webapp/${jetty.version}/war|webapps-ee10/ee10-demo-simple.war
|
||||
maven://org.eclipse.jetty.ee10.demos/jetty-ee10-demo-simple-webapp/${jetty.version}/war|webapps/ee10-demo-simple.war
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Bundle-SymbolicName>org.eclipse.jetty.demos.demo-servlet-container-initializer;singleton:=true</Bundle-SymbolicName>
|
||||
<Bundle-SymbolicName>org.eclipse.jetty.ee10.demos.demo-servlet-container-initializer;singleton:=true</Bundle-SymbolicName>
|
||||
<Bundle-Description>A bundle containing a ServletContainerInitializer for testing</Bundle-Description>
|
||||
<Require-Capability>osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)"</Require-Capability>
|
||||
<Provide-Capability>osgi.serviceloader; osgi.serviceloader=jakarta.servlet.ServletContainerInitializer</Provide-Capability>
|
||||
|
|
|
@ -20,5 +20,5 @@ ee10-demo-realm
|
|||
ee10-demo-mock-resources
|
||||
|
||||
[files]
|
||||
basehome:modules/demo.d/ee10-demo-spec.xml|webapps-ee10/ee10-demo-spec.xml
|
||||
maven://org.eclipse.jetty.ee10.demos/ee10-demo-spec-webapp/${jetty.version}/war|webapps-ee10/ee10-demo-spec.war
|
||||
basehome:modules/demo.d/ee10-demo-spec.xml|webapps/ee10-demo-spec.xml
|
||||
maven://org.eclipse.jetty.ee10.demos/jetty-ee10-demo-spec-webapp/${jetty.version}/war|webapps/ee10-demo-spec.war
|
||||
|
|
|
@ -350,7 +350,7 @@ public class JettyHomeForker extends AbstractForker
|
|||
modulesPath = Files.createDirectories(targetBasePath.resolve("modules"));
|
||||
etcPath = Files.createDirectories(targetBasePath.resolve("etc"));
|
||||
libPath = Files.createDirectories(targetBasePath.resolve("lib"));
|
||||
webappPath = Files.createDirectories(targetBasePath.resolve("webapps-ee10"));
|
||||
webappPath = Files.createDirectories(targetBasePath.resolve("webapps"));
|
||||
mavenLibPath = Files.createDirectories(libPath.resolve("maven-ee10"));
|
||||
|
||||
//copy in the jetty-maven-plugin jar
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
<Bundle-SymbolicName>${bundle-symbolic-name}</Bundle-SymbolicName>
|
||||
<Bundle-Name>Jetty OSGi Test WebApp Fragment</Bundle-Name>
|
||||
<Bundle-RequiredExecutionEnvironment>J2SE-1.5</Bundle-RequiredExecutionEnvironment>
|
||||
<Fragment-Host>org.eclipse.jetty.demos.spec.webapp</Fragment-Host>
|
||||
<Fragment-Host>org.eclipse.jetty.ee10.demos.spec.webapp</Fragment-Host>
|
||||
<Jetty-WarFragmentResourcePath>/</Jetty-WarFragmentResourcePath>
|
||||
</instructions>
|
||||
</configuration>
|
||||
|
|
|
@ -198,7 +198,6 @@ public class ServletContextHandler extends ContextHandler implements Graceful
|
|||
private final ServletContextApi _servletContext;
|
||||
protected ContextStatus _contextStatus = ContextStatus.NOTSET;
|
||||
private final Map<String, String> _initParams = new HashMap<>();
|
||||
private boolean _contextPathDefault = true;
|
||||
private String _defaultRequestCharacterEncoding;
|
||||
private String _defaultResponseCharacterEncoding;
|
||||
private String _contextPathEncoded = "/";
|
||||
|
@ -655,19 +654,6 @@ public class ServletContextHandler extends ContextHandler implements Graceful
|
|||
.toArray(String[]::new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default context path.
|
||||
* A default context path may be overriden by a default-context-path element
|
||||
* in a web.xml
|
||||
*
|
||||
* @param contextPath The _contextPath to set.
|
||||
*/
|
||||
public void setDefaultContextPath(String contextPath)
|
||||
{
|
||||
setContextPath(contextPath);
|
||||
_contextPathDefault = true;
|
||||
}
|
||||
|
||||
public void setDefaultRequestCharacterEncoding(String encoding)
|
||||
{
|
||||
_defaultRequestCharacterEncoding = encoding;
|
||||
|
@ -688,14 +674,6 @@ public class ServletContextHandler extends ContextHandler implements Graceful
|
|||
return _defaultResponseCharacterEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if the current contextPath is from default settings
|
||||
*/
|
||||
public boolean isContextPathDefault()
|
||||
{
|
||||
return _contextPathDefault;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param contextPath The _contextPath to set.
|
||||
*/
|
||||
|
@ -724,7 +702,6 @@ public class ServletContextHandler extends ContextHandler implements Graceful
|
|||
|
||||
super.setContextPath(contextPath);
|
||||
_contextPathEncoded = URIUtil.encodePath(contextPath);
|
||||
_contextPathDefault = false;
|
||||
|
||||
if (getServer() != null && (getServer().isStarting() || getServer().isStarted()))
|
||||
{
|
||||
|
|
|
@ -102,5 +102,9 @@
|
|||
<artifactId>jetty-client</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-ee</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
@ -21,14 +21,14 @@
|
|||
<Call name="addAppProvider">
|
||||
<Arg>
|
||||
<New id="WebAppProvider" class="org.eclipse.jetty.deploy.providers.ContextProvider">
|
||||
<Set name="defaultEnvironment">ee10</Set>
|
||||
<Set name="environmentName">ee10</Set>
|
||||
<Set name="monitoredDirName">
|
||||
<Call name="resolvePath" class="org.eclipse.jetty.xml.XmlConfiguration">
|
||||
<Arg>
|
||||
<Property name="jetty.base" />
|
||||
</Arg>
|
||||
<Arg>
|
||||
<Property name="jetty.deploy.monitoredDir" default="webapps-ee10" />
|
||||
<Property name="jetty.deploy.monitoredDir" default="webapps" />
|
||||
</Arg>
|
||||
</Call>
|
||||
</Set>
|
||||
|
@ -40,22 +40,28 @@
|
|||
</Default>
|
||||
</Property>
|
||||
</Set>
|
||||
<Set name="scanInterval">
|
||||
<Property name="jetty.deploy.scanInterval" default="1" />
|
||||
</Set>
|
||||
<Set name="extractWars">
|
||||
<Property name="jetty.deploy.extractWars" default="true" />
|
||||
</Set>
|
||||
<Set name="configurationManager">
|
||||
<New class="org.eclipse.jetty.deploy.PropertiesConfigurationManager">
|
||||
<!-- file of context configuration properties
|
||||
<Set name="file"><SystemProperty name="jetty.base"/>/etc/some.properties</Set>
|
||||
-->
|
||||
<!-- set a context configuration property
|
||||
<Call name="put"><Arg>name</Arg><Arg>value</Arg></Call>
|
||||
-->
|
||||
</New>
|
||||
</Set>
|
||||
<Set name="scanInterval" property="jetty.deploy.scanInterval"/>
|
||||
<Set name="defaultsDescriptor" property="jetty.deploy.defaultsDescriptor"/>
|
||||
<Set name="extractWars" property="jetty.deploy.extractWars" />
|
||||
<Set name="parentLoaderPriority" property="jetty.deploy.parentLoaderPriority" />
|
||||
<Set name="configurationClasses" property="jetty.deploy.configurationClasses" />
|
||||
<Set name="tempDir" property="jetty.deploy.tempDir" />
|
||||
<Get name="properties">
|
||||
<Put name="jetty.deploy.containerScanJarPattern">
|
||||
<Property name="jetty.deploy.containerScanJarPattern">
|
||||
<Default>.*jakarta.servlet.jsp.jstl-.*\.jar$</Default>
|
||||
</Property>
|
||||
</Put>
|
||||
<Put name="jetty.deploy.webInfScanJarPattern">
|
||||
<Property name="jetty.deploy.webInfScanJarPattern"/>
|
||||
</Put>
|
||||
<Put name="jetty.deploy.servletContainerInitializerExclusionPattern">
|
||||
<Property name="jetty.deploy.servletContainerInitializerExclusionPattern"/>
|
||||
</Put>
|
||||
<Put name="jetty.deploy.servletContainerInitializerOrder">
|
||||
<Property name="jetty.deploy.servletContainerInitializerOrder"/>
|
||||
</Put>
|
||||
</Get>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
|
|
@ -11,23 +11,44 @@ ee10-webapp
|
|||
[lib]
|
||||
|
||||
[files]
|
||||
webapps-ee10/
|
||||
webapps/
|
||||
|
||||
[xml]
|
||||
etc/jetty-ee10-deploy.xml
|
||||
|
||||
[ini-template]
|
||||
# Monitored directory name (relative to $jetty.base)
|
||||
# jetty.deploy.monitoredDir=webapps-ee10
|
||||
# - OR -
|
||||
# Monitored directory path (fully qualified)
|
||||
# jetty.deploy.monitoredPath=/var/www/webapps-ee10
|
||||
## Monitored directory name (relative to $jetty.base)
|
||||
# jetty.deploy.monitoredDir=webapps
|
||||
## - OR -
|
||||
## Monitored directory path (fully qualified)
|
||||
# jetty.deploy.monitoredPath=/var/www/webapps
|
||||
|
||||
# Defaults Descriptor for all deployed webapps
|
||||
# jetty.deploy.defaultsDescriptorPath=${jetty.base}/etc/webdefault-ee10.xml
|
||||
## Defaults Descriptor for all deployed webapps
|
||||
# jetty.deploy.defaultsDescriptor=${jetty.base}/etc/webdefault-ee10.xml
|
||||
|
||||
# Monitored directory scan period (seconds)
|
||||
## Monitored directory scan period (seconds)
|
||||
# jetty.deploy.scanInterval=1
|
||||
|
||||
# Whether to extract *.war files
|
||||
## Whether to extract *.war files
|
||||
# jetty.deploy.extractWars=true
|
||||
|
||||
## Whether to give the parent classloader priority
|
||||
# jetty.deploy.parentLoaderPriority=true
|
||||
|
||||
## Comma separated list of configuration classes to set.
|
||||
# jetty.deploy.configurationClasses=
|
||||
|
||||
## Base temporary directory for deployed web applications.
|
||||
# jetty.deploy.tempDir=
|
||||
|
||||
## Pattern to select jars from the container classloader to be scanned (or null to scan no jars)
|
||||
# jetty.deploy.containerScanJarPattern=.*jakarta.servlet.jsp.jstl-.*\.jar$
|
||||
|
||||
## Pattern to select jars from the container classloader to be scanned (or null to scan all jars).
|
||||
# jetty.deploy.webInfScanJarPattern=
|
||||
|
||||
## Pattern to exclude discovered ServletContainerInitializers
|
||||
# jetty.deploy.servletContainerInitializerExclusionPattern=
|
||||
|
||||
## Order of discovered ServletContainerInitializers
|
||||
# jetty.deploy.servletContainerInitializerOrder=
|
||||
|
|
|
@ -30,6 +30,7 @@ module org.eclipse.jetty.ee10.webapp
|
|||
requires org.slf4j;
|
||||
|
||||
requires transitive java.instrument;
|
||||
requires transitive org.eclipse.jetty.ee;
|
||||
requires transitive org.eclipse.jetty.session;
|
||||
requires transitive org.eclipse.jetty.ee10.servlet;
|
||||
requires transitive org.eclipse.jetty.xml;
|
||||
|
|
|
@ -36,7 +36,9 @@ import java.util.jar.JarEntry;
|
|||
import java.util.jar.JarFile;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.util.PatternMatcher;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.resource.EmptyResource;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceCollection;
|
||||
|
@ -186,13 +188,19 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
*/
|
||||
public void findAndFilterContainerPaths(final WebAppContext context) throws Exception
|
||||
{
|
||||
String pattern = (String)context.getAttribute(CONTAINER_JAR_PATTERN);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("{}={}", CONTAINER_JAR_PATTERN, pattern);
|
||||
if (StringUtil.isBlank(pattern))
|
||||
return; // TODO review if this short cut will allow later code simplifications
|
||||
|
||||
// Apply an initial name filter to the jars to select which will be eventually
|
||||
// scanned for META-INF info and annotations. The filter is based on inclusion patterns.
|
||||
ContainerPathNameMatcher containerPathNameMatcher = new ContainerPathNameMatcher(context, (String)context.getAttribute(CONTAINER_JAR_PATTERN));
|
||||
ContainerPathNameMatcher containerPathNameMatcher = new ContainerPathNameMatcher(context, pattern);
|
||||
List<URI> containerUris = getAllContainerJars(context);
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Matching container urls {}", containerUris);
|
||||
LOG.debug("All container urls {}", containerUris);
|
||||
containerPathNameMatcher.match(containerUris);
|
||||
|
||||
// When running on jvm 9 or above, we we won't be able to look at the application
|
||||
|
@ -264,9 +272,12 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
throws Exception
|
||||
{
|
||||
//Apply filter to WEB-INF/lib jars
|
||||
WebAppPathNameMatcher matcher = new WebAppPathNameMatcher(context, (String)context.getAttribute(WEBINF_JAR_PATTERN));
|
||||
String pattern = (String)context.getAttribute(WEBINF_JAR_PATTERN);
|
||||
WebAppPathNameMatcher matcher = new WebAppPathNameMatcher(context, pattern);
|
||||
|
||||
List<Resource> jars = findJars(context);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("webapp {}={} jars {}", WEBINF_JAR_PATTERN, pattern, jars);
|
||||
|
||||
//Convert to uris for matching
|
||||
if (jars != null)
|
||||
|
@ -284,23 +295,21 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
protected List<URI> getAllContainerJars(final WebAppContext context) throws URISyntaxException
|
||||
{
|
||||
List<URI> uris = new ArrayList<>();
|
||||
if (context.getClassLoader() != null)
|
||||
{
|
||||
ClassLoader loader = context.getClassLoader().getParent();
|
||||
ClassLoader loader = MetaInfConfiguration.class.getClassLoader();
|
||||
while (loader != null)
|
||||
{
|
||||
if (loader instanceof URLClassLoader)
|
||||
{
|
||||
URL[] urls = ((URLClassLoader)loader).getURLs();
|
||||
if (urls != null)
|
||||
for (URL url : urls)
|
||||
{
|
||||
for (URL url : urls)
|
||||
uris.add(new URI(url.toString().replaceAll(" ", "%20")));
|
||||
}
|
||||
}
|
||||
loader = loader.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
return uris;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,10 +38,10 @@ import jakarta.servlet.http.HttpSessionAttributeListener;
|
|||
import jakarta.servlet.http.HttpSessionBindingListener;
|
||||
import jakarta.servlet.http.HttpSessionIdListener;
|
||||
import jakarta.servlet.http.HttpSessionListener;
|
||||
import org.eclipse.jetty.ee.Deployable;
|
||||
import org.eclipse.jetty.ee10.servlet.ErrorHandler;
|
||||
import org.eclipse.jetty.ee10.servlet.ErrorPageErrorHandler;
|
||||
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.ee10.servlet.ServletContextHandler.ServletContextApi;
|
||||
import org.eclipse.jetty.ee10.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.ee10.servlet.SessionHandler;
|
||||
import org.eclipse.jetty.ee10.servlet.security.ConstraintAware;
|
||||
|
@ -50,8 +50,8 @@ import org.eclipse.jetty.ee10.servlet.security.ConstraintSecurityHandler;
|
|||
import org.eclipse.jetty.ee10.servlet.security.SecurityHandler;
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.util.MultiException;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
|
@ -75,7 +75,7 @@ import org.slf4j.LoggerFactory;
|
|||
*
|
||||
*/
|
||||
@ManagedObject("Web Application ContextHandler")
|
||||
public class WebAppContext extends ServletContextHandler implements WebAppClassLoader.Context
|
||||
public class WebAppContext extends ServletContextHandler implements WebAppClassLoader.Context, Deployable
|
||||
{
|
||||
static final Logger LOG = LoggerFactory.getLogger(WebAppContext.class);
|
||||
|
||||
|
@ -121,6 +121,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
private boolean _logUrlOnStart = false;
|
||||
private boolean _parentLoaderPriority = Boolean.getBoolean("org.eclipse.jetty.server.webapp.parentLoaderPriority");
|
||||
private PermissionCollection _permissions;
|
||||
private boolean _defaultContextPath = true;
|
||||
|
||||
private String[] _contextWhiteList = null;
|
||||
|
||||
|
@ -228,6 +229,55 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
setParent(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeDefaults(Map<String, String> properties)
|
||||
{
|
||||
for (String property : properties.keySet())
|
||||
{
|
||||
String value = properties.get(property);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("init {}: {}", property, value);
|
||||
|
||||
switch (property)
|
||||
{
|
||||
case Deployable.WAR -> setWar(value);
|
||||
case Deployable.BASE_TEMP_DIR -> setAttribute(BASETEMPDIR, value);
|
||||
case Deployable.CONFIGURATION_CLASSES -> setConfigurationClasses(value == null ? null : value.split(","));
|
||||
case Deployable.CONTAINER_SCAN_JARS -> setAttribute(MetaInfConfiguration.CONTAINER_JAR_PATTERN, value);
|
||||
case Deployable.EXTRACT_WARS -> setExtractWAR(Boolean.parseBoolean(value));
|
||||
case Deployable.PARENT_LOADER_PRIORITY -> setParentLoaderPriority(Boolean.parseBoolean(value));
|
||||
case Deployable.WEBINF_SCAN_JARS -> setAttribute(MetaInfConfiguration.WEBINF_JAR_PATTERN, value);
|
||||
case Deployable.DEFAULTS_DESCRIPTOR -> setDefaultsDescriptor(value);
|
||||
case Deployable.SCI_EXCLUSION_PATTERN -> setAttribute("org.eclipse.jetty.containerInitializerExclusionPattern", value);
|
||||
case Deployable.SCI_ORDER -> setAttribute("org.eclipse.jetty.containerInitializerOrder", value);
|
||||
default ->
|
||||
{
|
||||
if (LOG.isDebugEnabled() && StringUtil.isNotBlank(value))
|
||||
LOG.debug("unknown property {}={}", property, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
_defaultContextPath = true;
|
||||
}
|
||||
|
||||
public boolean isContextPathDefault()
|
||||
{
|
||||
return _defaultContextPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContextPath(String contextPath)
|
||||
{
|
||||
super.setContextPath(contextPath);
|
||||
_defaultContextPath = false;
|
||||
}
|
||||
|
||||
public void setDefaultContextPath(String contextPath)
|
||||
{
|
||||
super.setContextPath(contextPath);
|
||||
_defaultContextPath = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param servletContextName The servletContextName to set.
|
||||
*/
|
||||
|
|
|
@ -134,16 +134,17 @@ public class MetaInfConfigurationTest
|
|||
{
|
||||
MetaInfConfiguration config = new MetaInfConfiguration();
|
||||
WebAppContext context = new WebAppContext();
|
||||
context.setAttribute(MetaInfConfiguration.CONTAINER_JAR_PATTERN, ".*/jetty-util-[^/]*\\.jar$|.*/jetty-util/target/classes/$|.*/foo-bar-janb.jar");
|
||||
context.setAttribute(MetaInfConfiguration.CONTAINER_JAR_PATTERN, ".*servlet-api-[^/]*\\.jar$|.*/foo-bar-janb.jar");
|
||||
WebAppClassLoader loader = new WebAppClassLoader(context);
|
||||
context.setClassLoader(loader);
|
||||
config.findAndFilterContainerPaths(context);
|
||||
List<Resource> containerResources = context.getMetaData().getContainerResources();
|
||||
|
||||
assertEquals(2, containerResources.size());
|
||||
for (Resource r : containerResources)
|
||||
{
|
||||
String s = r.toString();
|
||||
assertTrue(s.endsWith("foo-bar-janb.jar") || s.contains("jetty-util"));
|
||||
assertTrue(s.endsWith("foo-bar-janb.jar") || s.contains("servlet-api"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-io</artifactId>
|
||||
<artifactId>jetty-ee</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
|
|
|
@ -21,41 +21,39 @@
|
|||
<Call name="addAppProvider">
|
||||
<Arg>
|
||||
<New id="WebAppProvider" class="org.eclipse.jetty.deploy.providers.ContextProvider">
|
||||
<Set name="defaultEnvironment">ee8</Set>
|
||||
<Set name="EnvironmentName">ee8</Set>
|
||||
<Set name="monitoredDirName">
|
||||
<Call name="resolvePath" class="org.eclipse.jetty.xml.XmlConfiguration">
|
||||
<Arg>
|
||||
<Property name="jetty.base" />
|
||||
</Arg>
|
||||
<Arg>
|
||||
<Property name="jetty.deploy.monitoredDir" default="webapps-ee8" />
|
||||
<Property name="jetty.deploy.monitoredDir" default="webapps" />
|
||||
</Arg>
|
||||
</Call>
|
||||
</Set>
|
||||
<Set name="defaultsDescriptor">
|
||||
<Property>
|
||||
<Name>jetty.deploy.defaultsDescriptorPath</Name>
|
||||
<Default>
|
||||
<Property name="jetty.home" default="." />/etc/webdefault-ee8.xml
|
||||
</Default>
|
||||
<Set name="scanInterval" property="jetty.deploy.scanInterval"/>
|
||||
<Set name="defaultsDescriptor" property="jetty.deploy.defaultsDescriptor"/>
|
||||
<Set name="extractWars" property="jetty.deploy.extractWars" />
|
||||
<Set name="parentLoaderPriority" property="jetty.deploy.parentLoaderPriority" />
|
||||
<Set name="configurationClasses" property="jetty.deploy.configurationClasses" />
|
||||
<Set name="tempDir" property="jetty.deploy.tempDir" />
|
||||
<Get name="properties">
|
||||
<Put name="jetty.deploy.containerScanJarPattern">
|
||||
<Property name="jetty.deploy.containerScanJarPattern">
|
||||
<Default>.*jakarta.servlet.jsp.jstl-.*\.jar$</Default>
|
||||
</Property>
|
||||
</Set>
|
||||
<Set name="scanInterval">
|
||||
<Property name="jetty.deploy.scanInterval" default="1" />
|
||||
</Set>
|
||||
<Set name="extractWars">
|
||||
<Property name="jetty.deploy.extractWars" default="true" />
|
||||
</Set>
|
||||
<Set name="configurationManager">
|
||||
<New class="org.eclipse.jetty.deploy.PropertiesConfigurationManager">
|
||||
<!-- file of context configuration properties
|
||||
<Set name="file"><SystemProperty name="jetty.base"/>/etc/some.properties</Set>
|
||||
-->
|
||||
<!-- set a context configuration property
|
||||
<Call name="put"><Arg>name</Arg><Arg>value</Arg></Call>
|
||||
-->
|
||||
</New>
|
||||
</Set>
|
||||
</Put>
|
||||
<Put name="jetty.deploy.webInfScanJarPattern">
|
||||
<Property name="jetty.deploy.webInfScanJarPattern"/>
|
||||
</Put>
|
||||
<Put name="jetty.deploy.servletContainerInitializerExclusionPattern">
|
||||
<Property name="jetty.deploy.servletContainerInitializerExclusionPattern"/>
|
||||
</Put>
|
||||
<Put name="jetty.deploy.servletContainerInitializerOrder">
|
||||
<Property name="jetty.deploy.servletContainerInitializerOrder"/>
|
||||
</Put>
|
||||
</Get>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
|
|
@ -11,23 +11,44 @@ ee8-webapp
|
|||
[lib]
|
||||
|
||||
[files]
|
||||
webapps-ee8/
|
||||
webapps/
|
||||
|
||||
[xml]
|
||||
etc/jetty-ee8-deploy.xml
|
||||
|
||||
[ini-template]
|
||||
# Monitored directory name (relative to $jetty.base)
|
||||
# jetty.deploy.monitoredDir=webapps-ee8
|
||||
# - OR -
|
||||
# Monitored directory path (fully qualified)
|
||||
# jetty.deploy.monitoredPath=/var/www/webapps-ee8
|
||||
## Monitored directory name (relative to $jetty.base)
|
||||
# jetty.deploy.monitoredDir=webapps
|
||||
## - OR -
|
||||
## Monitored directory path (fully qualified)
|
||||
# jetty.deploy.monitoredPath=/var/www/webapps
|
||||
|
||||
# Defaults Descriptor for all deployed webapps
|
||||
# jetty.deploy.defaultsDescriptorPath=${jetty.base}/etc/webdefault-ee8.xml
|
||||
## Defaults Descriptor for all deployed webapps
|
||||
# jetty.deploy.defaultsDescriptor=${jetty.base}/etc/webdefault-ee8.xml
|
||||
|
||||
# Monitored directory scan period (seconds)
|
||||
## Monitored directory scan period (seconds)
|
||||
# jetty.deploy.scanInterval=1
|
||||
|
||||
# Whether to extract *.war files
|
||||
## Whether to extract *.war files
|
||||
# jetty.deploy.extractWars=true
|
||||
|
||||
## Whether to give the parent classloader priority
|
||||
# jetty.deploy.parentLoaderPriority=true
|
||||
|
||||
## Comma separated list of configuration classes to set.
|
||||
# jetty.deploy.configurationClasses=
|
||||
|
||||
## Base temporary directory for deployed web applications.
|
||||
# jetty.deploy.tempDir=
|
||||
|
||||
## Pattern to select jars from the container classloader to be scanned (or null to scan no jars)
|
||||
# jetty.deploy.containerScanJarPattern=.*jakarta.servlet.jsp.jstl-.*\.jar$
|
||||
|
||||
## Pattern to select jars from the container classloader to be scanned (or null to scan all jars).
|
||||
# jetty.deploy.webInfScanJarPattern=
|
||||
|
||||
## Pattern to exclude discovered ServletContainerInitializers
|
||||
# jetty.deploy.servletContainerInitializerExclusionPattern=
|
||||
|
||||
## Order of discovered ServletContainerInitializers
|
||||
# jetty.deploy.servletContainerInitializerOrder=
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<servlet>
|
||||
<display-name>SerialRestServlet</display-name>
|
||||
<servlet-name>SerialRestServlet</servlet-name>
|
||||
<servlet-class>org.eclipse.jetty.demos.SerialRestServlet</servlet-class>
|
||||
<servlet-class>org.eclipse.jetty.ee9.demosSerialRestServlet</servlet-class>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>SerialRestServlet</servlet-name>
|
||||
|
@ -18,7 +18,7 @@
|
|||
<servlet>
|
||||
<display-name>AsyncRestServlet</display-name>
|
||||
<servlet-name>AsyncRestServlet</servlet-name>
|
||||
<servlet-class>org.eclipse.jetty.demos.AsyncRestServlet</servlet-class>
|
||||
<servlet-class>org.eclipse.jetty.ee9.demosAsyncRestServlet</servlet-class>
|
||||
<async-supported>true</async-supported>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
environment: ee9
|
|
@ -14,5 +14,5 @@ webapp
|
|||
ee9-deploy
|
||||
|
||||
[files]
|
||||
maven://org.eclipse.jetty.ee9.demos/ee9-demo-async-rest-webapp/${jetty.version}/war|webapps-ee9/ee9-demo-async-rest.war
|
||||
|
||||
basehome:modules/demo.d/ee9-demo-async-rest.properties|webapps/ee9-demo-async-rest.properties
|
||||
maven://org.eclipse.jetty.ee9.demos/jetty-ee9-demo-async-rest-webapp/${jetty.version}/war|webapps/ee9-demo-async-rest.war
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<New id="context" class="org.eclipse.jetty.ee9.servlet.ServletContextHandler">
|
||||
<Set name="contextPath">/hello</Set>
|
||||
<Call name="addServlet">
|
||||
<Arg>org.eclipse.jetty.demos.HelloServlet</Arg>
|
||||
<Arg>org.eclipse.jetty.ee9.demos.HelloServlet</Arg>
|
||||
<Arg>/</Arg>
|
||||
</Call>
|
||||
</New>
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
environment: ee9
|
|
@ -19,10 +19,11 @@ ee9-annotations
|
|||
ext
|
||||
|
||||
[files]
|
||||
basehome:modules/demo.d/ee9-demo-jaas.xml|webapps-ee9/ee9-demo-jaas.xml
|
||||
basehome:modules/demo.d/ee9-demo-jaas.xml|webapps/ee9-demo-jaas.xml
|
||||
basehome:modules/demo.d/ee9-demo-jaas.properties|webapps/ee9-demo-jaas.properties
|
||||
basehome:modules/demo.d/ee9-demo-login.conf|etc/ee9-demo-login.conf
|
||||
basehome:modules/demo.d/ee9-demo-login.properties|etc/ee9-demo-login.properties
|
||||
maven://org.eclipse.jetty.ee9.demos/ee9-demo-jaas-webapp/${jetty.version}/war|webapps-ee9/ee9-demo-jaas.war
|
||||
maven://org.eclipse.jetty.ee9.demos/jetty-ee9-demo-jaas-webapp/${jetty.version}/war|webapps/ee9-demo-jaas.war
|
||||
|
||||
[ini]
|
||||
# Enable security via jaas, and configure it
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
environment: ee9
|
|
@ -24,6 +24,7 @@ ee9-demo-realm
|
|||
|
||||
[files]
|
||||
webapps-ee9/demo-jetty.d/
|
||||
basehome:modules/demo.d/ee9-demo-jetty.xml|webapps-ee9/ee9-demo-jetty.xml
|
||||
basehome:modules/demo.d/ee9-demo-jetty-override-web.xml|webapps-ee9/ee9-demo-jetty.d/ee9-demo-jetty-override-web.xml
|
||||
maven://org.eclipse.jetty.ee9.demos/ee9-demo-jetty-webapp/${jetty.version}/war|webapps-ee9/ee9-demo-jetty.war
|
||||
basehome:modules/demo.d/ee9-demo-jetty.xml|webapps/ee9-demo-jetty.xml
|
||||
basehome:modules/demo.d/ee9-demo-jetty-override-web.xml|webapps/ee9-demo-jetty.d/ee9-demo-jetty-override-web.xml
|
||||
basehome:modules/demo.d/ee9-demo-jetty.properties|webapps/ee9-demo-jetty.properties
|
||||
maven://org.eclipse.jetty.ee9.demos/jetty-ee9-demo-jetty-webapp/${jetty.version}/war|webapps/ee9-demo-jetty.war
|
||||
|
|
|
@ -13,5 +13,5 @@ demo
|
|||
ee9-deploy
|
||||
|
||||
[files]
|
||||
basehome:modules/demo.d/ee9-demo-moved-context.xml|webapps-ee9/ee9-demo-moved-context.xml
|
||||
basehome:modules/demo.d/ee9-demo-moved-context.xml|webapps/ee9-demo-moved-context.xml
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
environment: ee9
|
|
@ -18,6 +18,7 @@ ee9-plus
|
|||
ee9-demo-mock-resources
|
||||
|
||||
[files]
|
||||
basehome:modules/demo.d/ee9-demo-jndi.xml|webapps-ee9/ee9-demo-jndi.xml
|
||||
maven://org.eclipse.jetty.ee9.demos/ee9-demo-jndi-webapp/${jetty.version}/war|webapps-ee9/ee9-demo-jndi.war
|
||||
basehome:modules/demo.d/ee9-demo-jndi.xml|webapps/ee9-demo-jndi.xml
|
||||
basehome:modules/demo.d/ee9-demo-jndi.properties|webapps/ee9-demo-jndi.properties
|
||||
maven://org.eclipse.jetty.ee9.demos/jetty-ee9-demo-jndi-webapp/${jetty.version}/war|webapps/ee9-demo-jndi.war
|
||||
maven://jakarta.mail/jakarta.mail-api/2.0.0/jar|lib/ext/jakarta.mail-api-2.0.0.jar
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
environment: ee9
|
|
@ -14,4 +14,5 @@ jstl
|
|||
ee9-deploy
|
||||
|
||||
[files]
|
||||
maven://org.eclipse.jetty.ee9.demos/ee9-demo-jsp-webapp/${jetty.version}/war|webapps-ee9/ee9-demo-jsp.war
|
||||
basehome:modules/demo.d/ee9-demo-jsp.properties|webapps/ee9-demo-jsp.properties
|
||||
maven://org.eclipse.jetty.ee9.demos/jetty-ee9-demo-jsp-webapp/${jetty.version}/war|webapps/ee9-demo-jsp.war
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</goals>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Bundle-SymbolicName>org.eclipse.jetty.demos.ee9-demo-mock-resources</Bundle-SymbolicName>
|
||||
<Bundle-SymbolicName>org.eclipse.jetty.ee9.demos.ee9-demo-mock-resources</Bundle-SymbolicName>
|
||||
<Bundle-Description>Mock resources used for testing</Bundle-Description>
|
||||
<Export-Package>
|
||||
org.example;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}"
|
||||
|
|
|
@ -14,4 +14,4 @@ jdbc
|
|||
ee9-annotations
|
||||
|
||||
[files]
|
||||
maven://org.eclipse.jetty.ee9.demos/ee9-demo-mock-resources/${jetty.version}/jar|lib/ext/ee9-demo-mock-resources-${jetty.version}.jar
|
||||
maven://org.eclipse.jetty.ee9.demos/jetty-ee9-demo-mock-resources/${jetty.version}/jar|lib/ext/ee9-demo-mock-resources-${jetty.version}.jar
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
environment: ee9
|
|
@ -14,4 +14,5 @@ webapp
|
|||
ee9-deploy
|
||||
|
||||
[files]
|
||||
maven://org.eclipse.jetty.ee9.demos/ee9-demo-proxy-webapp/${jetty.version}/war|webapps-ee9/ee9-demo-proxy.war
|
||||
basehome:modules/demo.d/ee9-demo-proxy.properties|webapps/ee9-demo-proxy.properties
|
||||
maven://org.eclipse.jetty.ee9.demos/jetty-ee9-demo-proxy-webapp/${jetty.version}/war|webapps/ee9-demo-proxy.war
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
environment: ee9
|
|
@ -12,4 +12,5 @@ webapp
|
|||
ee9-deploy
|
||||
|
||||
[files]
|
||||
maven://org.eclipse.jetty.ee9.demos/ee9-demo-simple-webapp/${jetty.version}/war|webapps-ee9/ee9-demo-simple.war
|
||||
basehome:modules/demo.d/ee9-demo-simple.properties|webapps/ee9-demo-simple.properties
|
||||
maven://org.eclipse.jetty.ee9.demos/jetty-ee9-demo-simple-webapp/${jetty.version}/war|webapps/ee9-demo-simple.war
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Bundle-SymbolicName>org.eclipse.jetty.demos.ee9-demo-servlet-container-initializer;singleton:=true</Bundle-SymbolicName>
|
||||
<Bundle-SymbolicName>org.eclipse.jetty.ee9.demos.ee9-demo-servlet-container-initializer;singleton:=true</Bundle-SymbolicName>
|
||||
<Bundle-Description>A bundle containing a ServletContainerInitializer for testing</Bundle-Description>
|
||||
<Require-Capability>osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)"</Require-Capability>
|
||||
<Provide-Capability>osgi.serviceloader; osgi.serviceloader=jakarta.servlet.ServletContainerInitializer</Provide-Capability>
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
environment: ee9
|
|
@ -20,5 +20,6 @@ ee9-demo-realm
|
|||
ee9-demo-mock-resources
|
||||
|
||||
[files]
|
||||
basehome:modules/demo.d/ee9-demo-spec.xml|webapps-ee9/ee9-demo-spec.xml
|
||||
maven://org.eclipse.jetty.ee9.demos/ee9-demo-spec-webapp/${jetty.version}/war|webapps-ee9/ee9-demo-spec.war
|
||||
basehome:modules/demo.d/ee9-demo-spec.xml|webapps/ee9-demo-spec.xml
|
||||
basehome:modules/demo.d/ee9-demo-spec.properties|webapps/ee9-demo-spec.properties
|
||||
maven://org.eclipse.jetty.ee9.demos/jetty-ee9-demo-spec-webapp/${jetty.version}/war|webapps/ee9-demo-spec.war
|
||||
|
|
|
@ -350,7 +350,7 @@ public class JettyHomeForker extends AbstractForker
|
|||
modulesPath = Files.createDirectories(targetBasePath.resolve("modules"));
|
||||
etcPath = Files.createDirectories(targetBasePath.resolve("etc"));
|
||||
libPath = Files.createDirectories(targetBasePath.resolve("lib"));
|
||||
webappPath = Files.createDirectories(targetBasePath.resolve("webapps-ee9"));
|
||||
webappPath = Files.createDirectories(targetBasePath.resolve("webapps"));
|
||||
mavenLibPath = Files.createDirectories(libPath.resolve("maven-ee9"));
|
||||
|
||||
//copy in the jetty-maven-plugin jar
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-io</artifactId>
|
||||
<artifactId>jetty-ee</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
module org.eclipse.jetty.ee9.nested
|
||||
{
|
||||
requires transitive jetty.servlet.api;
|
||||
requires transitive org.eclipse.jetty.ee;
|
||||
requires transitive org.eclipse.jetty.http;
|
||||
requires transitive org.eclipse.jetty.server;
|
||||
requires transitive org.eclipse.jetty.session;
|
||||
|
|
|
@ -198,7 +198,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
|||
protected ContextStatus _contextStatus = ContextStatus.NOTSET;
|
||||
protected APIContext _apiContext;
|
||||
private final Map<String, String> _initParams;
|
||||
private boolean _contextPathDefault = true;
|
||||
private String _defaultRequestCharacterEncoding;
|
||||
private String _defaultResponseCharacterEncoding;
|
||||
private String _contextPathEncoded = "/";
|
||||
|
@ -1065,19 +1064,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
|||
_coreContextHandler.setClassLoader(classLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default context path.
|
||||
* A default context path may be overriden by a default-context-path element
|
||||
* in a web.xml
|
||||
*
|
||||
* @param contextPath The _contextPath to set.
|
||||
*/
|
||||
public void setDefaultContextPath(String contextPath)
|
||||
{
|
||||
setContextPath(contextPath);
|
||||
_contextPathDefault = true;
|
||||
}
|
||||
|
||||
public void setDefaultRequestCharacterEncoding(String encoding)
|
||||
{
|
||||
_defaultRequestCharacterEncoding = encoding;
|
||||
|
@ -1098,14 +1084,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
|||
return _defaultResponseCharacterEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if the current contextPath is from default settings
|
||||
*/
|
||||
public boolean isContextPathDefault()
|
||||
{
|
||||
return _contextPathDefault;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param contextPath The _contextPath to set.
|
||||
*/
|
||||
|
@ -1133,7 +1111,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
|||
|
||||
_coreContextHandler.setContextPath(contextPath);
|
||||
_contextPathEncoded = URIUtil.encodePath(contextPath);
|
||||
_contextPathDefault = false;
|
||||
|
||||
// update context mappings
|
||||
if (getServer() != null && getServer().isRunning())
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
<Bundle-SymbolicName>${bundle-symbolic-name}</Bundle-SymbolicName>
|
||||
<Bundle-Name>Jetty OSGi Test WebApp Fragment</Bundle-Name>
|
||||
<Bundle-RequiredExecutionEnvironment>J2SE-1.5</Bundle-RequiredExecutionEnvironment>
|
||||
<Fragment-Host>org.eclipse.jetty.demos.spec.webapp</Fragment-Host>
|
||||
<Fragment-Host>org.eclipse.jetty.ee9.demos.spec.webapp</Fragment-Host>
|
||||
<Jetty-WarFragmentResourcePath>/</Jetty-WarFragmentResourcePath>
|
||||
</instructions>
|
||||
</configuration>
|
||||
|
|
|
@ -21,41 +21,39 @@
|
|||
<Call name="addAppProvider">
|
||||
<Arg>
|
||||
<New id="WebAppProvider" class="org.eclipse.jetty.deploy.providers.ContextProvider">
|
||||
<Set name="defaultEnvironment">ee9</Set>
|
||||
<Set name="EnvironmentName">ee9</Set>
|
||||
<Set name="monitoredDirName">
|
||||
<Call name="resolvePath" class="org.eclipse.jetty.xml.XmlConfiguration">
|
||||
<Arg>
|
||||
<Property name="jetty.base" />
|
||||
</Arg>
|
||||
<Arg>
|
||||
<Property name="jetty.deploy.monitoredDir" default="webapps-ee9" />
|
||||
<Property name="jetty.deploy.monitoredDir" default="webapps" />
|
||||
</Arg>
|
||||
</Call>
|
||||
</Set>
|
||||
<Set name="defaultsDescriptor">
|
||||
<Property>
|
||||
<Name>jetty.deploy.defaultsDescriptorPath</Name>
|
||||
<Default>
|
||||
<Property name="jetty.home" default="." />/etc/webdefault-ee9.xml
|
||||
</Default>
|
||||
<Set name="scanInterval" property="jetty.deploy.scanInterval"/>
|
||||
<Set name="defaultsDescriptor" property="jetty.deploy.defaultsDescriptor"/>
|
||||
<Set name="extractWars" property="jetty.deploy.extractWars" />
|
||||
<Set name="parentLoaderPriority" property="jetty.deploy.parentLoaderPriority" />
|
||||
<Set name="configurationClasses" property="jetty.deploy.configurationClasses" />
|
||||
<Set name="tempDir" property="jetty.deploy.tempDir" />
|
||||
<Get name="properties">
|
||||
<Put name="jetty.deploy.containerScanJarPattern">
|
||||
<Property name="jetty.deploy.containerScanJarPattern">
|
||||
<Default>.*jakarta.servlet.jsp.jstl-.*\.jar$</Default>
|
||||
</Property>
|
||||
</Set>
|
||||
<Set name="scanInterval">
|
||||
<Property name="jetty.deploy.scanInterval" default="1" />
|
||||
</Set>
|
||||
<Set name="extractWars">
|
||||
<Property name="jetty.deploy.extractWars" default="true" />
|
||||
</Set>
|
||||
<Set name="configurationManager">
|
||||
<New class="org.eclipse.jetty.deploy.PropertiesConfigurationManager">
|
||||
<!-- file of context configuration properties
|
||||
<Set name="file"><SystemProperty name="jetty.base"/>/etc/some.properties</Set>
|
||||
-->
|
||||
<!-- set a context configuration property
|
||||
<Call name="put"><Arg>name</Arg><Arg>value</Arg></Call>
|
||||
-->
|
||||
</New>
|
||||
</Set>
|
||||
</Put>
|
||||
<Put name="jetty.deploy.webInfScanJarPattern">
|
||||
<Property name="jetty.deploy.webInfScanJarPattern"/>
|
||||
</Put>
|
||||
<Put name="jetty.deploy.servletContainerInitializerExclusionPattern">
|
||||
<Property name="jetty.deploy.servletContainerInitializerExclusionPattern"/>
|
||||
</Put>
|
||||
<Put name="jetty.deploy.servletContainerInitializerOrder">
|
||||
<Property name="jetty.deploy.servletContainerInitializerOrder"/>
|
||||
</Put>
|
||||
</Get>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
|
|
@ -11,23 +11,44 @@ ee9-webapp
|
|||
[lib]
|
||||
|
||||
[files]
|
||||
webapps-ee9/
|
||||
webapps/
|
||||
|
||||
[xml]
|
||||
etc/jetty-ee9-deploy.xml
|
||||
|
||||
[ini-template]
|
||||
# Monitored directory name (relative to $jetty.base)
|
||||
# jetty.deploy.monitoredDir=webapps-ee9
|
||||
# - OR -
|
||||
# Monitored directory path (fully qualified)
|
||||
# jetty.deploy.monitoredPath=/var/www/webapps-ee9
|
||||
## Monitored directory name (relative to $jetty.base)
|
||||
# jetty.deploy.monitoredDir=webapps
|
||||
## - OR -
|
||||
## Monitored directory path (fully qualified)
|
||||
# jetty.deploy.monitoredPath=/var/www/webapps
|
||||
|
||||
# Defaults Descriptor for all deployed webapps
|
||||
# jetty.deploy.defaultsDescriptorPath=${jetty.base}/etc/webdefault-ee9.xml
|
||||
## Defaults Descriptor for all deployed webapps
|
||||
# jetty.deploy.defaultsDescriptor=${jetty.base}/etc/webdefault-ee9.xml
|
||||
|
||||
# Monitored directory scan period (seconds)
|
||||
## Monitored directory scan period (seconds)
|
||||
# jetty.deploy.scanInterval=1
|
||||
|
||||
# Whether to extract *.war files
|
||||
## Whether to extract *.war files
|
||||
# jetty.deploy.extractWars=true
|
||||
|
||||
## Whether to give the parent classloader priority
|
||||
# jetty.deploy.parentLoaderPriority=true
|
||||
|
||||
## Comma separated list of configuration classes to set.
|
||||
# jetty.deploy.configurationClasses=
|
||||
|
||||
## Base temporary directory for deployed web applications.
|
||||
# jetty.deploy.tempDir=
|
||||
|
||||
## Pattern to select jars from the container classloader to be scanned (or null to scan no jars)
|
||||
# jetty.deploy.containerScanJarPattern=.*jakarta.servlet.jsp.jstl-.*\.jar$
|
||||
|
||||
## Pattern to select jars from the container classloader to be scanned (or null to scan all jars).
|
||||
# jetty.deploy.webInfScanJarPattern=
|
||||
|
||||
## Pattern to exclude discovered ServletContainerInitializers
|
||||
# jetty.deploy.servletContainerInitializerExclusionPattern=
|
||||
|
||||
## Order of discovered ServletContainerInitializers
|
||||
# jetty.deploy.servletContainerInitializerOrder=
|
||||
|
|
|
@ -36,7 +36,9 @@ import java.util.jar.JarEntry;
|
|||
import java.util.jar.JarFile;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.util.PatternMatcher;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.resource.EmptyResource;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceCollection;
|
||||
|
@ -186,9 +188,13 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
*/
|
||||
public void findAndFilterContainerPaths(final WebAppContext context) throws Exception
|
||||
{
|
||||
String pattern = (String)context.getAttribute(CONTAINER_JAR_PATTERN);
|
||||
if (StringUtil.isBlank(pattern))
|
||||
return; // TODO review if this short cut will allow later code simplifications
|
||||
|
||||
// Apply an initial name filter to the jars to select which will be eventually
|
||||
// scanned for META-INF info and annotations. The filter is based on inclusion patterns.
|
||||
ContainerPathNameMatcher containerPathNameMatcher = new ContainerPathNameMatcher(context, (String)context.getAttribute(CONTAINER_JAR_PATTERN));
|
||||
ContainerPathNameMatcher containerPathNameMatcher = new ContainerPathNameMatcher(context, pattern);
|
||||
List<URI> containerUris = getAllContainerJars(context);
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
|
@ -284,23 +290,20 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
protected List<URI> getAllContainerJars(final WebAppContext context) throws URISyntaxException
|
||||
{
|
||||
List<URI> uris = new ArrayList<>();
|
||||
if (context.getClassLoader() != null)
|
||||
{
|
||||
ClassLoader loader = context.getClassLoader().getParent();
|
||||
ClassLoader loader = MetaInfConfiguration.class.getClassLoader();
|
||||
while (loader != null)
|
||||
{
|
||||
if (loader instanceof URLClassLoader)
|
||||
{
|
||||
URL[] urls = ((URLClassLoader)loader).getURLs();
|
||||
if (urls != null)
|
||||
for (URL url : urls)
|
||||
{
|
||||
for (URL url : urls)
|
||||
uris.add(new URI(url.toString().replaceAll(" ", "%20")));
|
||||
}
|
||||
}
|
||||
loader = loader.getParent();
|
||||
}
|
||||
}
|
||||
return uris;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,10 +38,9 @@ import jakarta.servlet.http.HttpSessionAttributeListener;
|
|||
import jakarta.servlet.http.HttpSessionBindingListener;
|
||||
import jakarta.servlet.http.HttpSessionIdListener;
|
||||
import jakarta.servlet.http.HttpSessionListener;
|
||||
import org.eclipse.jetty.ee9.nested.AbstractHandler;
|
||||
import org.eclipse.jetty.ee.Deployable;
|
||||
import org.eclipse.jetty.ee9.nested.ContextHandler;
|
||||
import org.eclipse.jetty.ee9.nested.ErrorHandler;
|
||||
import org.eclipse.jetty.ee9.nested.ManagedAttributeListener;
|
||||
import org.eclipse.jetty.ee9.nested.SessionHandler;
|
||||
import org.eclipse.jetty.ee9.security.ConstraintAware;
|
||||
import org.eclipse.jetty.ee9.security.ConstraintMapping;
|
||||
|
@ -50,13 +49,12 @@ import org.eclipse.jetty.ee9.security.SecurityHandler;
|
|||
import org.eclipse.jetty.ee9.servlet.ErrorPageErrorHandler;
|
||||
import org.eclipse.jetty.ee9.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.ee9.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.http.MimeTypes;
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.util.Attributes;
|
||||
import org.eclipse.jetty.util.MultiException;
|
||||
import org.eclipse.jetty.util.TopologicalSort;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
|
@ -79,76 +77,9 @@ import org.slf4j.LoggerFactory;
|
|||
* the default being {@link WebXmlConfiguration} and
|
||||
* {@link JettyWebXmlConfiguration}.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* The Start/Configuration of a WebAppContext is rather complex so as to allow
|
||||
* pluggable behaviour to be added in almost arbitrary ordering. The
|
||||
* sequence of a WebappContext start is as follows:
|
||||
* <blockquote>
|
||||
* {@link #doStart()}:
|
||||
* <ul>
|
||||
* <li>{@link #preConfigure()}
|
||||
* <ul>
|
||||
* <li>Add all Server class inclusions from all known configurations {@link Configurations#getKnown()}</li>
|
||||
* <li>{@link #loadConfigurations()}, which uses either explicitly set Configurations or takes the server
|
||||
* default (which is all known {@link Configuration#isEnabledByDefault()} Configurations.</li>
|
||||
* <li>Sort the configurations using {@link TopologicalSort} in {@link Configurations#sort()}.</li>
|
||||
* <li>Add all Server class exclusions from this webapps {@link Configurations}</li>
|
||||
* <li>Add all System classes inclusions and exclusions for this webapps {@link Configurations}</li>
|
||||
* <li>Instantiate the WebAppClassLoader (if one not already explicitly set)</li>
|
||||
* <li>{@link Configuration#preConfigure(WebAppContext)} which calls
|
||||
* {@link Configuration#preConfigure(WebAppContext)} for this webapps {@link Configurations}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>{@link ServletContextHandler#doStart()}
|
||||
* <ul>
|
||||
* <li>{@link ContextHandler#doStart()}
|
||||
* <ul>
|
||||
* <li>Init {@link MimeTypes}</li>
|
||||
* <li>enterScope
|
||||
* <ul>
|
||||
* <li>{@link #startContext()}
|
||||
* <ul>
|
||||
* <li>{@link #configure()}
|
||||
* <ul>
|
||||
* <li>Call {@link Configuration#configure(WebAppContext)} on enabled {@link Configurations}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>{@link MetaData#resolve(WebAppContext)}</li>
|
||||
* <li>{@link #startContext()}
|
||||
* <li>QuickStart may generate here and/or abort start
|
||||
* <ul>
|
||||
* <li>{@link ServletContextHandler#startContext}
|
||||
* <ul>
|
||||
* <li>Decorate listeners</li>
|
||||
* <li>{@link ContextHandler#startContext}
|
||||
* <ul>
|
||||
* <li>add {@link ManagedAttributeListener}</li>
|
||||
* <li>{@link AbstractHandler#doStart}</li>
|
||||
* <li>{@link #callContextInitialized(jakarta.servlet.ServletContextListener, jakarta.servlet.ServletContextEvent)}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>{@link ServletHandler#initialize()}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>exitScope</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>{@link #postConfigure()}</li>
|
||||
* </ul>
|
||||
*
|
||||
* </blockquote>
|
||||
*/
|
||||
@ManagedObject("Web Application ContextHandler")
|
||||
public class WebAppContext extends ServletContextHandler implements WebAppClassLoader.Context
|
||||
public class WebAppContext extends ServletContextHandler implements WebAppClassLoader.Context, Deployable
|
||||
{
|
||||
static final Logger LOG = LoggerFactory.getLogger(WebAppContext.class);
|
||||
|
||||
|
@ -211,6 +142,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
private boolean _throwUnavailableOnStartupException = false;
|
||||
|
||||
private MetaData _metadata = new MetaData();
|
||||
private boolean _defaultContextPath = true;
|
||||
|
||||
public static WebAppContext getCurrentWebAppContext()
|
||||
{
|
||||
|
@ -307,6 +239,54 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
parent.addHandler(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeDefaults(Map<String, String> properties)
|
||||
{
|
||||
for (String property : properties.keySet())
|
||||
{
|
||||
String value = properties.get(property);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("init {}: {}", property, value);
|
||||
switch (property)
|
||||
{
|
||||
case Deployable.WAR -> setWar(value);
|
||||
case Deployable.BASE_TEMP_DIR -> setAttribute(BASETEMPDIR, value);
|
||||
case Deployable.CONFIGURATION_CLASSES -> setConfigurationClasses(value == null ? null : value.split(","));
|
||||
case Deployable.CONTAINER_SCAN_JARS -> setAttribute(MetaInfConfiguration.CONTAINER_JAR_PATTERN, value);
|
||||
case Deployable.EXTRACT_WARS -> setExtractWAR(Boolean.parseBoolean(value));
|
||||
case Deployable.PARENT_LOADER_PRIORITY -> setParentLoaderPriority(Boolean.parseBoolean(value));
|
||||
case Deployable.WEBINF_SCAN_JARS -> setAttribute(MetaInfConfiguration.WEBINF_JAR_PATTERN, value);
|
||||
case Deployable.DEFAULTS_DESCRIPTOR -> setDefaultsDescriptor(value);
|
||||
case Deployable.SCI_EXCLUSION_PATTERN -> setAttribute("org.eclipse.jetty.containerInitializerExclusionPattern", value);
|
||||
case Deployable.SCI_ORDER -> setAttribute("org.eclipse.jetty.containerInitializerOrder", value);
|
||||
default ->
|
||||
{
|
||||
if (LOG.isDebugEnabled() && StringUtil.isNotBlank(value))
|
||||
LOG.debug("unknown property {}={}", property, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
_defaultContextPath = true;
|
||||
}
|
||||
|
||||
public boolean isContextPathDefault()
|
||||
{
|
||||
return _defaultContextPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContextPath(String contextPath)
|
||||
{
|
||||
super.setContextPath(contextPath);
|
||||
_defaultContextPath = false;
|
||||
}
|
||||
|
||||
public void setDefaultContextPath(String contextPath)
|
||||
{
|
||||
super.setContextPath(contextPath);
|
||||
_defaultContextPath = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param displayName The servletContextName to set.
|
||||
*/
|
||||
|
@ -950,14 +930,14 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
name = String.format("%s@%x", name, hashCode());
|
||||
|
||||
dumpObjects(out, indent,
|
||||
Dumpable.named("environment", ENVIRONMENT.getName()),
|
||||
Dumpable.named("environment", ContextHandler.ENVIRONMENT.getName()),
|
||||
new ClassLoaderDump(getClassLoader()),
|
||||
new DumpableCollection("Systemclasses " + name, systemClasses),
|
||||
new DumpableCollection("Serverclasses " + name, serverClasses),
|
||||
new DumpableCollection("Configurations " + name, _configurations),
|
||||
new DumpableCollection("Handler attributes " + name, getAttributes().asAttributeMap().entrySet()),
|
||||
new DumpableCollection("Context attributes " + name, getServletContext().getContextHandler().asAttributeMap().entrySet()),
|
||||
new DumpableCollection("Environment attributes " + name, ENVIRONMENT.asAttributeMap().entrySet()),
|
||||
new DumpableCollection("Environment attributes " + name, ContextHandler.ENVIRONMENT.asAttributeMap().entrySet()),
|
||||
new DumpableCollection("EventListeners " + this, getEventListeners()),
|
||||
new DumpableCollection("Initparams " + name, getInitParams().entrySet())
|
||||
);
|
||||
|
|
|
@ -20,7 +20,6 @@ import java.util.List;
|
|||
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
@ -131,12 +130,11 @@ public class MetaInfConfigurationTest
|
|||
* @throws Exception if the test fails
|
||||
*/
|
||||
@Test
|
||||
@Disabled // TODO
|
||||
public void testFindAndFilterContainerPathsJDK9() throws Exception
|
||||
{
|
||||
MetaInfConfiguration config = new MetaInfConfiguration();
|
||||
WebAppContext context = new WebAppContext();
|
||||
context.setAttribute(MetaInfConfiguration.CONTAINER_JAR_PATTERN, ".*/jetty-util-[^/]*\\.jar$|.*/jetty-util/target/classes/$|.*/foo-bar-janb.jar");
|
||||
context.setAttribute(MetaInfConfiguration.CONTAINER_JAR_PATTERN, ".*servlet-api-[^/]*\\.jar$|.*/foo-bar-janb.jar");
|
||||
WebAppClassLoader loader = new WebAppClassLoader(context);
|
||||
context.setClassLoader(loader);
|
||||
config.findAndFilterContainerPaths(context);
|
||||
|
@ -145,7 +143,7 @@ public class MetaInfConfigurationTest
|
|||
for (Resource r : containerResources)
|
||||
{
|
||||
String s = r.toString();
|
||||
assertTrue(s.endsWith("foo-bar-janb.jar") || s.contains("jetty-util"));
|
||||
assertTrue(s.endsWith("foo-bar-janb.jar") || s.contains("servlet-api"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ deploy
|
|||
[files]
|
||||
webapps-ee10/root-ee10/
|
||||
webapps-ee10/root-ee10/images/
|
||||
basehome:modules/demo.d/ee10-root/index.html|webapps-ee10/root-ee10/index.html
|
||||
basehome:modules/demo.d/ee10-root/jetty.css|webapps-ee10/root-ee10/jetty.css
|
||||
basehome:modules/demo.d/ee10-root/images/jetty-pic.png|webapps-ee10/root-ee10/images/jetty-pic.png
|
||||
basehome:modules/demo.d/ee10-root/images/webtide_logo.jpg|webapps-ee10/root-ee10/images/webtide_logo.jpg
|
||||
basehome:modules/demo.d/ee10-root/index.html|webapps/root-ee10/index.html
|
||||
basehome:modules/demo.d/ee10-root/jetty.css|webapps/root-ee10/jetty.css
|
||||
basehome:modules/demo.d/ee10-root/images/jetty-pic.png|webapps/root-ee10/images/jetty-pic.png
|
||||
basehome:modules/demo.d/ee10-root/images/webtide_logo.jpg|webapps/root-ee10/images/webtide_logo.jpg
|
||||
|
|
7
pom.xml
7
pom.xml
|
@ -186,7 +186,7 @@
|
|||
<!-- <module>documentation</module>-->
|
||||
<module>jetty-core</module>
|
||||
<module>jetty-integrations</module>
|
||||
<module>jetty-ee8</module>
|
||||
<!-- <module>jetty-ee8</module>-->
|
||||
<module>jetty-ee9</module>
|
||||
<module>jetty-ee10</module>
|
||||
<module>jetty-home</module>
|
||||
|
@ -1208,6 +1208,11 @@
|
|||
<artifactId>jetty-deploy</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-ee</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-hazelcast</artifactId>
|
||||
|
|
Loading…
Reference in New Issue