Skip to content
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

Improve file last modified time detection #61

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 56 additions & 6 deletions src/main/java/org/glassfish/wasp/compiler/Compiler.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, 2022 Contributors to the Eclipse Foundation.
* Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation.
* Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright 2004 The Apache Software Foundation
* Copyright (c) 2022 Contributors to the Eclipse Foundation
Expand All @@ -20,14 +20,20 @@
package org.glassfish.wasp.compiler;

import static java.util.logging.Level.FINE;
import static java.util.logging.Level.SEVERE;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
Expand Down Expand Up @@ -461,9 +467,9 @@ public boolean isOutDated(boolean checkClass) {
targetFile = new File(pagesCompilationContext.getServletJavaFileName());
}

// Get the target file's last modified time. File.lastModified()
// returns 0 if the file does not exist.
long targetLastModified = targetFile.lastModified();
// Get the target file's last modified time.
// getLastModifiedTime() returns 0 if the file does not exist.
long targetLastModified = getLastModifiedTime(targetFile);

// Check cached class file
if (checkClass) {
Expand All @@ -484,7 +490,7 @@ public boolean isOutDated(boolean checkClass) {
}

// Check if the Pages file exists in the filesystem (instead of a jar
// or a remote location). If yes, then do a File.lastModified()
// or a remote location). If yes, then do a getLastModifiedTime()
// to determine its last modified time. This is more performant
// (fewer stat calls) than the ctxt.getResource() followed by
// openConnection(). However, it only works for file system jsps.
Expand All @@ -493,7 +499,7 @@ public boolean isOutDated(boolean checkClass) {
if (pagesServletWrapper != null) {
File jspFile = pagesServletWrapper.getJspFile();
if (jspFile != null) {
jspRealLastModified = jspFile.lastModified();
jspRealLastModified = getLastModifiedTime(jspFile);
}
}

Expand Down Expand Up @@ -577,6 +583,50 @@ public boolean isOutDated(boolean checkClass) {

}

/**
* Returns a file's last modified time.
*
* <p>The {@code 0L} time stamp may be returned when:
* <ul>
* <li>Basic attribute view is not available for {@code file}.</li>
* <li>Creation time stamp and last modified time stamp not implemented for {@code file}.</li>
* <li>An I/O error occurred.</li>
* </ul>
*
* <p>If numeric overflow occurs, returns Long.MIN_VALUE if negative and Long.MAX_VALUE if positive.
*
* @param file file to read attributes from
* @return a time stamp representing the time the file was last modified
*/
private long getLastModifiedTime(File file) {
BasicFileAttributeView attributeView = Files.getFileAttributeView(file.toPath(), BasicFileAttributeView.class);
if (attributeView == null) {
log.log(SEVERE, "Basic attribute view is not available for " + file.getAbsolutePath());
return 0L;
}

BasicFileAttributes attributes;
try {
attributes = attributeView.readAttributes();
} catch (IOException e) {
avpinchuk marked this conversation as resolved.
Show resolved Hide resolved
log.log(SEVERE, "Failed to read attributes for file " + file.getAbsolutePath(), e);
return 0L;
}

FileTime creationTime = attributes.creationTime();
FileTime lastModifiedTime = attributes.lastModifiedTime();

if (creationTime == null) {
return lastModifiedTime != null ? lastModifiedTime.toMillis() : 0L;
}

if (lastModifiedTime == null) {
return creationTime.toMillis();
}

return creationTime.compareTo(lastModifiedTime) <= 0 ? lastModifiedTime.toMillis() : creationTime.toMillis();
}

/**
* Gets the error dispatcher.
*/
Expand Down