@@ -103,6 +103,9 @@ public void generatePropertiesFile() throws IOException {
103103        }
104104    }
105105
106+     // build the association for a class to a module; 
107+     // there are different methods for finding these depending on if the 
108+     // classpath entry is a jar or a directory 
106109    private  Map <String , String > buildClassesToModules () throws  IOException  {
107110        Map <String , String > classesToModules  = new  HashMap <>();
108111        for  (File  file  : getCodeLocations ().get ().getFiles ()) {
@@ -119,6 +122,7 @@ private Map<String, String> buildClassesToModules() throws IOException {
119122        return  classesToModules ;
120123    }
121124
125+     // find the first class and module when the class path entry is a jar 
122126    private  void  extractFromJar (File  file , Map <String , String > classesToModules ) throws  IOException  {
123127        try  (JarFile  jarFile  = new  JarFile (file )) {
124128            String  className  = extractClassNameFromJar (jarFile );
@@ -130,21 +134,32 @@ private void extractFromJar(File file, Map<String, String> classesToModules) thr
130134        }
131135    }
132136
137+     // look through the jar to find the first unique class that isn't 
138+     // in META-INF (those may not be unique) and isn't module-info.class 
139+     // (which is also not unique) and avoid anonymous classes 
133140    private  String  extractClassNameFromJar (JarFile  jarFile ) {
134141        return  jarFile .stream ()
135142            .filter (
136143                je  -> je .getName ().startsWith ("META-INF" ) == false 
137144                    && je .getName ().equals ("module-info.class" ) == false 
145+                     && je .getName ().contains ("$" ) == false 
138146                    && je .getName ().endsWith (".class" )
139147            )
140148            .findFirst ()
141149            .map (ZipEntry ::getName )
142150            .orElse (null );
143151    }
144152
153+     // look through the jar for the module name with 
154+     // each step commented inline 
145155    private  String  extractModuleNameFromJar (File  file , JarFile  jarFile ) throws  IOException  {
146156        String  moduleName  = null ;
147157
158+         // if the jar is multi-release, there will be a set versions 
159+         // under the path META-INF/versions/<version number>; 
160+         // each version will have its own module-info.class if this is a modular jar; 
161+         // look for the module name in the module-info from the latest version 
162+         // fewer than or equal to the current JVM version 
148163        if  (jarFile .isMultiRelease ()) {
149164            List <Integer > versions  = jarFile .stream ()
150165                .filter (je  -> je .getName ().startsWith ("META-INF/versions/" ) && je .getName ().endsWith ("/module-info.class" ))
@@ -172,6 +187,8 @@ private String extractModuleNameFromJar(File file, JarFile jarFile) throws IOExc
172187            }
173188        }
174189
190+         // if the jar is *not* multi-release then first look in 
191+         // module-info.class from the top-level if it exists 
175192        if  (moduleName  == null ) {
176193            JarEntry  moduleEntry  = jarFile .getJarEntry ("module-info.class" );
177194            if  (moduleEntry  != null ) {
@@ -181,6 +198,8 @@ private String extractModuleNameFromJar(File file, JarFile jarFile) throws IOExc
181198            }
182199        }
183200
201+         // if the jar does *not* contain module-info.class 
202+         // check the manifest file for the module name 
184203        if  (moduleName  == null ) {
185204            JarEntry  manifestEntry  = jarFile .getJarEntry ("META-INF/MANIFEST.MF" );
186205            if  (manifestEntry  != null ) {
@@ -194,6 +213,8 @@ private String extractModuleNameFromJar(File file, JarFile jarFile) throws IOExc
194213            }
195214        }
196215
216+         // if the jar does not have module-info.class and no module name in the manifest 
217+         // default to the jar name without .jar and no versioning 
197218        if  (moduleName  == null ) {
198219            String  jn  = file .getName ().substring (0 , file .getName ().length () - 4 );
199220            Matcher  matcher  = Pattern .compile ("-(\\ d+(\\ .|$))" ).matcher (jn );
@@ -207,14 +228,18 @@ private String extractModuleNameFromJar(File file, JarFile jarFile) throws IOExc
207228        return  moduleName ;
208229    }
209230
231+     // find the first class and module when the class path entry is a directory 
210232    private  void  extractFromDirectory (File  file , Map <String , String > classesToModules ) throws  IOException  {
211233        String  className  = extractClassNameFromDirectory (file );
212234        String  moduleName  = extractModuleNameFromDirectory (file );
235+ 
213236        if  (className  != null  && moduleName  != null ) {
214237            classesToModules .put (className , moduleName );
215238        }
216239    }
217240
241+     // look through the directory to find the first unique class that isn't 
242+     // module-info.class (which may not be unique) and avoid anonymous classes 
218243    private  String  extractClassNameFromDirectory (File  file ) {
219244        List <File > files  = new  ArrayList <>(List .of (file ));
220245        while  (files .isEmpty () == false ) {
@@ -233,6 +258,8 @@ private String extractClassNameFromDirectory(File file) {
233258        return  null ;
234259    }
235260
261+     // look through the directory to find the module name in either module-info.class 
262+     // if it exists or the preset one derived from the jar task 
236263    private  String  extractModuleNameFromDirectory (File  file ) throws  IOException  {
237264        List <File > files  = new  ArrayList <>(List .of (file ));
238265        while  (files .isEmpty () == false ) {
@@ -250,6 +277,8 @@ private String extractModuleNameFromDirectory(File file) throws IOException {
250277        return  getModuleName ().isPresent () ? getModuleName ().get () : null ;
251278    }
252279
280+     // a helper method to extract the module name from module-info.class 
281+     // using an ASM ClassVisitor 
253282    private  String  extractModuleNameFromModuleInfo (InputStream  inputStream ) throws  IOException  {
254283        String [] moduleName  = new  String [1 ];
255284        ClassReader  cr  = new  ClassReader (inputStream );
0 commit comments