< prev index next >

src/java.base/share/classes/sun/launcher/LauncherHelper.java

Print this page
rev 50671 : [mq]: validate-modules


  27 
  28 /*
  29  *
  30  *  <p><b>This is NOT part of any API supported by Sun Microsystems.
  31  *  If you write code that depends on this, you do so at your own
  32  *  risk.  This code and its internal interfaces are subject to change
  33  *  or deletion without notice.</b>
  34  *
  35  */
  36 
  37 /**
  38  * A utility package for the java(1), javaw(1) launchers.
  39  * The following are helper methods that the native launcher uses
  40  * to perform checks etc. using JNI, see src/share/bin/java.c
  41  */
  42 import java.io.File;
  43 import java.io.IOException;
  44 import java.io.PrintStream;
  45 import java.io.UnsupportedEncodingException;
  46 import java.lang.module.Configuration;
  47 import java.lang.module.FindException;
  48 import java.lang.module.ModuleDescriptor;
  49 import java.lang.module.ModuleDescriptor.Requires;
  50 import java.lang.module.ModuleDescriptor.Exports;
  51 import java.lang.module.ModuleDescriptor.Opens;
  52 import java.lang.module.ModuleDescriptor.Provides;
  53 import java.lang.module.ModuleFinder;
  54 import java.lang.module.ModuleReference;
  55 import java.lang.module.ResolvedModule;
  56 import java.lang.reflect.InvocationTargetException;
  57 import java.lang.reflect.Method;
  58 import java.lang.reflect.Modifier;
  59 import java.math.BigDecimal;
  60 import java.math.RoundingMode;
  61 import java.net.URI;
  62 import java.nio.charset.Charset;
  63 import java.nio.file.DirectoryStream;
  64 import java.nio.file.Files;
  65 import java.nio.file.NoSuchFileException;
  66 import java.nio.file.Path;
  67 import java.nio.file.Paths;
  68 import java.nio.file.attribute.BasicFileAttributes;
  69 import java.text.Normalizer;
  70 import java.text.MessageFormat;
  71 import java.util.ArrayList;
  72 import java.util.Collections;
  73 import java.util.Comparator;
  74 import java.util.HashMap;
  75 import java.util.Iterator;
  76 import java.util.List;
  77 import java.util.Locale;
  78 import java.util.Locale.Category;
  79 import java.util.Map;
  80 import java.util.Optional;
  81 import java.util.Properties;
  82 import java.util.ResourceBundle;
  83 import java.util.Set;
  84 import java.util.TreeSet;
  85 import java.util.jar.Attributes;
  86 import java.util.jar.JarFile;
  87 import java.util.jar.Manifest;
  88 import java.util.stream.Collectors;
  89 import java.util.stream.Stream;
  90 
  91 import jdk.internal.misc.VM;
  92 import jdk.internal.module.ModuleBootstrap;
  93 import jdk.internal.module.Modules;
  94 import jdk.internal.platform.Container;
  95 import jdk.internal.platform.Metrics;
  96 
  97 
  98 public final class LauncherHelper {
  99 


1195             if (isJrt(a)) {
1196                 return isJrt(b) ? real.compare(a, b) : -1;
1197             } else {
1198                 return isJrt(b) ? 1 : real.compare(a, b);
1199             }
1200         }
1201     }
1202 
1203     private static <T> Stream<String> toStringStream(Set<T> s) {
1204         return s.stream().map(e -> e.toString().toLowerCase());
1205     }
1206 
1207     private static boolean isJrt(ModuleReference mref) {
1208         return isJrt(mref.location().orElse(null));
1209     }
1210 
1211     private static boolean isJrt(URI uri) {
1212         return (uri != null && uri.getScheme().equalsIgnoreCase("jrt"));
1213     }
1214 
1215     /**
1216      * Called by the launcher to validate the modules on the upgrade and
1217      * application module paths.
1218      *
1219      * @return {@code true} if no errors are found
1220      */
1221     private static boolean validateModules() {
1222         initOutput(System.out);
1223 
1224         ModuleValidator validator = new ModuleValidator();
1225 
1226         // upgrade module path
1227         String value = System.getProperty("jdk.module.upgrade.path");
1228         if (value != null) {
1229             Stream.of(value.split(File.pathSeparator))
1230                     .map(Paths::get)
1231                     .forEach(validator::scan);
1232         }
1233 
1234         // system modules
1235         ModuleFinder.ofSystem().findAll().stream()
1236                 .sorted(Comparator.comparing(ModuleReference::descriptor))
1237                 .forEach(validator::process);
1238 
1239         // application module path
1240         value = System.getProperty("jdk.module.path");
1241         if (value != null) {
1242             Stream.of(value.split(File.pathSeparator))
1243                     .map(Paths::get)
1244                     .forEach(validator::scan);
1245         }
1246 
1247         return !validator.foundErrors();
1248     }
1249 
1250     /**
1251      * A simple validator to check for errors and conflicts between modules.
1252      */
1253     static class ModuleValidator {
1254         private static final String MODULE_INFO = "module-info.class";
1255 
1256         private Map<String, ModuleReference> nameToModule = new HashMap<>();
1257         private Map<String, ModuleReference> packageToModule = new HashMap<>();
1258         private boolean errorFound;
1259 
1260         /**
1261          * Returns true if at least one error was found
1262          */
1263         boolean foundErrors() {
1264             return errorFound;
1265         }
1266 
1267         /**
1268          * Prints the module location and name.
1269          */
1270         private void printModule(ModuleReference mref) {
1271             mref.location()
1272                 .filter(uri -> !isJrt(uri))
1273                 .ifPresent(uri -> ostream.print(uri + " "));
1274             ModuleDescriptor descriptor = mref.descriptor();
1275             ostream.print(descriptor.name());
1276             if (descriptor.isAutomatic())
1277                 ostream.print(" automatic");
1278             ostream.println();
1279         }
1280 
1281         /**
1282          * Prints the module location and name, checks if the module is
1283          * shadowed by a previously seen module, and finally checks for
1284          * package conflicts with previously seen modules.
1285          */
1286         void process(ModuleReference mref) {
1287             printModule(mref);
1288 
1289             String name = mref.descriptor().name();
1290             ModuleReference previous = nameToModule.putIfAbsent(name, mref);
1291             if (previous != null) {
1292                 ostream.print(INDENT + "shadowed by ");
1293                 printModule(previous);
1294             } else {
1295                 // check for package conflicts when not shadowed
1296                 for (String pkg :  mref.descriptor().packages()) {
1297                     previous = packageToModule.putIfAbsent(pkg, mref);
1298                     if (previous != null) {
1299                         String mn = previous.descriptor().name();
1300                         ostream.println(INDENT + "contains " + pkg
1301                                         + " conflicts with module " + mn);
1302                         errorFound = true;
1303                     }
1304                 }
1305             }
1306         }
1307 
1308         /**
1309          * Scan an element on a module path. The element is a directory
1310          * of modules, an exploded module, or a JAR file.
1311          */
1312         void scan(Path entry) {
1313             BasicFileAttributes attrs;
1314             try {
1315                 attrs = Files.readAttributes(entry, BasicFileAttributes.class);
1316             } catch (NoSuchFileException ignore) {
1317                 return;
1318             } catch (IOException ioe) {
1319                 ostream.println(entry + " " + ioe);
1320                 errorFound = true;
1321                 return;
1322             }
1323 
1324             String fn = entry.getFileName().toString();
1325             if (attrs.isRegularFile() && fn.endsWith(".jar")) {
1326                 // JAR file, explicit or automatic module
1327                 scanModule(entry).ifPresent(this::process);
1328             } else if (attrs.isDirectory()) {
1329                 Path mi = entry.resolve(MODULE_INFO);
1330                 if (Files.exists(mi)) {
1331                     // exploded module
1332                     scanModule(entry).ifPresent(this::process);
1333                 } else {
1334                     // directory of modules
1335                     scanDirectory(entry);
1336                 }
1337             }
1338         }
1339 
1340         /**
1341          * Scan the JAR files and exploded modules in a directory.
1342          */
1343         private void scanDirectory(Path dir) {
1344             try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
1345                 Map<String, Path> moduleToEntry = new HashMap<>();
1346 
1347                 for (Path entry : stream) {
1348                     BasicFileAttributes attrs;
1349                     try {
1350                         attrs = Files.readAttributes(entry, BasicFileAttributes.class);
1351                     } catch (IOException ioe) {
1352                         ostream.println(entry + " " + ioe);
1353                         errorFound = true;
1354                         continue;
1355                     }
1356 
1357                     ModuleReference mref = null;
1358 
1359                     String fn = entry.getFileName().toString();
1360                     if (attrs.isRegularFile() && fn.endsWith(".jar")) {
1361                         mref = scanModule(entry).orElse(null);
1362                     } else if (attrs.isDirectory()) {
1363                         Path mi = entry.resolve(MODULE_INFO);
1364                         if (Files.exists(mi)) {
1365                             mref = scanModule(entry).orElse(null);
1366                         }
1367                     }
1368 
1369                     if (mref != null) {
1370                         String name = mref.descriptor().name();
1371                         Path previous = moduleToEntry.putIfAbsent(name, entry);
1372                         if (previous != null) {
1373                             // same name as other module in the directory
1374                             printModule(mref);
1375                             ostream.println(INDENT + "contains same module as "
1376                                             + previous.getFileName());
1377                             errorFound = true;
1378                         } else {
1379                             process(mref);
1380                         }
1381                     }
1382                 }
1383             } catch (IOException ioe) {
1384                 ostream.println(dir + " " + ioe);
1385                 errorFound = true;
1386             }
1387         }
1388 
1389         /**
1390          * Scan a JAR file or exploded module.
1391          */
1392         private Optional<ModuleReference> scanModule(Path entry) {
1393             ModuleFinder finder = ModuleFinder.of(entry);
1394             try {
1395                 return finder.findAll().stream().findFirst();
1396             } catch (FindException e) {
1397                 ostream.println(entry);
1398                 ostream.println(INDENT + e.getMessage());
1399                 Throwable cause = e.getCause();
1400                 if (cause != null) {
1401                     ostream.println(INDENT + cause);
1402                 }
1403                 errorFound = true;
1404                 return Optional.empty();
1405             }
1406         }
1407     }
1408 }


  27 
  28 /*
  29  *
  30  *  <p><b>This is NOT part of any API supported by Sun Microsystems.
  31  *  If you write code that depends on this, you do so at your own
  32  *  risk.  This code and its internal interfaces are subject to change
  33  *  or deletion without notice.</b>
  34  *
  35  */
  36 
  37 /**
  38  * A utility package for the java(1), javaw(1) launchers.
  39  * The following are helper methods that the native launcher uses
  40  * to perform checks etc. using JNI, see src/share/bin/java.c
  41  */
  42 import java.io.File;
  43 import java.io.IOException;
  44 import java.io.PrintStream;
  45 import java.io.UnsupportedEncodingException;
  46 import java.lang.module.Configuration;

  47 import java.lang.module.ModuleDescriptor;
  48 import java.lang.module.ModuleDescriptor.Requires;
  49 import java.lang.module.ModuleDescriptor.Exports;
  50 import java.lang.module.ModuleDescriptor.Opens;
  51 import java.lang.module.ModuleDescriptor.Provides;
  52 import java.lang.module.ModuleFinder;
  53 import java.lang.module.ModuleReference;
  54 import java.lang.module.ResolvedModule;
  55 import java.lang.reflect.InvocationTargetException;
  56 import java.lang.reflect.Method;
  57 import java.lang.reflect.Modifier;
  58 import java.math.BigDecimal;
  59 import java.math.RoundingMode;
  60 import java.net.URI;
  61 import java.nio.charset.Charset;
  62 import java.nio.file.DirectoryStream;
  63 import java.nio.file.Files;

  64 import java.nio.file.Path;


  65 import java.text.Normalizer;
  66 import java.text.MessageFormat;
  67 import java.util.ArrayList;
  68 import java.util.Collections;
  69 import java.util.Comparator;

  70 import java.util.Iterator;
  71 import java.util.List;
  72 import java.util.Locale;
  73 import java.util.Locale.Category;

  74 import java.util.Optional;
  75 import java.util.Properties;
  76 import java.util.ResourceBundle;
  77 import java.util.Set;
  78 import java.util.TreeSet;
  79 import java.util.jar.Attributes;
  80 import java.util.jar.JarFile;
  81 import java.util.jar.Manifest;
  82 import java.util.stream.Collectors;
  83 import java.util.stream.Stream;
  84 
  85 import jdk.internal.misc.VM;
  86 import jdk.internal.module.ModuleBootstrap;
  87 import jdk.internal.module.Modules;
  88 import jdk.internal.platform.Container;
  89 import jdk.internal.platform.Metrics;
  90 
  91 
  92 public final class LauncherHelper {
  93 


1189             if (isJrt(a)) {
1190                 return isJrt(b) ? real.compare(a, b) : -1;
1191             } else {
1192                 return isJrt(b) ? 1 : real.compare(a, b);
1193             }
1194         }
1195     }
1196 
1197     private static <T> Stream<String> toStringStream(Set<T> s) {
1198         return s.stream().map(e -> e.toString().toLowerCase());
1199     }
1200 
1201     private static boolean isJrt(ModuleReference mref) {
1202         return isJrt(mref.location().orElse(null));
1203     }
1204 
1205     private static boolean isJrt(URI uri) {
1206         return (uri != null && uri.getScheme().equalsIgnoreCase("jrt"));
1207     }
1208 

































































































































































































1209 }
< prev index next >