in runtime/runtime_impl_jetty12/src/main/java/com/google/apphosting/runtime/jetty/JettyServletEngineAdapter.java [99:208]
public void start(String serverInfo, ServletEngineAdapter.Config runtimeOptions) {
boolean isHttpConnectorMode = Boolean.getBoolean(HTTP_CONNECTOR_MODE);
QueuedThreadPool threadPool =
new QueuedThreadPool(MAX_THREAD_POOL_THREADS, MIN_THREAD_POOL_THREADS);
// Try to enable virtual threads if requested and on java21:
if (Boolean.getBoolean("appengine.use.virtualthreads")
&& "java21".equals(GAE_RUNTIME)) {
threadPool.setVirtualThreadsExecutor(VirtualThreads.getDefaultVirtualThreadsExecutor());
logger.atInfo().log("Configuring Appengine web server virtual threads.");
}
server =
new Server(threadPool) {
@Override
public InvocationType getInvocationType() {
return InvocationType.BLOCKING;
}
};
// Don't add the RPC Connector if in HttpConnector mode.
if (!isHttpConnectorMode) {
rpcConnector =
new DelegateConnector(server, "RPC") {
@Override
public void run(Runnable runnable) {
// Override this so that it does the initial run in the same thread.
// Currently, we block until completion in serviceRequest() so no point starting new
// thread.
runnable.run();
}
};
HttpConfiguration httpConfiguration = rpcConnector.getHttpConfiguration();
httpConfiguration.setSendDateHeader(false);
httpConfiguration.setSendServerVersion(false);
httpConfiguration.setSendXPoweredBy(false);
// If runtime is using EE8, then set URI compliance to LEGACY to behave like Jetty 9.4.
if (Objects.equals(AppVersionHandlerFactory.getEEVersion(), AppVersionHandlerFactory.EEVersion.EE8)) {
httpConfiguration.setUriCompliance(UriCompliance.LEGACY);
}
if (LEGACY_MODE) {
httpConfiguration.setUriCompliance(UriCompliance.LEGACY);
httpConfiguration.setHttpCompliance(HttpCompliance.RFC7230_LEGACY);
httpConfiguration.setRequestCookieCompliance(CookieCompliance.RFC2965);
httpConfiguration.setResponseCookieCompliance(CookieCompliance.RFC2965);
httpConfiguration.setMultiPartCompliance(MultiPartCompliance.LEGACY);
}
server.addConnector(rpcConnector);
}
AppVersionHandlerFactory appVersionHandlerFactory =
AppVersionHandlerFactory.newInstance(server, serverInfo);
appVersionHandler = new AppVersionHandler(appVersionHandlerFactory);
server.setHandler(appVersionHandler);
// In HttpConnector mode we will combine both SizeLimitHandlers.
boolean ignoreResponseSizeLimit = Boolean.getBoolean(IGNORE_RESPONSE_SIZE_LIMIT);
if (!ignoreResponseSizeLimit && !isHttpConnectorMode) {
server.insertHandler(new SizeLimitHandler(-1, MAX_RESPONSE_SIZE));
}
boolean startJettyHttpProxy = false;
if (runtimeOptions.useJettyHttpProxy()) {
AppInfoFactory appInfoFactory;
AppVersionKey appVersionKey;
/* The init actions are not done in the constructor as they are not used when testing */
try {
String appRoot = runtimeOptions.applicationRoot();
String appPath = runtimeOptions.fixedApplicationPath();
appInfoFactory = new AppInfoFactory(System.getenv());
AppinfoPb.AppInfo appinfo = appInfoFactory.getAppInfoFromFile(appRoot, appPath);
// TODO Should we also call ApplyCloneSettings()?
LocalRpcContext<EmptyMessage> context = new LocalRpcContext<>(EmptyMessage.class);
EvaluationRuntimeServerInterface evaluationRuntimeServerInterface =
Objects.requireNonNull(runtimeOptions.evaluationRuntimeServerInterface());
evaluationRuntimeServerInterface.addAppVersion(context, appinfo);
context.getResponse();
appVersionKey = AppVersionKey.fromAppInfo(appinfo);
} catch (Exception e) {
throw new IllegalStateException(e);
}
if (isHttpConnectorMode) {
logger.atInfo().log("Using HTTP_CONNECTOR_MODE to bypass RPC");
server.insertHandler(
new JettyHttpHandler(
runtimeOptions, appVersionHandler.getAppVersion(), appVersionKey, appInfoFactory));
JettyHttpProxy.insertHandlers(server, ignoreResponseSizeLimit);
server.addConnector(JettyHttpProxy.newConnector(server, runtimeOptions));
} else {
server.setAttribute(
"com.google.apphosting.runtime.jetty.appYaml",
JettyServletEngineAdapter.getAppYaml(runtimeOptions));
// Delay start of JettyHttpProxy until after the main server and application is started.
startJettyHttpProxy = true;
}
}
try {
server.start();
if (startJettyHttpProxy) {
JettyHttpProxy.startServer(runtimeOptions);
}
} catch (Exception ex) {
// TODO: Should we have a wrapper exception for this
// type of thing in ServletEngineAdapter?
throw new RuntimeException(ex);
}
}