-
Notifications
You must be signed in to change notification settings - Fork 6.1k
8356645: Javac should utilize new ZIP file system read-only access mode #25639
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,10 +51,8 @@ | |
import javax.annotation.processing.Processor; | ||
import javax.tools.ForwardingJavaFileObject; | ||
import javax.tools.JavaFileManager; | ||
import javax.tools.JavaFileManager.Location; | ||
import javax.tools.JavaFileObject; | ||
import javax.tools.JavaFileObject.Kind; | ||
import javax.tools.StandardJavaFileManager; | ||
import javax.tools.StandardLocation; | ||
|
||
import com.sun.source.util.Plugin; | ||
|
@@ -96,6 +94,14 @@ public PlatformDescription getPlatformTrusted(String platformName) { | |
|
||
private static final String[] symbolFileLocation = { "lib", "ct.sym" }; | ||
|
||
// These must match attributes defined in ZipFileSystem.java. | ||
private static final Map<String, ?> CT_SYM_ZIP_ENV = Map.of( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Didn't use FSInfo here, even though it's mostly the same logic, because the symbol file is a ZIP, not a JAR, so naming gets a little muddled, and in this case there's no runtime info, so I can just make a constant map. |
||
// Symbol file should always be opened read-only. | ||
"accessMode", "readOnly", | ||
// Uses less accurate, but faster, timestamp information | ||
// (nobody should care about timestamps in the CT symbol file). | ||
"zipinfo-time", "false"); | ||
|
||
private static final Set<String> SUPPORTED_JAVA_PLATFORM_VERSIONS; | ||
public static final Comparator<String> NUMERICAL_COMPARATOR = (s1, s2) -> { | ||
int i1; | ||
|
@@ -117,7 +123,7 @@ public PlatformDescription getPlatformTrusted(String platformName) { | |
SUPPORTED_JAVA_PLATFORM_VERSIONS = new TreeSet<>(NUMERICAL_COMPARATOR); | ||
Path ctSymFile = findCtSym(); | ||
if (Files.exists(ctSymFile)) { | ||
try (FileSystem fs = FileSystems.newFileSystem(ctSymFile, (ClassLoader)null); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Several places in existing code pass "(ClassLoader) null", which by inspection makes no difference compared to simply not passing the parameter, so I took the decision to remove it for neatness. |
||
try (FileSystem fs = FileSystems.newFileSystem(ctSymFile, CT_SYM_ZIP_ENV); | ||
DirectoryStream<Path> dir = | ||
Files.newDirectoryStream(fs.getRootDirectories().iterator().next())) { | ||
for (Path section : dir) { | ||
|
@@ -249,7 +255,11 @@ public String inferBinaryName(Location location, JavaFileObject file) { | |
try { | ||
FileSystem fs = ctSym2FileSystem.get(file); | ||
if (fs == null) { | ||
ctSym2FileSystem.put(file, fs = FileSystems.newFileSystem(file, (ClassLoader)null)); | ||
fs = FileSystems.newFileSystem(file, CT_SYM_ZIP_ENV); | ||
// If for any reason this was not opened from a ZIP file, | ||
// then the resulting file system would not be read-only. | ||
assert fs.isReadOnly(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if an assert is the right thing here or if this should be an always-on runtime check (it can be provoked by having a non-ZIP symbol file, but it's not sanctioned in any way). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We typically don't use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmmm .... question: The other place using FSInfo static method was the cySym verifier. And this is the cySym code. So it feels like it would be good to be consistent between both these cases. So is this a place for FSInfo as well, or not? The advantage of FSInfo is that you can get the JAR provider (which we know is the ZIP provider too) and not have to worry about mismatches between given file and "discovered" file system type. You just only use the JAR provider and you're done. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I removed the FSInfo use in the test, just not worth the dependency. |
||
ctSym2FileSystem.put(file, fs); | ||
} | ||
|
||
Path root = fs.getRootDirectories().iterator().next(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,6 +37,7 @@ | |
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.stream.Collectors; | ||
import java.util.zip.ZipEntry; | ||
import java.util.zip.ZipOutputStream; | ||
|
@@ -160,7 +161,7 @@ List<Path> getTestFilePaths() throws IOException { | |
List<Path> getTestZipPaths() throws IOException { | ||
if (zipfs == null) { | ||
Path testZip = createSourceZip(); | ||
zipfs = FileSystems.newFileSystem(testZip); | ||
zipfs = FileSystems.newFileSystem(testZip, Map.of("accessMode", "readOnly")); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not strictly necessary, but seems like a good idea to use read-only for testing. |
||
closeables.add(zipfs); | ||
zipPaths = Files.list(zipfs.getRootDirectories().iterator().next()) | ||
.filter(p -> p.getFileName().toString().endsWith(".java")) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,13 +27,17 @@ | |
* @summary Verify classfile inside ct.sym | ||
* @library /tools/lib | ||
* @modules jdk.compiler/com.sun.tools.javac.api | ||
* jdk.compiler/com.sun.tools.javac.file | ||
* jdk.compiler/com.sun.tools.javac.main | ||
* jdk.compiler/com.sun.tools.javac.platform | ||
* jdk.compiler/com.sun.tools.javac.util:+open | ||
* @build toolbox.ToolBox VerifyCTSymClassFiles | ||
* @run main VerifyCTSymClassFiles | ||
*/ | ||
|
||
import com.sun.tools.javac.file.FSInfo; | ||
import com.sun.tools.javac.util.Context; | ||
|
||
import java.io.IOException; | ||
import java.io.UncheckedIOException; | ||
import java.lang.classfile.ClassFile; | ||
|
@@ -53,14 +57,17 @@ public static void main(String... args) throws IOException, URISyntaxException { | |
t.checkClassFiles(); | ||
} | ||
|
||
private final FSInfo fsInfo = FSInfo.instance(new Context()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this is actually right unless we make the other cySym code use FSInfo. Happy to hear people's thoughts on this. One benefit here is that we know we've matched the expected ZIP file with the ZIP file system provider, so no need to worry if the environment was going to be honoured. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I changed both case (test and code) to NOT use FSInfo now. The dependency and extra code (esp. now the method is an instance method) just doesn't seem worth it. |
||
|
||
void checkClassFiles() throws IOException { | ||
Path ctSym = Paths.get(System.getProperty("java.home"), "lib", "ct.sym"); | ||
|
||
if (!Files.exists(ctSym)) { | ||
//no ct.sym, nothing to check: | ||
return ; | ||
} | ||
try (FileSystem fs = FileSystems.newFileSystem(ctSym)) { | ||
// Expected to always be a ZIP filesystem. | ||
try (var fs = fsInfo.getJarFSProvider().newFileSystem(ctSym, fsInfo.readOnlyJarFSEnv(null))) { | ||
Files.walk(fs.getRootDirectories().iterator().next()) | ||
.filter(p -> Files.isRegularFile(p)) | ||
.forEach(p -> checkClassFile(p)); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added comment just to pull out the fact that we might not be able to promise that all ArchiveContainer instances are backed by a read-only file system, and the compiler still has a duty not to attempt any modification.