[BLOSSOM-39] Spring @Scope annotation doesn't appear to work Created: 25/Jan/11  Updated: 07/Nov/14  Resolved: 27/Jan/11

Status: Closed
Project: Blossom
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Neutral
Reporter: Dave Lloyd Assignee: Tobias Mattsson
Resolution: Workaround exists Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Template:
Acceptance criteria:
Empty
Task DoD:
[ ]* Doc/release notes changes? Comment present?
[ ]* Downstream builds green?
[ ]* Solution information and context easily available?
[ ]* Tests
[ ]* FixVersion filled and not yet released
[ ]  Architecture Decision Record (ADR)
Bug DoR:
[ ]* Steps to reproduce, expected, and actual results filled
[ ]* Affected version filled
Date of First Response:

 Description   

The following code works fine without the @Scope annotation (this code doesn't need the annotation actually, but it is self-contained and demonstrates the problem)

package uk.co.moviestorm.hub.paragraphs;

import info.magnolia.module.blossom.annotation.Paragraph;
import info.magnolia.module.blossom.annotation.ParagraphDescription;
import info.magnolia.module.blossom.annotation.TabFactory;
import info.magnolia.module.blossom.dialog.TabBuilder;
import info.magnolia.module.fckeditor.dialogs.FckEditorDialog;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**

  • Simple paragraph for adding text to a page.
    */
    @Controller
    @Paragraph("Text")
    @ParagraphDescription("Simple text block")
    @Scope( "session" )
    public class TextParagraph
    {
    @RequestMapping("/text")
    public String render() { return "text"; }

@TabFactory("Content")
public void addDialog( TabBuilder tab )

{ FckEditorDialog editor = tab.addFckEditor( "body", "Text", "" ); editor.setConfig( FckEditorDialog.PARAM_WIDTH, 600 ); editor.setConfig( FckEditorDialog.PARAM_HEIGHT, 400 ); editor.setConfig( FckEditorDialog.PARAM_STYLES, "/css/fckStyles.xml"); editor.setConfig( FckEditorDialog.PARAM_CSS, "/css/fckStyles.css"); editor.setConfig( FckEditorDialog.PARAM_SOURCE, true ); }

}

With the annotation, I get the following exception:

011-01-25 14:43:37,667 ERROR info.magnolia.cms.taglibs.Include : Can't find renderable definition text
info.magnolia.module.templating.RenderException: Can't find renderable definition text
at info.magnolia.module.templating.engine.DefaultRenderingEngine.render(DefaultRenderingEngine.java:162)
at info.magnolia.module.templating.engine.DefaultRenderingEngine.render(DefaultRenderingEngine.java:127)
at info.magnolia.module.templating.engine.DefaultRenderingEngine.render(DefaultRenderingEngine.java:120)
at info.magnolia.module.templating.engine.DefaultRenderingEngine$$EnhancerByCGLIB$$d081ecd6.render(<generated>)
at info.magnolia.cms.taglibs.Include.doEndTag(Include.java:215)
at org.apache.jsp.WEB_002dINF.templates.marketplacePage_jsp._jspx_meth_cms_005fincludeTemplate_005f1(marketplacePage_jsp.java:750)
at org.apache.jsp.WEB_002dINF.templates.marketplacePage_jsp._jspx_meth_cms_005fcontentNodeIterator_005f1(marketplacePage_jsp.java:723)
at org.apache.jsp.WEB_002dINF.templates.marketplacePage_jsp._jspService(marketplacePage_jsp.java:368)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:76)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:84)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:84)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:84)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:84)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:84)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:84)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:84)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:84)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:84)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:84)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:84)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:84)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:84)
at info.magnolia.cms.filters.ContentTypeFilter.doFilter(ContentTypeFilter.java:102)
at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:88)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
at info.magnolia.cms.filters.ContextFilter.doFilter(ContextFilter.java:120)
at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:88)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
at info.magnolia.cms.filters.CompositeFilter.doFilter(CompositeFilter.java:66)
at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:88)
at info.magnolia.cms.filters.MgnlMainFilter.doFilter(MgnlMainFilter.java:105)
at info.magnolia.cms.filters.MgnlMainFilter.doFilter(MgnlMainFilter.java:216)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:630)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:436)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:374)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302)
at info.magnolia.module.templating.renderers.JspTemplateRenderer.onRender(JspTemplateRenderer.java:69)
at info.magnolia.module.blossom.view.JspTemplateViewRenderer.onRender(JspTemplateViewRenderer.java:92)
at info.magnolia.module.templating.AbstractRenderer.render(AbstractRenderer.java:92)
at info.magnolia.module.templating.renderers.AbstractTemplateRenderer.renderTemplate(AbstractTemplateRenderer.java:77)
at info.magnolia.module.blossom.view.TemplateView.renderMergedOutputModel(TemplateView.java:70)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1047)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:817)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at info.magnolia.module.blossom.render.BlossomDispatcherServlet.dispatch(BlossomDispatcherServlet.java:116)
at info.magnolia.module.blossom.render.BlossomTemplateRenderer.renderTemplate(BlossomTemplateRenderer.java:74)
at info.magnolia.module.templating.engine.DefaultRenderingEngine$RenderingHelper$2.render(DefaultRenderingEngine.java:108)
at info.magnolia.module.templating.engine.DefaultRenderingEngine.render(DefaultRenderingEngine.java:171)
at info.magnolia.module.templating.engine.DefaultRenderingEngine.render(DefaultRenderingEngine.java:130)
at info.magnolia.module.templating.engine.DefaultRenderingEngine$$EnhancerByCGLIB$$d081ecd6.render(<generated>)
at info.magnolia.module.templating.RenderingFilter.render(RenderingFilter.java:137)
at info.magnolia.module.templating.RenderingFilter.doFilter(RenderingFilter.java:92)
at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:88)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
at info.magnolia.cms.filters.BackwardCompatibilityFilter.doFilter(BackwardCompatibilityFilter.java:73)
at info.magnolia.cms.filters.OncePerRequestAbstractMgnlFilter.doFilter(OncePerRequestAbstractMgnlFilter.java:60)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
at info.magnolia.module.blossom.preexecution.BlossomFilter.doFilter(BlossomFilter.java:80)
at info.magnolia.cms.filters.OncePerRequestAbstractMgnlFilter.doFilter(OncePerRequestAbstractMgnlFilter.java:60)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
at info.magnolia.module.templating.ModelExecutionFilter.doFilter(ModelExecutionFilter.java:84)
at info.magnolia.cms.filters.OncePerRequestAbstractMgnlFilter.doFilter(OncePerRequestAbstractMgnlFilter.java:60)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
at info.magnolia.cms.filters.InterceptFilter.doFilter(InterceptFilter.java:121)
at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:88)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
at info.magnolia.cms.filters.AggregatorFilter.doFilter(AggregatorFilter.java:104)
at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:88)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
at info.magnolia.cms.security.BaseSecurityFilter.doFilter(BaseSecurityFilter.java:64)
at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:88)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
at info.magnolia.cms.filters.RepositoryMappingFilter.doFilter(RepositoryMappingFilter.java:91)
at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:88)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
at info.magnolia.cms.filters.CompositeFilter.doFilter(CompositeFilter.java:66)
at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:88)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:76)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:84)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:84)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:84)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:84)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:84)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:84)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:84)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:84)
at info.magnolia.cms.filters.CompositeFilter.doFilter(CompositeFilter.java:66)
at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:88)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
at info.magnolia.cms.filters.VirtualUriFilter.doFilter(VirtualUriFilter.java:69)
at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:88)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
at info.magnolia.module.cache.executor.Bypass.processCacheRequest(Bypass.java:57)
at info.magnolia.module.cache.filter.CacheFilter.doFilter(CacheFilter.java:122)
at info.magnolia.cms.filters.OncePerRequestAbstractMgnlFilter.doFilter(OncePerRequestAbstractMgnlFilter.java:60)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
at info.magnolia.cms.i18n.I18nContentSupportFilter.doFilter(I18nContentSupportFilter.java:75)
at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:88)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
at info.magnolia.module.cache.filter.GZipFilter.doFilter(GZipFilter.java:73)
at info.magnolia.cms.filters.OncePerRequestAbstractMgnlFilter.doFilter(OncePerRequestAbstractMgnlFilter.java:60)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:84)
at info.magnolia.cms.security.BaseSecurityFilter.doFilter(BaseSecurityFilter.java:64)
at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:88)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
at info.magnolia.cms.security.LogoutFilter.doFilter(LogoutFilter.java:88)
at info.magnolia.cms.filters.OncePerRequestAbstractMgnlFilter.doFilter(OncePerRequestAbstractMgnlFilter.java:60)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
at info.magnolia.cms.security.auth.login.LoginFilter.doFilter(LoginFilter.java:77)
at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:88)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:84)
at info.magnolia.cms.filters.CosMultipartRequestFilter.doFilter(CosMultipartRequestFilter.java:86)
at info.magnolia.cms.filters.OncePerRequestAbstractMgnlFilter.doFilter(OncePerRequestAbstractMgnlFilter.java:60)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
at info.magnolia.cms.filters.ContentTypeFilter.doFilter(ContentTypeFilter.java:102)
at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:88)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
at info.magnolia.cms.filters.ContextFilter.doFilter(ContextFilter.java:120)
at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:88)
at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
at info.magnolia.cms.filters.CompositeFilter.doFilter(CompositeFilter.java:66)
at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:88)
at info.magnolia.cms.filters.MgnlMainFilter.doFilter(MgnlMainFilter.java:105)
at info.magnolia.cms.filters.MgnlMainFilter.doFilter(MgnlMainFilter.java:216)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:680)



 Comments   
