in runtime/local_jetty12_ee10/src/main/java/com/google/appengine/tools/development/jetty/ee10/JettyContainerService.java [174:281]
protected File initContext() throws IOException {
// Register our own slight modification of Jetty's WebAppContext,
// which maintains ApiProxy's environment ThreadLocal.
this.context =
new DevAppEngineWebAppContext(
appDir, externalResourceDir, devAppServerVersion, apiProxyDelegate, devAppServer);
context.addEventListener(
new ContextHandler.ContextScopeListener() {
@Override
public void enterScope(Context context, Request request) {
JettyContainerService.this.enterScope(request);
}
@Override
public void exitScope(Context context, Request request) {
JettyContainerService.this.exitScope(null);
}
});
this.appContext = new JettyAppContext();
// Set the location of deployment descriptor. This value might be null,
// which is fine, it just means Jetty will look for it in the default
// location (WEB-INF/web.xml).
context.setDescriptor(webXmlLocation == null ? null : webXmlLocation.getAbsolutePath());
// Override the web.xml that Jetty automatically prepends to other
// web.xml files. This is where the DefaultServlet is registered,
// which serves static files. We override it to disable some
// other magic (e.g. JSP compilation), and to turn off some static
// file functionality that Prometheus won't support
// (e.g. directory listings) and turn on others (e.g. symlinks).
String webDefaultXml =
devAppServer
.getServiceProperties()
.getOrDefault("appengine.webdefault.xml", WEB_DEFAULTS_XML);
context.setDefaultsDescriptor(webDefaultXml);
// Disable support for jetty-web.xml.
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(WebAppContext.class.getClassLoader());
context.setConfigurationClasses(CONFIG_CLASSES);
}
finally {
Thread.currentThread().setContextClassLoader(contextClassLoader);
}
// Create the webapp ClassLoader.
// We need to load appengine-web.xml to initialize the class loader.
File appRoot = determineAppRoot();
installLocalInitializationEnvironment();
// Create the webapp ClassLoader.
// ADD TLDs that must be under WEB-INF for Jetty9.
// We make it non fatal, and emit a warning when it fails, as the user can add this dependency
// in the application itself.
if (applicationContainsJSP(appDir, JSP_REGEX)) {
for (File file : AppengineSdk.getSdk().getUserJspLibFiles()) {
if (file.getName().startsWith(JETTY_TAG_LIB_JAR_PREFIX)) {
// Jetty provided tag lib jars are currently
// org.apache.taglibs.taglibs-standard-spec-1.2.5.jar and
// org.apache.taglibs.taglibs-standard-impl-1.2.5.jar.
// For jars provided by a Maven or Gradle builder, the prefix org.apache.taglibs.taglibs-
// is not present, so the jar names are:
// standard-spec-1.2.5.jar and
// standard-impl-1.2.5.jar.
// We check if these jars are provided by the web app, or we copy them from Jetty distro.
File jettyProvidedDestination = new File(appDir + "/WEB-INF/lib/" + file.getName());
if (!jettyProvidedDestination.exists()) {
File mavenProvidedDestination =
new File(
appDir
+ "/WEB-INF/lib/"
+ file.getName().substring(JETTY_TAG_LIB_JAR_PREFIX.length()));
if (!mavenProvidedDestination.exists()) {
log.log(
Level.WARNING,
"Adding jar "
+ file.getName()
+ " to WEB-INF/lib."
+ " You might want to add a dependency in your project build system to avoid"
+ " this warning.");
try {
Files.copy(file, jettyProvidedDestination);
} catch (IOException e) {
log.log(
Level.WARNING,
"Cannot copy org.apache.taglibs.taglibs jar file to WEB-INF/lib.",
e);
}
}
}
}
}
}
URL[] classPath = getClassPathForApp(appRoot);
IsolatedAppClassLoader isolatedClassLoader = new IsolatedAppClassLoader(
appRoot, externalResourceDir, classPath, JettyContainerService.class.getClassLoader());
context.setClassLoader(isolatedClassLoader);
if (Boolean.parseBoolean(System.getProperty("appengine.allowRemoteShutdown"))) {
context.addServlet(new ServletHolder(new ServerShutdownServlet()), "/_ah/admin/quit");
}
return appRoot;
}