|
78 | 78 | import java.io.File; |
79 | 79 | import java.io.IOException; |
80 | 80 | import java.io.InputStream; |
| 81 | +import java.net.URI; |
81 | 82 | import java.net.URISyntaxException; |
82 | 83 | import java.net.URL; |
| 84 | +import java.nio.file.FileSystem; |
| 85 | +import java.nio.file.FileSystems; |
| 86 | +import java.nio.file.Files; |
83 | 87 | import java.util.ArrayList; |
84 | 88 | import java.util.Arrays; |
85 | 89 | import java.util.Collection; |
@@ -384,13 +388,20 @@ private static class INameEnvironmentImpl implements INameEnvironment { |
384 | 388 |
|
385 | 389 | private final Map<String, CompiledClass> internalTypes; |
386 | 390 |
|
| 391 | + private final FileSystem jrt = FileSystems.getFileSystem(URI.create("jrt:/")); |
| 392 | + |
387 | 393 | public INameEnvironmentImpl(Set<String> packages, Map<String, CompiledClass> internalTypes) { |
388 | 394 | this.packages = packages; |
389 | 395 | this.internalTypes = internalTypes; |
390 | 396 | } |
391 | 397 |
|
392 | 398 | @Override |
393 | 399 | public void cleanup() { |
| 400 | + try { |
| 401 | + jrt.close(); |
| 402 | + } catch (IOException e) { |
| 403 | + // Ignore failure to close read-only jrt file system |
| 404 | + } |
394 | 405 | } |
395 | 406 |
|
396 | 407 | @Override |
@@ -547,8 +558,8 @@ private NameEnvironmentAnswer doFindTypeInClassPath(String internalName) { |
547 | 558 |
|
548 | 559 | ClassFileReader classFileReader = |
549 | 560 | ClassFileReader.read(openStream, resource.toExternalForm(), true); |
550 | | - // In case insensitive file systems we might have found a resource whose name is different |
551 | | - // in case and should not be returned as an answer. |
| 561 | + // In case-insensitive file systems we might have found a resource whose name is |
| 562 | + // different in case and should not be returned as an answer. |
552 | 563 | if (internalName.equals(CharOperation.charToString(classFileReader.getName()))) { |
553 | 564 | return new NameEnvironmentAnswer(classFileReader, null); |
554 | 565 | } |
@@ -606,14 +617,40 @@ private boolean isPackage(String slashedPackageName) { |
606 | 617 | return false; |
607 | 618 | } |
608 | 619 | // Include class loader check for binary-only annotations. |
609 | | - if (caseSensitivePathExists(slashedPackageName)) { |
| 620 | + if (caseSensitivePackageExists(slashedPackageName)) { |
610 | 621 | addPackages(packages, slashedPackageName); |
611 | 622 | return true; |
612 | 623 | } else { |
613 | 624 | notPackages.add(slashedPackageName); |
614 | 625 | return false; |
615 | 626 | } |
616 | 627 | } |
| 628 | + |
| 629 | + private boolean caseSensitivePackageExists(String slashedPackage) { |
| 630 | + URL resourceURL = getClassLoader().getResource(slashedPackage + '/'); |
| 631 | + if (resourceURL == null) { |
| 632 | + // Can't be found in jars or class directories - might be system defined, test jrt |
| 633 | + String pkg = slashedPackage.replace('/', '.'); |
| 634 | + // This check is always case-sensitive - we're looking inside the modules, rather than on |
| 635 | + // the host file system, so no additional checks are needed. |
| 636 | + return Files.exists(jrt.getPath("/packages", pkg)); |
| 637 | + } |
| 638 | + |
| 639 | + try { |
| 640 | + File resourceFile = new File(resourceURL.toURI()); |
| 641 | + return Arrays.asList(resourceFile.getParentFile().list()).contains(resourceFile.getName()); |
| 642 | + } catch (URISyntaxException e) { |
| 643 | + // The URL can not be converted to a URI. |
| 644 | + } catch (IllegalArgumentException e) { |
| 645 | + // A file instance can not be constructed from a URI. |
| 646 | + } |
| 647 | + |
| 648 | + // Some exception occurred while trying to make sure the name for the resource on disk is |
| 649 | + // exactly the same as the one requested including case. If an exception is thrown in the |
| 650 | + // process we assume that the URI does not refer to a resource in the filesystem and that the |
| 651 | + // resource obtained from the classloader is the one requested. |
| 652 | + return true; |
| 653 | + } |
617 | 654 | } |
618 | 655 |
|
619 | 656 | /** |
@@ -1091,28 +1128,6 @@ private static void addPackages(Set<String> packages, String slashedPackageName) |
1091 | 1128 | } |
1092 | 1129 | } |
1093 | 1130 |
|
1094 | | - private static boolean caseSensitivePathExists(String resourcePath) { |
1095 | | - URL resourceURL = getClassLoader().getResource(resourcePath + '/'); |
1096 | | - if (resourceURL == null) { |
1097 | | - return false; |
1098 | | - } |
1099 | | - |
1100 | | - try { |
1101 | | - File resourceFile = new File(resourceURL.toURI()); |
1102 | | - return Arrays.asList(resourceFile.getParentFile().list()).contains(resourceFile.getName()); |
1103 | | - } catch (URISyntaxException e) { |
1104 | | - // The URL can not be converted to a URI. |
1105 | | - } catch (IllegalArgumentException e) { |
1106 | | - // A file instance can not be constructed from a URI. |
1107 | | - } |
1108 | | - |
1109 | | - // Some exception occurred while trying to make sure the name for the resource on disk is |
1110 | | - // exactly the same as the one requested including case. If an exception is thrown in the |
1111 | | - // process we assume that the URI does not refer to a resource in the filesystem and that the |
1112 | | - // resource obtained from the classloader is the one requested. |
1113 | | - return true; |
1114 | | - } |
1115 | | - |
1116 | 1131 | private static ClassLoader getClassLoader() { |
1117 | 1132 | return Thread.currentThread().getContextClassLoader(); |
1118 | 1133 | } |
|
0 commit comments