This repository has been archived by the owner on Feb 23, 2023. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix static resource handling with GraalVM 21.2
Related to spring-projects/spring-framework#27538 Closes gh-1174
- Loading branch information
Showing
5 changed files
with
158 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Foo |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,12 @@ | ||
#!/usr/bin/env bash | ||
RESPONSE=`curl -s localhost:8080/` | ||
if [[ "$RESPONSE" == 'Hello from Spring MVC and Tomcat' ]]; then | ||
exit 0 | ||
RESPONSE=`curl -s localhost:8080/foo.html` | ||
if [[ "$RESPONSE" == 'Foo' ]]; then | ||
exit 0 | ||
else | ||
exit 1 | ||
fi | ||
else | ||
exit 1 | ||
fi |
17 changes: 17 additions & 0 deletions
17
.../org/springframework/nativex/substitutions/framework/Target_ApplicationObjectSupport.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package org.springframework.nativex.substitutions.framework; | ||
|
||
import com.oracle.svm.core.annotate.Alias; | ||
import com.oracle.svm.core.annotate.TargetClass; | ||
|
||
import org.springframework.context.ApplicationContext; | ||
import org.springframework.nativex.substitutions.OnlyIfPresent; | ||
|
||
@TargetClass(className = "org.springframework.context.support.ApplicationObjectSupport", onlyWith = OnlyIfPresent.class) | ||
final class Target_ApplicationObjectSupport { | ||
|
||
@Alias | ||
protected ApplicationContext obtainApplicationContext() { | ||
return null; | ||
} | ||
|
||
} |
85 changes: 85 additions & 0 deletions
85
...rg/springframework/nativex/substitutions/framework/Target_ResourceHttpRequestHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package org.springframework.nativex.substitutions.framework; | ||
|
||
import java.nio.charset.Charset; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import com.oracle.svm.core.annotate.Alias; | ||
import com.oracle.svm.core.annotate.Substitute; | ||
import com.oracle.svm.core.annotate.TargetClass; | ||
|
||
import org.springframework.context.ApplicationContext; | ||
import org.springframework.core.io.Resource; | ||
import org.springframework.core.io.UrlResource; | ||
import org.springframework.nativex.substitutions.OnlyIfPresent; | ||
import org.springframework.util.StringValueResolver; | ||
import org.springframework.web.context.support.ServletContextResource; | ||
|
||
// Workaround for https://github.com/spring-projects-experimental/spring-native/issues/1174 with GraalVM 21.2.0 (works fine with GraalVM 21.3.0) | ||
@TargetClass(className = "org.springframework.web.servlet.resource.ResourceHttpRequestHandler", onlyWith = OnlyIfPresent.class) | ||
final class Target_ResourceHttpRequestHandler { | ||
|
||
@Alias | ||
private List<String> locationValues; | ||
|
||
@Alias | ||
private List<Resource> locationResources; | ||
|
||
@Alias | ||
private List<Resource> locationsToUse; | ||
|
||
@Alias | ||
private Map<Resource, Charset> locationCharsets; | ||
|
||
@Alias | ||
private StringValueResolver embeddedValueResolver; | ||
|
||
@Substitute | ||
private void resolveResourceLocations() { | ||
List<Resource> result = new ArrayList<>(); | ||
if (!this.locationValues.isEmpty()) { | ||
ApplicationContext applicationContext = ((Target_ApplicationObjectSupport)(Object)this).obtainApplicationContext(); | ||
for (String location : this.locationValues) { | ||
if (this.embeddedValueResolver != null) { | ||
String resolvedLocation = this.embeddedValueResolver.resolveStringValue(location); | ||
if (resolvedLocation == null) { | ||
throw new IllegalArgumentException("Location resolved to null: " + location); | ||
} | ||
location = resolvedLocation; | ||
} | ||
Charset charset = null; | ||
location = location.trim(); | ||
if (location.startsWith("[charset=")) { | ||
int endIndex = location.indexOf(']', "[charset=".length()); | ||
if (endIndex == -1) { | ||
throw new IllegalArgumentException("Invalid charset syntax in location: " + location); | ||
} | ||
String value = location.substring("[charset=".length(), endIndex); | ||
charset = Charset.forName(value); | ||
location = location.substring(endIndex + 1); | ||
} | ||
Resource resource = applicationContext.getResource(location); | ||
if (location.equals("/") && !(resource instanceof ServletContextResource)) { | ||
throw new IllegalStateException( | ||
"The String-based location \"/\" should be relative to the web application root " + | ||
"but resolved to a Resource of type: " + resource.getClass() + ". " + | ||
"If this is intentional, please pass it as a pre-configured Resource via setLocations."); | ||
} | ||
result.add(resource); | ||
if (charset != null) { | ||
if (!(resource instanceof UrlResource)) { | ||
throw new IllegalArgumentException("Unexpected charset for non-UrlResource: " + resource); | ||
} | ||
this.locationCharsets.put(resource, charset); | ||
} | ||
} | ||
} | ||
|
||
result.addAll(this.locationResources); | ||
|
||
this.locationsToUse.clear(); | ||
this.locationsToUse.addAll(result); | ||
} | ||
|
||
} |
49 changes: 49 additions & 0 deletions
49
...n/java/org/springframework/nativex/substitutions/framework/Target_ResourceWebHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package org.springframework.nativex.substitutions.framework; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import com.oracle.svm.core.annotate.Alias; | ||
import com.oracle.svm.core.annotate.Substitute; | ||
import com.oracle.svm.core.annotate.TargetClass; | ||
|
||
import org.springframework.core.io.Resource; | ||
import org.springframework.core.io.ResourceLoader; | ||
import org.springframework.nativex.substitutions.OnlyIfPresent; | ||
import org.springframework.util.Assert; | ||
import org.springframework.util.CollectionUtils; | ||
|
||
// Workaround for https://github.com/spring-projects-experimental/spring-native/issues/1174 with GraalVM 21.2.0 (works fine with GraalVM 21.3.0) | ||
@TargetClass(className = "org.springframework.web.reactive.resource.ResourceWebHandler", onlyWith = OnlyIfPresent.class) | ||
final class Target_ResourceWebHandler { | ||
|
||
@Alias | ||
private List<String> locationValues; | ||
|
||
@Alias | ||
private List<Resource> locationResources; | ||
|
||
@Alias | ||
private List<Resource> locationsToUse; | ||
|
||
@Alias | ||
private ResourceLoader resourceLoader; | ||
|
||
@Substitute | ||
private void resolveResourceLocations() { | ||
List<Resource> result = new ArrayList<>(this.locationResources); | ||
|
||
if (!this.locationValues.isEmpty()) { | ||
Assert.notNull(this.resourceLoader, | ||
"ResourceLoader is required when \"locationValues\" are configured."); | ||
Assert.isTrue(CollectionUtils.isEmpty(this.locationResources), "Please set " + | ||
"either Resource-based \"locations\" or String-based \"locationValues\", but not both."); | ||
for (String location : this.locationValues) { | ||
result.add(this.resourceLoader.getResource(location)); | ||
} | ||
} | ||
|
||
this.locationsToUse.clear(); | ||
this.locationsToUse.addAll(result); | ||
} | ||
} |