From 4a964d05a996e51cdf9a6e689fe5c4b9165885f7 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Fri, 17 Nov 2023 13:15:25 +1100 Subject: [PATCH] fixes to make spring boot application run on DevAppServer Signed-off-by: Lachlan Roberts --- .../development/DevAppServerClassLoader.java | 33 ++++++++++++++----- .../jetty/ee10/DevAppEngineWebAppContext.java | 9 +++-- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/api_dev/src/main/java/com/google/appengine/tools/development/DevAppServerClassLoader.java b/api_dev/src/main/java/com/google/appengine/tools/development/DevAppServerClassLoader.java index 932ddd1c..1f1f046e 100644 --- a/api_dev/src/main/java/com/google/appengine/tools/development/DevAppServerClassLoader.java +++ b/api_dev/src/main/java/com/google/appengine/tools/development/DevAppServerClassLoader.java @@ -60,16 +60,31 @@ class DevAppServerClassLoader extends URLClassLoader { * classes will be loaded (e.g. DevAppServer). */ public static DevAppServerClassLoader newClassLoader(ClassLoader delegate) { + List sharedLibs = AppengineSdk.getSdk().getSharedLibs(); + List implLibs = AppengineSdk.getSdk().getImplLibs(); + List userJspLibs = AppengineSdk.getSdk().getUserJspLibs(); + // NB Doing shared, then impl, in order, allows us to prefer - // returning shared classes when asked by other classloaders. This makes - // it so that we don't have to have the impl and shared classes - // be a strictly disjoint set. - List libs = new ArrayList<>(AppengineSdk.getSdk().getSharedLibs()); - libs.addAll(AppengineSdk.getSdk().getImplLibs()); - // Needed by admin console servlets, which are loaded by this - // ClassLoader - libs.addAll(AppengineSdk.getSdk().getUserJspLibs()); - return new DevAppServerClassLoader(libs.toArray(new URL[libs.size()]), delegate); + // returning shared classes when asked by other classloaders. + // This makes it so that we don't have to have the impl and + // shared classes be a strictly disjoint set. + List libs = new ArrayList<>(sharedLibs); + addLibs(libs, implLibs); + + // Needed by admin console servlets, which are loaded by this ClassLoader. + addLibs(libs, userJspLibs); + + return new DevAppServerClassLoader(libs.toArray(new URL[0]), delegate); + } + + private static void addLibs(List libs, List toAdd) + { + for (URL url : toAdd) + { + if (libs.contains(url)) + continue; + libs.add(url); + } } // NB diff --git a/runtime/local_jetty12_ee10/src/main/java/com/google/appengine/tools/development/jetty/ee10/DevAppEngineWebAppContext.java b/runtime/local_jetty12_ee10/src/main/java/com/google/appengine/tools/development/jetty/ee10/DevAppEngineWebAppContext.java index ed2b7883..d8c7a2c9 100644 --- a/runtime/local_jetty12_ee10/src/main/java/com/google/appengine/tools/development/jetty/ee10/DevAppEngineWebAppContext.java +++ b/runtime/local_jetty12_ee10/src/main/java/com/google/appengine/tools/development/jetty/ee10/DevAppEngineWebAppContext.java @@ -64,6 +64,7 @@ public DevAppEngineWebAppContext(File appDir, File externalResourceDir, String s // Set up the classpath required to compile JSPs. This is specific to Jasper. setAttribute(JASPER_SERVLET_CLASSPATH, buildClasspath()); + setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", ".*/jakarta.servlet-api-[^/]*\\.jar$|.*jakarta.servlet.jsp.jstl-.*\\.jar$"); // Make ApiProxyLocal available via the servlet context. This allows // servlets that are part of the dev appserver (like those that render the @@ -94,14 +95,18 @@ protected ClassLoader configureClassLoader(ClassLoader loader) { return loader; } + @Override + protected void doStart() throws Exception { + super.doStart(); + disableTransportGuarantee(); + } + @Override protected ClassLoader enterScope(Request contextRequest) { if ((contextRequest != null) && (hasSkipAdminCheck(contextRequest))) { contextRequest.setAttribute(SKIP_ADMIN_CHECK_ATTR, Boolean.TRUE); } - disableTransportGuarantee(); - // TODO An extremely heinous way of helping the DevAppServer's // SecurityManager determine if a DevAppServer request thread is executing. // Find something better.