Skip to content

Commit

Permalink
fix: Also load default JAR resources for DevModeInitializer (#9823)
Browse files Browse the repository at this point in the history
Fixes #9802
# Conflicts:
#	flow-server/src/main/java/com/vaadin/flow/server/startup/DevModeInitializer.java
#	flow-server/src/test/java/com/vaadin/flow/server/startup/DevModeInitializerTest.java
  • Loading branch information
Tan Bui authored and pleku committed Mar 15, 2021
1 parent 4ed945e commit 4a01a06
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,11 @@ public final class Constants implements Serializable {
*/
public static final String RESOURCES_JAR_DEFAULT = "META-INF/resources/";

/**
* Location for the theme resources in jar files.
*/
public static final String RESOURCES_THEME_JAR_DEFAULT = RESOURCES_JAR_DEFAULT + APPLICATION_THEME_ROOT + "/";

/**
* @deprecated Use
* {@link InitParameters#SERVLET_PARAMETER_DEVMODE_WEBPACK_TIMEOUT}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@

import elemental.json.Json;
import elemental.json.JsonObject;

import static com.vaadin.flow.server.Constants.PACKAGE_JSON;
import static com.vaadin.flow.server.InitParameters.SERVLET_PARAMETER_DEVMODE_OPTIMIZE_BUNDLE;
import static com.vaadin.flow.server.frontend.FrontendUtils.DEFAULT_FRONTEND_DIR;
Expand Down Expand Up @@ -173,6 +172,11 @@ private static Set<String> calculateApplicableClassNames() {
private static final Pattern DIR_REGEX_FRONTEND_DEFAULT = Pattern.compile(
"^(?:file:0)?(.+)" + Constants.RESOURCES_FRONTEND_DEFAULT + "/?$");

// allow trailing slash
private static final Pattern DIR_REGEX_RESOURCES_JAR_DEFAULT = Pattern
.compile("^(?:file:0)?(.+)" + Constants.RESOURCES_THEME_JAR_DEFAULT
+ "/?$");

// allow trailing slash
private static final Pattern DIR_REGEX_COMPATIBILITY_FRONTEND_DEFAULT = Pattern
.compile("^(?:file:)?(.+)"
Expand Down Expand Up @@ -407,8 +411,8 @@ private static String getBaseDirectoryFallback() {

/*
* This method returns all folders of jar files having files in the
* META-INF/resources/frontend folder. We don't use URLClassLoader because
* will fail in Java 9+
* META-INF/resources/frontend and META-INF/resources/themes folder.
* We don't use URLClassLoader because will fail in Java 9+
*/
static Set<File> getFrontendLocationsFromClassloader(
ClassLoader classLoader) throws ServletException {
Expand All @@ -417,6 +421,8 @@ static Set<File> getFrontendLocationsFromClassloader(
Constants.RESOURCES_FRONTEND_DEFAULT));
frontendFiles.addAll(getFrontendLocationsFromClassloader(classLoader,
Constants.COMPATIBILITY_RESOURCES_FRONTEND_DEFAULT));
frontendFiles.addAll(getFrontendLocationsFromClassloader(classLoader,
Constants.RESOURCES_THEME_JAR_DEFAULT));
return frontendFiles;
}

Expand Down Expand Up @@ -458,6 +464,8 @@ private static Set<File> getFrontendLocationsFromClassloader(
Matcher zipProtocolJarMatcher = ZIP_PROTOCOL_JAR_FILE_REGEX
.matcher(path);
Matcher dirMatcher = DIR_REGEX_FRONTEND_DEFAULT.matcher(path);
Matcher dirResourcesMatcher = DIR_REGEX_RESOURCES_JAR_DEFAULT
.matcher(path);
Matcher dirCompatibilityMatcher = DIR_REGEX_COMPATIBILITY_FRONTEND_DEFAULT
.matcher(path);
Matcher jarVfsMatcher = VFS_FILE_REGEX.matcher(urlString);
Expand All @@ -479,6 +487,8 @@ private static Set<File> getFrontendLocationsFromClassloader(
frontendFiles.add(new File(zipProtocolJarMatcher.group(1)));
} else if (dirMatcher.find()) {
frontendFiles.add(new File(dirMatcher.group(1)));
} else if (dirResourcesMatcher.find()) {
frontendFiles.add(new File(dirResourcesMatcher.group(1)));
} else if (dirCompatibilityMatcher.find()) {
frontendFiles
.add(new File(dirCompatibilityMatcher.group(1)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import com.vaadin.flow.server.frontend.FallbackChunk;
import com.vaadin.flow.server.frontend.FrontendUtils;

import static com.vaadin.flow.server.Constants.RESOURCES_THEME_JAR_DEFAULT;
import static com.vaadin.flow.server.InitParameters.SERVLET_PARAMETER_COMPATIBILITY_MODE;
import static com.vaadin.flow.server.InitParameters.SERVLET_PARAMETER_DEVMODE_OPTIMIZE_BUNDLE;
import static org.junit.Assert.assertEquals;
Expand Down Expand Up @@ -119,6 +120,14 @@ public void loadingJars_useModernResourcesFolder_allFilesExist()
loadingJars_allFilesExist(Constants.RESOURCES_FRONTEND_DEFAULT);
}

@Test
public void loadingJars_useResourcesThemesFolder_allFilesExist()
throws IOException, ServletException {
loadingJarsWithProtocol_allFilesExist(RESOURCES_THEME_JAR_DEFAULT,
"src/test/resources/jar-with-themes-resources.jar!/META-INF/resources/themes",
this::jarUrlBuilder);
}

@Test
public void loadingZipProtocolJars_useModernResourcesFolder_allFilesExist()
throws IOException, ServletException {
Expand All @@ -140,6 +149,13 @@ public void loadingFsResources_useModernResourcesFolder_allFilesExist()
Constants.RESOURCES_FRONTEND_DEFAULT);
}

@Test
public void loadingFsResources_useResourcesThemesFolder_allFilesExist()
throws IOException, ServletException {
loadingFsResources_allFilesExist("/dir-with-theme-resources/",
RESOURCES_THEME_JAR_DEFAULT);
}

@Test
public void loadingFsResources_useObsoleteResourcesFolder_allFilesExist()
throws IOException, ServletException {
Expand Down Expand Up @@ -389,13 +405,15 @@ public void onStartup_fallbackBaseDirIsGradleProjectDirectory_isAccepted()

private void loadingJars_allFilesExist(String resourcesFolder)
throws IOException, ServletException {
loadingJarsWithProtocol_allFilesExist(resourcesFolder, s -> {
try {
return new URL("jar:" + s);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
});
loadingJarsWithProtocol_allFilesExist(resourcesFolder, this::jarUrlBuilder);
}

private URL jarUrlBuilder(String url) {
try {
return new URL("jar:" + url);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}

private void loadingZipProtocolJars_allFilesExist(String resourcesFolder)
Expand All @@ -421,30 +439,38 @@ protected URLConnection openConnection(URL u) throws IOException {
private void loadingJarsWithProtocol_allFilesExist(String resourcesFolder,
Function<String, URL> urlBuilder)
throws IOException, ServletException {
loadingJarsWithProtocol_allFilesExist(resourcesFolder,
"src/test/resources/with%20space/jar-with-frontend-resources.jar!/META-INF/resources/frontend",
urlBuilder);
}

private void loadingJarsWithProtocol_allFilesExist(String resourcesFolder, String jarContent,
Function<String, URL> urlBuilder)
throws IOException, ServletException {
// Create jar urls with the given urlBuilder for test
String urlPath = this.getClass().getResource("/").toString()
.replace("target/test-classes/", "")
+ "src/test/resources/with%20space/jar-with-frontend-resources.jar!/META-INF/resources/frontend";
.replace("target/test-classes/", "")
+ jarContent;
URL jar = urlBuilder.apply(urlPath);
List<URL> urls = new ArrayList<>();
urls.add(jar);

// Create mock loader with the single jar to be found
ClassLoader classLoader = Mockito.mock(ClassLoader.class);
Mockito.when(classLoader.getResources(resourcesFolder))
.thenReturn(Collections.enumeration(urls));
.thenReturn(Collections.enumeration(urls));

// load jars from classloader
List<File> jarFilesFromClassloader = new ArrayList<>(DevModeInitializer
.getFrontendLocationsFromClassloader(classLoader));
.getFrontendLocationsFromClassloader(classLoader));

// Assert that jar was found and accepted
assertEquals("One jar should have been found and added as a File", 1,
jarFilesFromClassloader.size());
jarFilesFromClassloader.size());
// Assert that the file can be found from the filesystem by the given
// path.
assertTrue("File in path 'with space' doesn't load from given path",
jarFilesFromClassloader.get(0).exists());
jarFilesFromClassloader.get(0).exists());
}

private void loadingFsResources_allFilesExist(String resourcesRoot,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Binary file not shown.

0 comments on commit 4a01a06

Please sign in to comment.