aboutsummaryrefslogtreecommitdiffstats
path: root/server/src
diff options
context:
space:
mode:
authorAnna Koskinen <Ansku@users.noreply.github.com>2021-08-06 17:37:46 +0300
committerGitHub <noreply@github.com>2021-08-06 17:37:46 +0300
commitb1036f69cf0fc8d4bb1dc33df4e7aae0296a00cd (patch)
treec2d8b69d567074a3529d52d1ffec03fba1faf9b9 /server/src
parent724a1564de9a02ebc6e2a59e5faf04084d493a41 (diff)
downloadvaadin-framework-b1036f69cf0fc8d4bb1dc33df4e7aae0296a00cd.tar.gz
vaadin-framework-b1036f69cf0fc8d4bb1dc33df4e7aae0296a00cd.zip
fix: Reuse existing filesystem (#12346) (#12362)
Modified cherry-pick of https://github.com/vaadin/flow/pull/11428
Diffstat (limited to 'server/src')
-rw-r--r--server/src/main/java/com/vaadin/server/VaadinServlet.java33
-rw-r--r--server/src/test/java/com/vaadin/server/VaadinServletTest.java54
2 files changed, 71 insertions, 16 deletions
diff --git a/server/src/main/java/com/vaadin/server/VaadinServlet.java b/server/src/main/java/com/vaadin/server/VaadinServlet.java
index 3ddbd956e9..b418b5dd3f 100644
--- a/server/src/main/java/com/vaadin/server/VaadinServlet.java
+++ b/server/src/main/java/com/vaadin/server/VaadinServlet.java
@@ -39,6 +39,7 @@ import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystem;
+import java.nio.file.FileSystemAlreadyExistsException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -197,8 +198,12 @@ public class VaadinServlet extends HttpServlet implements Constants {
private VaadinServletService servletService;
- // Mapped uri is for the jar file
- static final Map<URI, Integer> openFileSystems = new HashMap<>();
+ /**
+ * Mapped uri is for the jar file.
+ * <p>
+ * FOR INTERNAL USE ONLY, may get renamed or removed.
+ */
+ static final Map<URI, Integer> OPEN_FILE_SYSTEMS = new HashMap<>();
private static final Object fileSystemLock = new Object();
/**
@@ -1364,29 +1369,41 @@ public class VaadinServlet extends HttpServlet implements Constants {
+ " and will determine this as not a folder");
}
- Integer locks = openFileSystems.computeIfPresent(fileURI,
+ Integer locks = OPEN_FILE_SYSTEMS.computeIfPresent(fileURI,
(key, value) -> value + 1);
if (locks != null) {
// Get filesystem is for the file to get the correct provider
return FileSystems.getFileSystem(resourceURI);
}
// Opened filesystem is for the file to get the correct provider
- FileSystem fileSystem = FileSystems.newFileSystem(resourceURI,
- Collections.emptyMap());
- openFileSystems.put(fileURI, 1);
+ FileSystem fileSystem = getNewOrExistingFileSystem(resourceURI);
+ OPEN_FILE_SYSTEMS.put(fileURI, 1);
return fileSystem;
}
}
+ private FileSystem getNewOrExistingFileSystem(URI resourceURI)
+ throws IOException {
+ try {
+ return FileSystems.newFileSystem(resourceURI,
+ Collections.emptyMap());
+ } catch (FileSystemAlreadyExistsException fsaee) {
+ getLogger().log(Level.FINER,
+ "Tried to get new filesystem, but it already existed for target uri.",
+ fsaee);
+ return FileSystems.getFileSystem(resourceURI);
+ }
+ }
+
// Package protected for feature verification purpose
void closeFileSystem(URI resourceURI) {
synchronized (fileSystemLock) {
try {
URI fileURI = getFileURI(resourceURI);
- Integer locks = openFileSystems.computeIfPresent(fileURI,
+ Integer locks = OPEN_FILE_SYSTEMS.computeIfPresent(fileURI,
(key, value) -> value - 1);
if (locks != null && locks == 0) {
- openFileSystems.remove(fileURI);
+ OPEN_FILE_SYSTEMS.remove(fileURI);
// Get filesystem is for the file to get the correct
// provider
FileSystems.getFileSystem(resourceURI).close();
diff --git a/server/src/test/java/com/vaadin/server/VaadinServletTest.java b/server/src/test/java/com/vaadin/server/VaadinServletTest.java
index 006872b212..4eb97d4453 100644
--- a/server/src/test/java/com/vaadin/server/VaadinServletTest.java
+++ b/server/src/test/java/com/vaadin/server/VaadinServletTest.java
@@ -10,11 +10,13 @@ import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
+import java.nio.file.FileSystem;
import java.nio.file.FileSystemNotFoundException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
@@ -233,7 +235,7 @@ public class VaadinServletTest {
public void isAllowedVAADINResource_jarWarFileScheme_detectsAsStaticResources()
throws IOException, URISyntaxException, ServletException {
assertTrue("Can not run concurrently with other test",
- VaadinServlet.openFileSystems.isEmpty());
+ VaadinServlet.OPEN_FILE_SYSTEMS.isEmpty());
VaadinServlet servlet = new VaadinServlet();
servlet.init(new MockServletConfig());
@@ -276,7 +278,7 @@ public class VaadinServletTest {
public void isAllowedVAADINResource_jarInAJar_detectsAsStaticResources()
throws IOException, URISyntaxException, ServletException {
assertTrue("Can not run concurrently with other test",
- VaadinServlet.openFileSystems.isEmpty());
+ VaadinServlet.OPEN_FILE_SYSTEMS.isEmpty());
VaadinServlet servlet = new VaadinServlet();
servlet.init(new MockServletConfig());
@@ -322,10 +324,46 @@ public class VaadinServletTest {
}
@Test
+ public void openFileServerExistsForZip_openingNewDoesNotFail()
+ throws IOException, URISyntaxException {
+ assertTrue("Can not run concurrently with other test",
+ VaadinServlet.OPEN_FILE_SYSTEMS.isEmpty());
+
+ VaadinServlet servlet = new VaadinServlet();
+
+ final TemporaryFolder folder = TemporaryFolder.builder().build();
+ folder.create();
+
+ try {
+ Path tempArchive = createJAR(folder).toPath();
+
+ final FileSystem fileSystem = FileSystems
+ .newFileSystem(
+ new URL("jar:file:///" + tempArchive.toString()
+ .replaceAll("\\\\", "/") + "!/").toURI(),
+ Collections.emptyMap());
+
+ final URL folderResourceURL = new URL("jar:file:///"
+ + tempArchive.toString().replaceAll("\\\\", "/")
+ + "!/VAADIN");
+
+ try {
+ servlet.getFileSystem(folderResourceURL.toURI());
+ } finally {
+ servlet.closeFileSystem(folderResourceURL.toURI());
+ fileSystem.close();
+ }
+ } finally {
+ folder.delete();
+ }
+
+ }
+
+ @Test
public void openingJarFileSystemForDifferentFilesInSameJar_existingFileSystemIsUsed()
throws IOException, URISyntaxException, ServletException {
assertTrue("Can not run concurrently with other test",
- VaadinServlet.openFileSystems.isEmpty());
+ VaadinServlet.OPEN_FILE_SYSTEMS.isEmpty());
VaadinServlet servlet = new VaadinServlet();
servlet.init(new MockServletConfig());
@@ -348,15 +386,15 @@ public class VaadinServletTest {
servlet.getFileSystem(fileResourceURL.toURI());
assertEquals("Same file should be marked for both resources",
- (Integer) 2, VaadinServlet.openFileSystems.entrySet()
+ (Integer) 2, VaadinServlet.OPEN_FILE_SYSTEMS.entrySet()
.iterator().next().getValue());
servlet.closeFileSystem(folderResourceURL.toURI());
assertEquals("Closing resource should be removed from jar uri",
- (Integer) 1, VaadinServlet.openFileSystems.entrySet()
+ (Integer) 1, VaadinServlet.OPEN_FILE_SYSTEMS.entrySet()
.iterator().next().getValue());
servlet.closeFileSystem(fileResourceURL.toURI());
assertTrue("Closing last resource should clear marking",
- VaadinServlet.openFileSystems.isEmpty());
+ VaadinServlet.OPEN_FILE_SYSTEMS.isEmpty());
try {
FileSystems.getFileSystem(folderResourceURL.toURI());
@@ -375,7 +413,7 @@ public class VaadinServletTest {
throws IOException, InterruptedException, ExecutionException,
URISyntaxException, ServletException {
assertTrue("Can not run concurrently with other test",
- VaadinServlet.openFileSystems.isEmpty());
+ VaadinServlet.OPEN_FILE_SYSTEMS.isEmpty());
VaadinServlet servlet = new VaadinServlet();
servlet.init(new MockServletConfig());
@@ -547,7 +585,7 @@ public class VaadinServletTest {
private void ensureFileSystemsCleared(URL fileResourceURL)
throws URISyntaxException {
assertFalse("URI should have been cleared",
- VaadinServlet.openFileSystems
+ VaadinServlet.OPEN_FILE_SYSTEMS
.containsKey(fileResourceURL.toURI()));
try {
FileSystems.getFileSystem(fileResourceURL.toURI());