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

ScriptTemplateView can't load web-app resources [SPR-14210] #18784

Closed
spring-issuemaster opened this issue Apr 23, 2016 · 2 comments
Closed

ScriptTemplateView can't load web-app resources [SPR-14210] #18784

spring-issuemaster opened this issue Apr 23, 2016 · 2 comments
Assignees
Milestone

Comments

@spring-issuemaster
Copy link
Collaborator

@spring-issuemaster spring-issuemaster commented Apr 23, 2016

Michael Feige opened SPR-14210 and commented

Hey there,

I found, that it's not possible to use the ScriptTemplateView in combination with JavaScripts (or resources in general) that only reside inside the ServleContexts Classloader.

I have following spring-mvc-setup:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">


    <mvc:view-resolvers>
        <bean id="dotViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
            <property name="viewClass" value="de.deyovi.spring.web.scriptbug.PatchedScriptTemplateView" />
            <property name="prefix" value="/WEB-INF/resources/templates/" />
            <property name="viewNames" value="*.dot" />
        </bean>
        <mvc:jsp prefix="/WEB-INF/jsp/" suffix=".jsp" />
    </mvc:view-resolvers>

    <context:component-scan base-package="de.deyovi.spring.web" />

    <mvc:annotation-driven />

    <bean id="dotScriptViewTemplate" class="org.springframework.web.servlet.view.script.ScriptTemplateConfigurer">
        <property name="engineName" value="JavaScript" />
        <property name="renderFunction" value="render" />
        <property name="renderObject" value="JavaDotRenderer" />
        <property name="sharedEngine" value="true" />
        <property name="resourceLoaderPath" value="classpath*:,WEB-INF/**" />
        <property name="scripts">
            <array>
                <value>WEB-INF/resources/js/vendor/doT.min.js</value>
                <value>WEB-INF/resources/js/java-bridge-dot.js</value>
            </array>
        </property>
    </bean>

</beans>

My Controller has this method:

@RequestMapping("/hello/dot")
public String plainHello(Model model) {
    model.addAttribute("content", "Hello Dot!");
    return "test.dot";
}

Now this should result in the ScriptTemplateView using the Scripts (provided by the config in the ScriptTemplateConfigurer) and rendering the output using the dot.js - Templating Engine.

But the ScriptTemplateView and its ResourceLoader are not able to load the resources that reside inside the webapp-context.

The GitHub-Repo I provided with the Reference URL shows the case reproducable in its master-branch and a possible solution (having a Patched copy of the ScriptTemplateView) which shows that the usage of the current ServletContext could solve the problem.

See:
de.deyovi.spring.web.scriptbug.PatchedScriptTemplateView:226

+		if (this.resourceLoader == null) {
+			// In case of an WebApplication
+			if (context instanceof WebApplicationContext) {
+				// .. we choose a ServletContext-aware ResourceLoader to allow access to all resources in the web-applications-context
+				this.resourceLoader = new ServletContextResourceLoader(((WebApplicationContext) context).getServletContext());
+			} else {
+				// otherwise we fallback to the default behaviour which handles classpath-resources
+				this.resourceLoader = new DefaultResourceLoader(createClassLoader());
+			}
+		}

Or is it so that I am missing something very important while configuring my ScriptTemplateViewResolver?

Regards,
Michael


Affects: 4.2.3

Reference URL: https://github.com/MichiShyGuy/spring-script-bug-example.git

Referenced from: commits 15138ed

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Apr 28, 2016

Sébastien Deleuze commented

Hey MezzoMicks, based on your feedback and Juergen insights, I have revisited ScriptTemplateView resource loading implementation to support more use cases, including loading resources from WEB-INF/....

The improvement requires some non-trivial changes so it will be only available in Spring Framework 4.3, which will be released shortly. I have validated that it works with you repro project (even without customizing resourceLoaderPath), but any test on your side with 4.3.0.BUILD-SNAPSHOT builds could help to double check that everything is ok with the new implementation.

Please post a comment if you find any issue.

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Apr 28, 2016

Michael Feige commented

Hello Sébastien,

I just checked with the recent BUILD-SNAPSHOT and your solution works like a charm. As expected it even works in my other project which also includes additional WEB-INF-Resources provided by JARs with web-fragment.xml.

Also thumbs up for the protected getResource(..)-Method which allows easier overriding in other, even more complicated, resource handling scenarios.

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.