4141
4242class BytecodeInstructionIntegrationTest {
4343
44+ static Stream <CompilerHelper .CompilerConfig > provideCompilerConfigs () {
45+ List <CompilerHelper .CompilerConfig > configs = new ArrayList <>();
46+ configs .addAll (CompilerHelper .getAvailableCompilers ("1.5" ));
47+ configs .addAll (CompilerHelper .getAvailableCompilers ("1.8" ));
48+ configs .addAll (CompilerHelper .getAvailableCompilers ("11" ));
49+ configs .addAll (CompilerHelper .getAvailableCompilers ("17" ));
50+ configs .addAll (CompilerHelper .getAvailableCompilers ("21" ));
51+ configs .addAll (CompilerHelper .getAvailableCompilers ("25" ));
52+ return configs .stream ();
53+ }
54+
4455 @ ParameterizedTest
45- @ ValueSource (strings = {"1.5" , "1.8" })
46- void translatesOptimizedBytecodeToLLVMExecutable (String targetVersion ) throws Exception {
47- if ("1.5" .equals (targetVersion ) && !isSourceVersionSupported ("1.5" )) {
48- return ; // Skip on newer JDKs that dropped 1.5 support
49- }
56+ @ org .junit .jupiter .params .provider .MethodSource ("provideCompilerConfigs" )
57+ void translatesOptimizedBytecodeToLLVMExecutable (CompilerHelper .CompilerConfig config ) throws Exception {
5058 Parser .cleanup ();
5159
5260 Path sourceDir = Files .createTempDirectory ("bytecode-integration-sources" );
@@ -61,28 +69,43 @@ void translatesOptimizedBytecodeToLLVMExecutable(String targetVersion) throws Ex
6169 Path nativeReport = sourceDir .resolve ("native_report.c" );
6270 Files .write (nativeReport , nativeReportSource ().getBytes (StandardCharsets .UTF_8 ));
6371
64- JavaCompiler compiler = ToolProvider .getSystemJavaCompiler ();
65- assertNotNull (compiler , "A JDK is required to compile test sources" );
66-
67- // Compile App using JavaAPI as bootclasspath
72+ // Compile App using the specific JDK
6873 List <String > compileArgs = new ArrayList <>();
69- compileArgs .add ("-source" );
70- compileArgs .add (targetVersion );
71- compileArgs .add ("-target" );
72- compileArgs .add (targetVersion );
73- compileArgs .add ("-bootclasspath" );
74- compileArgs .add (javaApiDir .toString ());
74+
75+ double targetVer = 1.8 ;
76+ try { targetVer = Double .parseDouble (config .targetVersion ); } catch (NumberFormatException ignored ) {}
77+
78+ double jdkVer = 1.8 ;
79+ try { jdkVer = Double .parseDouble (config .jdkVersion ); } catch (NumberFormatException ignored ) {}
80+
81+ if (jdkVer >= 9 ) {
82+ compileArgs .add ("-source" );
83+ compileArgs .add (config .targetVersion );
84+ compileArgs .add ("-target" );
85+ compileArgs .add (config .targetVersion );
86+ // On JDK 9+, -bootclasspath is removed.
87+ // --patch-module is not allowed with -target 8.
88+ // We rely on the JDK's own bootstrap classes but include our JavaAPI in classpath
89+ // so that any non-replaced classes are found.
90+ // This means we compile against JDK 9+ API but emit older bytecode.
91+ compileArgs .add ("-classpath" );
92+ compileArgs .add (javaApiDir .toString ());
93+ } else {
94+ compileArgs .add ("-source" );
95+ compileArgs .add (config .targetVersion );
96+ compileArgs .add ("-target" );
97+ compileArgs .add (config .targetVersion );
98+ compileArgs .add ("-bootclasspath" );
99+ compileArgs .add (javaApiDir .toString ());
100+ compileArgs .add ("-Xlint:-options" );
101+ }
102+
75103 compileArgs .add ("-d" );
76104 compileArgs .add (classesDir .toString ());
77105 compileArgs .add (sourceDir .resolve ("BytecodeInstructionApp.java" ).toString ());
78106
79- int compileResult = compiler .run (
80- null ,
81- null ,
82- null ,
83- compileArgs .toArray (new String [0 ])
84- );
85- assertEquals (0 , compileResult , "BytecodeInstructionApp should compile" );
107+ int compileResult = CompilerHelper .compile (config .jdkHome , compileArgs );
108+ assertEquals (0 , compileResult , "BytecodeInstructionApp should compile with " + config );
86109
87110 Files .copy (nativeReport , classesDir .resolve ("native_report.c" ));
88111
@@ -190,11 +213,8 @@ private String invokeLdcLocalVarsAppSource() {
190213 }
191214
192215 @ ParameterizedTest
193- @ ValueSource (strings = {"1.5" , "1.8" })
194- void translatesInvokeAndLdcBytecodeToLLVMExecutable (String targetVersion ) throws Exception {
195- if ("1.5" .equals (targetVersion ) && !isSourceVersionSupported ("1.5" )) {
196- return ; // Skip on newer JDKs that dropped 1.5 support
197- }
216+ @ org .junit .jupiter .params .provider .MethodSource ("provideCompilerConfigs" )
217+ void translatesInvokeAndLdcBytecodeToLLVMExecutable (CompilerHelper .CompilerConfig config ) throws Exception {
198218 Parser .cleanup ();
199219
200220 Path sourceDir = Files .createTempDirectory ("invoke-ldc-sources" );
@@ -209,27 +229,37 @@ void translatesInvokeAndLdcBytecodeToLLVMExecutable(String targetVersion) throws
209229 Path nativeReport = sourceDir .resolve ("native_report.c" );
210230 Files .write (nativeReport , nativeReportSource ().getBytes (StandardCharsets .UTF_8 ));
211231
212- JavaCompiler compiler = ToolProvider .getSystemJavaCompiler ();
213- assertNotNull (compiler , "A JDK is required to compile test sources" );
214-
215232 List <String > compileArgs = new ArrayList <>();
216- compileArgs .add ("-source" );
217- compileArgs .add (targetVersion );
218- compileArgs .add ("-target" );
219- compileArgs .add (targetVersion );
220- compileArgs .add ("-bootclasspath" );
221- compileArgs .add (javaApiDir .toString ());
233+
234+ double targetVer = 1.8 ;
235+ try { targetVer = Double .parseDouble (config .targetVersion ); } catch (NumberFormatException ignored ) {}
236+
237+ double jdkVer = 1.8 ;
238+ try { jdkVer = Double .parseDouble (config .jdkVersion ); } catch (NumberFormatException ignored ) {}
239+
240+ if (jdkVer >= 9 ) {
241+ compileArgs .add ("-source" );
242+ compileArgs .add (config .targetVersion );
243+ compileArgs .add ("-target" );
244+ compileArgs .add (config .targetVersion );
245+ compileArgs .add ("-classpath" );
246+ compileArgs .add (javaApiDir .toString ());
247+ } else {
248+ compileArgs .add ("-source" );
249+ compileArgs .add (config .targetVersion );
250+ compileArgs .add ("-target" );
251+ compileArgs .add (config .targetVersion );
252+ compileArgs .add ("-bootclasspath" );
253+ compileArgs .add (javaApiDir .toString ());
254+ compileArgs .add ("-Xlint:-options" );
255+ }
256+
222257 compileArgs .add ("-d" );
223258 compileArgs .add (classesDir .toString ());
224259 compileArgs .add (sourceDir .resolve ("InvokeLdcLocalVarsApp.java" ).toString ());
225260
226- int compileResult = compiler .run (
227- null ,
228- null ,
229- null ,
230- compileArgs .toArray (new String [0 ])
231- );
232- assertEquals (0 , compileResult , "InvokeLdcLocalVarsApp should compile" );
261+ int compileResult = CompilerHelper .compile (config .jdkHome , compileArgs );
262+ assertEquals (0 , compileResult , "InvokeLdcLocalVarsApp should compile with " + config );
233263
234264 Files .copy (nativeReport , classesDir .resolve ("native_report.c" ));
235265
@@ -985,18 +1015,15 @@ private String nativeReportSource() {
9851015 }
9861016
9871017 @ ParameterizedTest
988- @ ValueSource (strings = {"1.5" , "1.8" })
989- void handleDefaultOutputWritesOutput (String targetVersion ) throws Exception {
990- if ("1.5" .equals (targetVersion ) && !isSourceVersionSupported ("1.5" )) {
991- return ; // Skip on newer JDKs that dropped 1.5 support
992- }
1018+ @ org .junit .jupiter .params .provider .MethodSource ("provideCompilerConfigs" )
1019+ void handleDefaultOutputWritesOutput (CompilerHelper .CompilerConfig config ) throws Exception {
9931020 Parser .cleanup ();
9941021 resetByteCodeClass ();
9951022 Path sourceDir = Files .createTempDirectory ("default-output-source" );
9961023 Path outputDir = Files .createTempDirectory ("default-output-dest" );
9971024
9981025 Files .write (sourceDir .resolve ("resource.txt" ), "data" .getBytes (StandardCharsets .UTF_8 ));
999- compileDummyMainClass (sourceDir , "com.example" , "MyAppDefault" , targetVersion );
1026+ compileDummyMainClass (sourceDir , "com.example" , "MyAppDefault" , config );
10001027
10011028 String [] args = new String [] {
10021029 "csharp" ,
@@ -1076,18 +1103,15 @@ void copyDirRecursivelyCopies() throws Exception {
10761103 }
10771104
10781105 @ ParameterizedTest
1079- @ ValueSource (strings = {"1.5" , "1.8" })
1080- void handleIosOutputGeneratesProjectStructure (String targetVersion ) throws Exception {
1081- if ("1.5" .equals (targetVersion ) && !isSourceVersionSupported ("1.5" )) {
1082- return ; // Skip on newer JDKs that dropped 1.5 support
1083- }
1106+ @ org .junit .jupiter .params .provider .MethodSource ("provideCompilerConfigs" )
1107+ void handleIosOutputGeneratesProjectStructure (CompilerHelper .CompilerConfig config ) throws Exception {
10841108 Parser .cleanup ();
10851109 resetByteCodeClass ();
10861110 Path sourceDir = Files .createTempDirectory ("ios-output-source" );
10871111 Path outputDir = Files .createTempDirectory ("ios-output-dest" );
10881112
10891113 Files .write (sourceDir .resolve ("resource.txt" ), "data" .getBytes (StandardCharsets .UTF_8 ));
1090- compileDummyMainClass (sourceDir , "com.example" , "MyAppIOS" , targetVersion );
1114+ compileDummyMainClass (sourceDir , "com.example" , "MyAppIOS" , config );
10911115
10921116 // Add a bundle to test copyDir invocation in execute loop
10931117 Path bundleDir = sourceDir .resolve ("test.bundle" );
@@ -1139,7 +1163,7 @@ private void resetByteCodeClass() throws Exception {
11391163 ((Set <?>) writableFieldsField .get (null )).clear ();
11401164 }
11411165
1142- private void compileDummyMainClass (Path sourceDir , String packageName , String className , String targetVersion ) throws Exception {
1166+ private void compileDummyMainClass (Path sourceDir , String packageName , String className , CompilerHelper . CompilerConfig config ) throws Exception {
11431167 Path packageDir = sourceDir ;
11441168 for (String part : packageName .split ("\\ ." )) {
11451169 packageDir = packageDir .resolve (part );
@@ -1152,13 +1176,17 @@ private void compileDummyMainClass(Path sourceDir, String packageName, String cl
11521176 "}\n " ;
11531177 Files .write (javaFile , content .getBytes (StandardCharsets .UTF_8 ));
11541178
1155- JavaCompiler compiler = ToolProvider .getSystemJavaCompiler ();
1156- int result = compiler .run (null , null , null ,
1157- "-source" , targetVersion ,
1158- "-target" , targetVersion ,
1159- "-d" , sourceDir .toString (),
1160- javaFile .toString ());
1161- assertEquals (0 , result , "Compilation failed" );
1179+ List <String > args = new ArrayList <>();
1180+ args .add ("-source" );
1181+ args .add (config .targetVersion );
1182+ args .add ("-target" );
1183+ args .add (config .targetVersion );
1184+ args .add ("-d" );
1185+ args .add (sourceDir .toString ());
1186+ args .add (javaFile .toString ());
1187+
1188+ int result = CompilerHelper .compile (config .jdkHome , args );
1189+ assertEquals (0 , result , "Compilation failed with " + config );
11621190 }
11631191
11641192 @ Test
@@ -1262,19 +1290,4 @@ void testArithmeticExpressionCoverage() {
12621290 // or mock if possible. But here we can check basic behavior.
12631291 }
12641292
1265- private boolean isSourceVersionSupported (String version ) {
1266- String javaVersion = System .getProperty ("java.specification.version" );
1267- if (javaVersion .startsWith ("1." )) {
1268- return true ;
1269- }
1270- try {
1271- int major = Integer .parseInt (javaVersion );
1272- if ("1.5" .equals (version )) {
1273- if (major >= 9 ) return false ;
1274- }
1275- } catch (NumberFormatException e ) {
1276- return true ;
1277- }
1278- return true ;
1279- }
12801293}
0 commit comments