Comment by Tobias Mattsson [ 26/Jan/11 ]

Hi Dave,

When you add scope to a controller it has its initialization deferred until it is first needed to serve a request. Therefore its not detected by blossom when it starts up and searches for controllers annotated with @Paragraph. This is the reason for the problem you're seeing. Magnolia throws an error saying 'renderable definition not found' since the paragraph hasn't been registered.

Although this part could be rewritten to handle this scenario there's another problem with this approach. Controllers are also called to create dialogs and at that point an instance is needed.

Setting scope on objects used by your controller on the other hand works as expected.

So the answer will have to be that no, adding scope on the controller is not supported. I don't expect this to be a huge inconvenience as the usual use case is to have controllers singleton scoped and stateless. If it is indeed a problem for you please explain more about why you need this setup and why its beneficial.

// Tobias

Comment by Dave Lloyd [ 26/Jan/11 ]

Hi Tobias,

Thanks for investigating this and your considered reply. That makes perfect sense to me. I'm still finding my feet with Spring & Blossom, converting an old school servlet site to work in a new way.
Previously the servlets (which were per-request instances) would hold working data such as the user object, per-user services, forms etc. So I guess with the controllers being stateless, I'll need to put the same data into some session objects that can be passed into the method calls. More reading needed I can see.

Thanks,
Dave

Comment by Tobias Mattsson [ 27/Jan/11 ]

Hi Dave,

You can add seesion scope to for instance the user object and have that injected into the stateless controller. Spring will create a proxy that delegates calls to the actual instance in the session.

@Component
@Scope("session")
public class User {...}

@Paragraph("Text")
@Controller
public class TextParagraph {
@Autowired
private User user;
...
}

Then load them using component scan with scoped-proxy set to targetClass.

  <context:component-scan base-package="info.magnolia.blossom.sample" scoped-proxy="targetClass" />

The controller is stateless but needs no boiler plate code to find the objects it needs.

// Tobias

Generated at Sun Feb 11 23:29:31 CET 2024 using Jira 9.4.2#940002-sha1:46d1a51de284217efdcb32434eab47a99af2938b.