1515
1616public final class JarHandler {
1717
18+ enum ModuleNameOrigin {
19+ MANIFEST ,
20+ MODULE_INFO ,
21+ GUESSED
22+ }
23+
24+ record Result (String name , ModuleNameOrigin origin , Path jar ) {}
25+
1826 static void safeHandle (final Path source , final Path target ) {
1927 try {
2028 handle (source , target );
@@ -31,24 +39,32 @@ static void handle(final Path source, final Path target) throws IOException {
3139
3240 Files .createDirectories (target );
3341
34- Map <String , Path > seenModules = new HashMap <>();
42+ Map <String , Result > seenModules = new HashMap <>();
3543
3644 try (DirectoryStream <Path > stream = Files .newDirectoryStream (source , "*.jar" )) {
3745 for (Path jar : stream ) {
38- String moduleName = resolveModuleName (jar );
39- if (moduleName == null ) {
46+ var module = resolveModuleName (jar );
47+ if (module == null ) {
4048 System .out .println ("Skipping non-module JAR: " + jar );
4149 continue ;
4250 }
4351
44- if (!seenModules .containsKey (moduleName )) {
45- if (check (jar )) continue ;
52+ if (!seenModules .containsKey (module .name ())) {
4653 Path dest = target .resolve (jar .getFileName ());
4754 Files .copy (jar , dest , StandardCopyOption .REPLACE_EXISTING );
48- seenModules .put (moduleName , jar );
49- System .out .println ("Added module: " + moduleName + " from " + jar );
55+ seenModules .put (module . name (), module );
56+ System .out .println ("Added module: " + module . name () + " from " + jar );
5057 } else {
51- System .out .println ("Duplicate module ignored: " + moduleName + " from " + jar );
58+ if (seenModules .get (module .name ()).origin () == ModuleNameOrigin .GUESSED && module .origin () != ModuleNameOrigin .GUESSED ) {
59+ var oldModule = seenModules .get (module .name ());
60+ Path dest = target .resolve (jar .getFileName ());
61+ Files .copy (jar , dest , StandardCopyOption .REPLACE_EXISTING );
62+ seenModules .put (module .name (), module );
63+ System .out .println ("Swapped to module: " + module .name () + "to " + jar + " from" + oldModule .jar ());
64+ return ;
65+ }
66+
67+ System .out .println ("Duplicate module ignored: " + module .name () + " from " + jar );
5268 }
5369 }
5470 }
@@ -67,21 +83,33 @@ private static void deleteDirectory(Path dir) throws IOException {
6783 .forEach (File ::delete );
6884 }
6985
70- private static String resolveModuleName (Path jarPath ) {
86+ private static Result resolveModuleName (Path jarPath ) {
7187 try (JarFile jarFile = new JarFile (jarPath .toFile ())) {
7288 ZipEntry entry = jarFile .getEntry ("module-info.class" );
7389 if (entry != null ) {
7490 // This is a proper JPMS module JAR
75- return ModuleFinder .of (jarPath ).findAll ().iterator ().next ().descriptor ().name ();
91+ return new Result (
92+ ModuleFinder .of (jarPath ).findAll ().iterator ().next ().descriptor ().name (),
93+ ModuleNameOrigin .MODULE_INFO ,
94+ jarPath
95+ );
7696 } else {
7797 final var found = ModuleFinder .of (jarPath ).findAll ().stream ().findAny ();
7898 if (found .isPresent ()) {
79- return found .get ().descriptor ().name ();
99+ return new Result (
100+ found .get ().descriptor ().name (),
101+ ModuleNameOrigin .MANIFEST ,
102+ jarPath
103+ );
80104 }
81105
82106 // Fall back to heuristic based on filename (best effort)
83107 String filename = jarPath .getFileName ().toString ();
84- return filename .replaceAll ("-[\\ d\\ .]+.*\\ .jar$" , "" ).replaceAll ("\\ .jar$" , "" );
108+ return new Result (
109+ filename .replaceAll ("-[\\ d\\ .]+.*\\ .jar$" , "" ).replaceAll ("\\ .jar$" , "" ),
110+ ModuleNameOrigin .GUESSED ,
111+ jarPath
112+ );
85113 }
86114 } catch (IOException e ) {
87115 e .printStackTrace ();
0 commit comments