1
1
/*
2
- * Copyright (c) 2017, 2024 , Oracle and/or its affiliates.
2
+ * Copyright (c) 2017, 2025 , Oracle and/or its affiliates.
3
3
* Copyright (c) 2013, Regents of the University of California
4
4
*
5
5
* All rights reserved.
47
47
import java .util .Set ;
48
48
import java .util .UUID ;
49
49
import java .util .function .Function ;
50
+ import java .util .function .Predicate ;
50
51
51
52
import org .graalvm .launcher .AbstractLanguageLauncher ;
52
53
import org .graalvm .nativeimage .ImageInfo ;
@@ -530,11 +531,17 @@ private String getLauncherExecName() {
530
531
* {@link #getEnv(String)} is used to retrieve $PATH.
531
532
* @return The absolute path to the program or {@code null}.
532
533
*/
533
- private String calculateProgramFullPath (String program , Function <Path , Boolean > isExecutable , String envPath ) {
534
+ private String calculateProgramFullPath (String program , Predicate <Path > isExecutable , String envPath ) {
534
535
Path programPath = Paths .get (program );
535
536
536
537
// If this is an absolute path, we are already fine.
537
538
if (programPath .isAbsolute ()) {
539
+ if (IS_WINDOWS ) {
540
+ String resolvedProgramNameWithExtension = getProgramNameWithExtension (isExecutable , program );
541
+ if (resolvedProgramNameWithExtension != null ) {
542
+ return resolvedProgramNameWithExtension ;
543
+ }
544
+ }
538
545
return program ;
539
546
}
540
547
@@ -553,26 +560,15 @@ private String calculateProgramFullPath(String program, Function<Path, Boolean>
553
560
i = path .indexOf (File .pathSeparatorChar , previous );
554
561
int end = i == -1 ? path .length () : i ;
555
562
Path resolvedProgramName = Paths .get (path .substring (previous , end )).resolve (programPath );
556
- if (isExecutable .apply (resolvedProgramName )) {
563
+ if (isExecutable .test (resolvedProgramName )) {
557
564
return resolvedProgramName .toString ();
558
565
}
559
566
560
567
// On windows, the program name may be without the extension
561
568
if (IS_WINDOWS ) {
562
- String pathExtEnvvar = getEnv ("PATHEXT" );
563
- if (pathExtEnvvar != null ) {
564
- // default extensions are defined
565
- String resolvedStr = resolvedProgramName .toString ();
566
- if (resolvedStr .length () <= 3 || resolvedStr .charAt (resolvedStr .length () - 4 ) != '.' ) {
567
- // program has no file extension
568
- String [] pathExts = pathExtEnvvar .toLowerCase ().split (";" );
569
- for (String pathExt : pathExts ) {
570
- resolvedProgramName = Path .of (resolvedStr + pathExt );
571
- if (isExecutable .apply (resolvedProgramName )) {
572
- return resolvedProgramName .toString ();
573
- }
574
- }
575
- }
569
+ String resolvedProgramNameWithExtension = getProgramNameWithExtension (isExecutable , resolvedProgramName .toString ());
570
+ if (resolvedProgramNameWithExtension != null ) {
571
+ return resolvedProgramNameWithExtension ;
576
572
}
577
573
}
578
574
@@ -598,6 +594,28 @@ private String calculateProgramFullPath(String program, Function<Path, Boolean>
598
594
return programPath .toAbsolutePath ().toString ();
599
595
}
600
596
597
+ private static String getProgramNameWithExtension (Predicate <Path > isExecutable , String programStr ) {
598
+ if (isExecutable .test (Path .of (programStr ))) {
599
+ return programStr ;
600
+ }
601
+ if (programStr .length () <= 3 || programStr .charAt (programStr .length () - 4 ) != '.' ) {
602
+ // program has no file extension
603
+ Path programNameWithExtension = null ;
604
+ String pathExtEnvvar = getEnv ("PATHEXT" );
605
+ if (pathExtEnvvar != null ) {
606
+ // default extensions are defined
607
+ String [] pathExts = pathExtEnvvar .toLowerCase ().split (";" );
608
+ for (String pathExt : pathExts ) {
609
+ programNameWithExtension = Path .of (programStr + pathExt );
610
+ if (isExecutable .test (programNameWithExtension )) {
611
+ return programNameWithExtension .toString ();
612
+ }
613
+ }
614
+ }
615
+ }
616
+ return null ;
617
+ }
618
+
601
619
private String [] getExecutableList () {
602
620
String launcherExecName = getLauncherExecName ();
603
621
if (launcherExecName != null ) {
0 commit comments