5252import com .google .common .annotations .VisibleForTesting ;
5353import com .google .common .collect .ImmutableSet ;
5454import com .google .common .collect .Lists ;
55+ import com .google .common .base .StandardSystemProperty ;
5556import com .google .common .collect .Sets ;
5657import com .google .common .io .FileWriteMode ;
5758import com .google .common .io .Files ;
@@ -1101,22 +1102,30 @@ private void compileJsps(File stage, ApplicationProcessingOptions opts, String r
11011102
11021103 // We do not want the -compile flag there, as we will compile all the generated files
11031104 // at once, in a second step.
1104- String [] args = {
1105- "-classpath" ,
1106- classpath ,
1107- "-uriroot" ,
1108- stage .getPath (),
1109- "-p" ,
1110- "org.apache.jsp" ,
1111- "-l" ,
1112- "-v" ,
1113- "-webinc" ,
1114- generatedWebXml .getPath (),
1115- "-d" ,
1116- getJspJavaFilesGeneratedTempDirectory ().getPath (),
1117- "-javaEncoding" ,
1118- staging .compileEncoding ().get (),
1119- };
1105+ List <String > argsList =
1106+ new ArrayList <>(
1107+ Arrays .asList (
1108+ "-classpath" ,
1109+ classpath ,
1110+ "-uriroot" ,
1111+ stage .getPath (),
1112+ "-p" ,
1113+ "org.apache.jsp" ,
1114+ "-l" ,
1115+ "-v" ,
1116+ "-webinc" ,
1117+ generatedWebXml .getPath (),
1118+ "-d" ,
1119+ getJspJavaFilesGeneratedTempDirectory ().getPath (),
1120+ "-javaEncoding" ,
1121+ staging .compileEncoding ().get ()));
1122+
1123+ String javaVersion = getJavaVersionForJsp (runtime );
1124+ argsList .addAll (Arrays .asList ("-source" , javaVersion ));
1125+ argsList .addAll (Arrays .asList ("-target" , javaVersion ));
1126+
1127+ String [] args = argsList .toArray (new String [0 ]);
1128+
11201129 if (detailsWriter == null ) {
11211130 detailsWriter =
11221131 new PrintWriter (
@@ -1140,7 +1149,7 @@ private void compileJsps(File stage, ApplicationProcessingOptions opts, String r
11401149 // Now that the Java servlet files from jsp have been generated, we compile them in a single
11411150 // invocation to speed up the deployment process.
11421151 compileJspJavaFiles (
1143- classpath , webInf , getJspJavaFilesGeneratedTempDirectory (), opts , runtime );
1152+ classpath , webInf , getJspJavaFilesGeneratedTempDirectory (), opts , javaVersion );
11441153
11451154 // Reread the web.xml as it has been modified by Jasper to add the mapping of the generated
11461155 // servlets.
@@ -1153,12 +1162,54 @@ File getJspJavaFilesGeneratedTempDirectory() {
11531162 return jspJavaFilesGeneratedTempDirectory ;
11541163 }
11551164
1165+ private String getJavaVersionForJsp (String runtime ) {
1166+ String version = "21" ; // Default to 21.
1167+ switch (runtime ) {
1168+ case JAVA_11_RUNTIME_ID :
1169+ version = "11" ;
1170+ break ;
1171+ case JAVA_17_RUNTIME_ID :
1172+ version = "17" ;
1173+ break ;
1174+ case JAVA_21_RUNTIME_ID :
1175+ version = "21" ;
1176+ break ;
1177+ case JAVA_25_RUNTIME_ID :
1178+ version = "25" ;
1179+ break ;
1180+ default :
1181+ if (runtime .startsWith (GOOGLE_LEGACY_RUNTIME_ID )) {
1182+ version = "21" ;
1183+ } else if (runtime .startsWith (JAVA_8_RUNTIME_ID )) {
1184+ version = "8" ;
1185+ }
1186+ break ;
1187+ }
1188+
1189+ int currentJdkVersion = Runtime .version ().feature ();
1190+
1191+ int runtimeVersion = Integer .parseInt (version );
1192+ if (currentJdkVersion < runtimeVersion ) {
1193+ statusUpdate (
1194+ "Warning: Current JDK version used for JSP compilation is "
1195+ + currentJdkVersion
1196+ + " but the AppEngine runtime is "
1197+ + runtime
1198+ + ". JSPs will be compiled with source/target "
1199+ + currentJdkVersion
1200+ + " instead of "
1201+ + version );
1202+ version = String .valueOf (currentJdkVersion );
1203+ }
1204+ return version ;
1205+ }
1206+
11561207 private void compileJspJavaFiles (
11571208 String classpath ,
11581209 File webInf ,
11591210 File jspClassDir ,
11601211 ApplicationProcessingOptions opts ,
1161- String runtime )
1212+ String javaVersion )
11621213 throws IOException {
11631214
11641215 JavaCompiler compiler = ToolProvider .getSystemJavaCompiler ();
@@ -1184,19 +1235,9 @@ private void compileJspJavaFiles(
11841235 optionList .addAll (Arrays .asList ("-encoding" , staging .compileEncoding ().get ()));
11851236 // Depending on the runtime, select the correct bytecode target for the jsp classes compilation.
11861237 // If the runtime is unknown and forced (like java9), keep the default settings.
1187- if (runtime .startsWith (JAVA_8_RUNTIME_ID )) {
1188- optionList .addAll (Arrays .asList ("-source" , "8" ));
1189- optionList .addAll (Arrays .asList ("-target" , "8" ));
1190- } else if (runtime .startsWith (GOOGLE_LEGACY_RUNTIME_ID )
1191- || runtime .equals (JAVA_11_RUNTIME_ID )
1192- || runtime .equals (JAVA_17_RUNTIME_ID )
1193- || runtime .equals (JAVA_21_RUNTIME_ID )
1194- || runtime .equals (JAVA_25_RUNTIME_ID )) {
1195- // TODO(b/115569833): for now, it's still possible to use a JDK8 to compile and deploy Java11
1196- // apps.
1197- optionList .addAll (Arrays .asList ("-source" , "8" ));
1198- optionList .addAll (Arrays .asList ("-target" , "8" ));
1199- }
1238+ // If the current JDK is older than the runtime, we fallback to the current JDK version.
1239+ optionList .addAll (Arrays .asList ("-source" , javaVersion ));
1240+ optionList .addAll (Arrays .asList ("-target" , javaVersion ));
12001241
12011242 Iterable <? extends JavaFileObject > compilationUnits =
12021243 fileManager .getJavaFileObjectsFromFiles (files );
0 commit comments