@@ -60,6 +60,7 @@ public static void main(String[] args) {
6060 new EspressoLauncher ().launch (args );
6161 }
6262
63+ private final boolean launcherDebug = System .getenv ("_JAVA_LAUNCHER_DEBUG" ) != null ;
6364 private final ArrayList <String > mainClassArgs = new ArrayList <>();
6465 private String mainClassName = null ;
6566 private LaunchMode launchMode = LaunchMode .LM_CLASS ;
@@ -185,6 +186,14 @@ protected List<String> preprocessArguments(List<String> arguments, Map<String, S
185186
186187 List <String > expandedArguments = expandAtFiles (arguments );
187188
189+ if (launcherDebug ) {
190+ println ("Command line args:" );
191+ println ("argv[0] = " + getProgramName ());
192+ for (int i = 0 ; i < expandedArguments .size (); i ++) {
193+ println (String .format ("argv[%d] = %s" , i + 1 , expandedArguments .get (i )));
194+ }
195+ }
196+
188197 Arguments args = new Arguments (expandedArguments );
189198 while (args .next ()) {
190199 String arg = args .getKey ();
@@ -401,21 +410,76 @@ protected List<String> preprocessArguments(List<String> arguments, Map<String, S
401410 }
402411
403412 private List <String > expandAtFiles (List <String > arguments ) {
413+ // Expand @arg-file arguments until we reach application arguments
404414 List <String > expanded = null ;
405- for (int i = 0 ; i < arguments .size (); i ++) {
415+ int i = 0 ;
416+ for (; i < arguments .size (); i ++) {
406417 String arg = arguments .get (i );
407- if (arg .startsWith ("@" )) {
418+ if (arg .startsWith ("@" ) && arg . length () > 1 ) {
408419 if (expanded == null ) {
409420 expanded = new ArrayList <>(arguments .subList (0 , i ));
410421 }
411- parseArgFile (arg .substring (1 , arg .length ()), expanded );
412- } else if (expanded != null ) {
413- expanded .add (arg );
422+ String argArg = arg .substring (1 );
423+ if (arg .charAt (1 ) == '@' ) {
424+ // escaped argument
425+ expanded .add (argArg );
426+ } else {
427+ // Note, at the moment we don't detect the end of VM arguments
428+ // inside the arg file itself
429+ parseArgFile (argArg , expanded );
430+ }
431+ } else {
432+ if (arg .startsWith ("-" )) {
433+ if (isWhiteSpaceOption (arg )) {
434+ // Skip the argument that follows this option
435+ if (expanded != null ) {
436+ expanded .add (arg );
437+ }
438+ i ++;
439+ arg = arguments .get (i );
440+ } else if ("--disable-@files" .equals (arg ) || arg .startsWith ("--module=" )) {
441+ break ;
442+ }
443+ } else {
444+ // We have reached the main class or the jar
445+ break ;
446+ }
447+ if (expanded != null ) {
448+ expanded .add (arg );
449+ }
414450 }
415451 }
452+ if (expanded != null && i < arguments .size ()) {
453+ expanded .addAll (arguments .subList (i , arguments .size ()));
454+ }
416455 return expanded == null ? arguments : expanded ;
417456 }
418457
458+ private static boolean isWhiteSpaceOption (String arg ) {
459+ return switch (arg ) {
460+ case "--module-path" ,
461+ "-p" ,
462+ "--upgrade-module-path" ,
463+ "--add-modules" ,
464+ "--enable-native-access" ,
465+ "--limit-modules" ,
466+ "--add-exports" ,
467+ "--add-opens" ,
468+ "--add-reads" ,
469+ "--patch-module" ,
470+ "--describe-module" ,
471+ "-d" ,
472+ "--source" ,
473+ "--module" ,
474+ "-m" ,
475+ "-classpath" ,
476+ "-cp" ,
477+ "--class-path" ->
478+ true ;
479+ default -> false ;
480+ };
481+ }
482+
419483 private void parseArgFile (String pathArg , List <String > expanded ) {
420484 Path argFilePath = Paths .get (pathArg );
421485 try {
@@ -464,6 +528,8 @@ private void handleXXArg(String fullArg, ArrayList<String> unrecognized) {
464528 case "TieredStopAtLevel" -> {
465529 if ("0" .equals (value )) {
466530 espressoOptions .put ("engine.Compilation" , "false" );
531+ } else if ("1" .equals (value )) {
532+ espressoOptions .put ("engine.Mode" , "latency" );
467533 } else {
468534 unrecognized .add (fullArg );
469535 }
0 commit comments