@@ -45,12 +45,12 @@ class DevAppServerClassLoader extends URLClassLoader {
4545 = "com.google.appengine.tools.development.agent.AppEngineDevAgent" ;
4646
4747 /**
48- * A system property defining a prefix where, if a class name begins with the prefix, the class
49- * will be loaded by the system class loader. If unset, no classes are loaded by the system
50- * class loader.
48+ * A system property defining a comma-separated list of prefixes. If a class name begins with one
49+ * of these prefixes, the class will be loaded by the system class loader. If unset, only classes
50+ * that are required to be loaded by it, such as Jacoco, will be loaded by the system class
51+ * loader.
5152 */
52- static final String SYSTEM_CLASS_PREFIX_PROPERTY =
53- "com.google.appengine.system.class.prefix" ;
53+ static final String SYSTEM_CLASS_PREFIX_PROPERTY = "com.google.appengine.system.class.prefix" ;
5454
5555 /**
5656 * Creates a new {@code DevAppServerClassLoader}, which will load
@@ -101,18 +101,30 @@ private static void addLibs(List<URL> libs, List<URL> toAdd)
101101 }
102102
103103 @ Override
104+ @ SuppressWarnings ("StringSplitter" ) // Avoid Guava in Classloader and manual check for weird case
104105 protected synchronized Class <?> loadClass (String name , boolean resolve )
105106 throws ClassNotFoundException {
106107
107- // No class can begin with /// so the default value disables the extraPrefix logic.
108- String systemClassPrefix = System .getProperty (SYSTEM_CLASS_PREFIX_PROPERTY , "///" );
109-
110- if (name .startsWith (systemClassPrefix ) || name .startsWith ("org.jacoco.agent." )) {
111- Class <?> c = ClassLoader .getSystemClassLoader ().loadClass (name );
112- if (resolve ) {
113- resolveClass (c );
108+ // A comma-separated list of prefixes of classes that should be loaded by the system class
109+ // loader.
110+ String systemClassPrefixes = System .getProperty (SYSTEM_CLASS_PREFIX_PROPERTY , "" );
111+ List <String > systemPrefixStrings = new ArrayList <>();
112+ for (String prefix : systemClassPrefixes .split ("," )) {
113+ if (!prefix .trim ().isEmpty ()) {
114+ systemPrefixStrings .add (prefix .trim ());
115+ }
116+ }
117+ // jacoco agent needs to be loaded by the system class loader.
118+ systemPrefixStrings .add ("org.jacoco.agent." );
119+
120+ for (String prefix : systemPrefixStrings ) {
121+ if (name .startsWith (prefix )) {
122+ Class <?> c = ClassLoader .getSystemClassLoader ().loadClass (name );
123+ if (resolve ) {
124+ resolveClass (c );
125+ }
126+ return c ;
114127 }
115- return c ;
116128 }
117129 // Special-case a few classes that need to be shared.
118130 if (name .equals (DEV_APP_SERVER_INTERFACE )
0 commit comments