[BLOSSOM-197] Page Edit does not work after reload of Template with JRebel Created: 02/Jan/15  Updated: 22/Jun/17  Resolved: 29/May/15

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

Type: Improvement Priority: Neutral
Reporter: Thomas Kratz Assignee: Tobias Mattsson
Resolution: Not an issue Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Relates
relates to BLOSSOM-210 Spring Loaded plugin for Blossom deve... Closed
relates to BLOSSOM-209 BlossomDispatcherServlet should send ... Closed
relation
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)
Date of First Response:

 Description   

I'm currently trying to figure out a way to make jrebel reconfigure the blossom template definitions on a pagecontroller class reload.

Trying to to that I came across a different problem, and I am not so sure if it is related to blossom at all. So please move it, if you thnk its not related to blossom.

Start Mgnl/Blossom with current jrebel.
Open a page template, add a component
Reload Page Template with Jrebel
Add another component ->

info.magnolia.ui.api.action.ActionExecutionException: Action execution failed for action: addComponent
	at info.magnolia.ui.api.action.AbstractActionExecutor.execute(AbstractActionExecutor.java:64)
	at info.magnolia.pages.app.editor.PageEditorPresenter.onAction(PageEditorPresenter.java:127)
	at info.magnolia.ui.vaadin.editor.PageEditor$1.newComponent(PageEditor.java:78)
	at sun.reflect.GeneratedMethodAccessor1239.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Method.java:483)
	at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:168)
	at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:118)
	at com.vaadin.server.communication.ServerRpcHandler.handleBurst(ServerRpcHandler.java:214)
	at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:111)
	at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:91)
	at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:37)
	at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1371)
	at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:238)
	at info.magnolia.ui.admincentral.AdmincentralVaadinServlet.service(AdmincentralVaadinServlet.java:132)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
	at info.magnolia.cms.filters.ServletDispatchingFilter.doFilter(ServletDispatchingFilter.java:148)
	at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:89)
	at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:80)
	at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
	at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
	at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
	at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
	at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
	at info.magnolia.cms.filters.CompositeFilter.doFilter(CompositeFilter.java:65)
	at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:89)
	at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:80)
	at info.magnolia.cms.filters.VirtualUriFilter.doFilter(VirtualUriFilter.java:68)
	at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:89)
	at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:80)
	at info.magnolia.module.cache.executor.Bypass.processCacheRequest(Bypass.java:58)
	at info.magnolia.module.cache.executor.CompositeExecutor.processCacheRequest(CompositeExecutor.java:66)
	at info.magnolia.module.cache.filter.CacheFilter.doFilter(CacheFilter.java:153)
	at info.magnolia.cms.filters.OncePerRequestAbstractMgnlFilter.doFilter(OncePerRequestAbstractMgnlFilter.java:58)
	at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:80)
	at info.magnolia.cms.i18n.I18nContentSupportFilter.doFilter(I18nContentSupportFilter.java:73)
	at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:89)
	at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:80)
	at info.magnolia.cms.filters.RangeSupportFilter.doFilter(RangeSupportFilter.java:84)
	at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:89)
	at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:80)
	at info.magnolia.cms.security.BaseSecurityFilter.doFilter(BaseSecurityFilter.java:57)
	at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:89)
	at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:80)
	at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
	at info.magnolia.cms.security.SecurityCallbackFilter.doFilter(SecurityCallbackFilter.java:83)
	at info.magnolia.cms.filters.OncePerRequestAbstractMgnlFilter.doFilter(OncePerRequestAbstractMgnlFilter.java:58)
	at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:80)
	at info.magnolia.cms.security.LogoutFilter.doFilter(LogoutFilter.java:94)
	at info.magnolia.cms.filters.OncePerRequestAbstractMgnlFilter.doFilter(OncePerRequestAbstractMgnlFilter.java:58)
	at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:80)
	at info.magnolia.cms.filters.MultiChannelFilter.doFilter(MultiChannelFilter.java:82)
	at info.magnolia.cms.filters.OncePerRequestAbstractMgnlFilter.doFilter(OncePerRequestAbstractMgnlFilter.java:58)
	at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:80)
	at info.magnolia.module.cache.filter.GZipFilter.doFilter(GZipFilter.java:73)
	at info.magnolia.cms.filters.OncePerRequestAbstractMgnlFilter.doFilter(OncePerRequestAbstractMgnlFilter.java:58)
	at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:80)
	at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
	at info.magnolia.cms.security.auth.login.LoginFilter.doFilter(LoginFilter.java:120)
	at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:89)
	at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:80)
	at info.magnolia.cms.filters.UnicodeNormalizationFilter.doFilter(UnicodeNormalizationFilter.java:87)
	at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:89)
	at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:80)
	at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:82)
	at info.magnolia.cms.filters.ContentTypeFilter.doFilter(ContentTypeFilter.java:103)
	at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:89)
	at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:80)
	at info.magnolia.cms.filters.ContextFilter.doFilter(ContextFilter.java:129)
	at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:89)
	at info.magnolia.cms.filters.MgnlFilterChain.doFilter(MgnlFilterChain.java:80)
	at info.magnolia.cms.filters.CompositeFilter.doFilter(CompositeFilter.java:65)
	at info.magnolia.cms.filters.AbstractMgnlFilter.doFilter(AbstractMgnlFilter.java:89)
	at info.magnolia.cms.filters.SafeDestroyMgnlFilterWrapper.doFilter(SafeDestroyMgnlFilterWrapper.java:106)
	at info.magnolia.cms.filters.MgnlFilterDispatcher.doDispatch(MgnlFilterDispatcher.java:66)
	at info.magnolia.cms.filters.MgnlMainFilter.doFilter(MgnlMainFilter.java:107)
	at info.magnolia.cms.filters.MgnlMainFilter.doFilter(MgnlMainFilter.java:93)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
	at org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:122)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
	at org.apache.catalina.core.StandardHostValve.__invoke(StandardHostValve.java:170)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:315)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)
Caused by: info.magnolia.objectfactory.MgnlInstantiationException: Unable to resolve parameters for constructor public info.magnolia.ui.dialog.formdialog.FormDialogPresenterImpl(info.magnolia.ui.dialog.registry.DialogDefinitionRegistry,info.magnolia.ui.dialog.formdialog.FormBuilder,info.magnolia.objectfactory.ComponentProvider,info.magnolia.ui.dialog.actionarea.DialogActionExecutor,info.magnolia.ui.dialog.formdialog.FormView,info.magnolia.i18nsystem.I18nizer,info.magnolia.i18nsystem.SimpleTranslator,info.magnolia.ui.api.availability.AvailabilityChecker,info.magnolia.ui.vaadin.integration.contentconnector.ContentConnector)
	at info.magnolia.objectfactory.ObjectManufacturer.newInstance(ObjectManufacturer.java:77)
	at info.magnolia.objectfactory.guice.GuiceComponentProvider.newInstanceWithParameterResolvers(GuiceComponentProvider.java:121)
	at info.magnolia.objectfactory.guice.GuiceComponentProvider.newInstance(GuiceComponentProvider.java:107)
	at info.magnolia.pages.app.action.CreateComponentAction.execute(CreateComponentAction.java:112)
	at info.magnolia.ui.api.action.AbstractActionExecutor.execute(AbstractActionExecutor.java:62)
	... 93 more


 Comments   
Comment by Tobias Mattsson [ 09/Jan/15 ]

Appears as if JRebel messes something up and we fail to match arguments after that. It might be possible to recover without having to restart by restarting your Admincentral instance by adding ?restartApplication to the url. It is not an issue specific to Blossom.

JRebel is useful in Magnolia development and can save a lot of time. For Blossom development its Spring integration will allow you to do modifications to your controller classes. It will however not make Blossom reinitialize the information it keeps after scanning classes at startup. Such as values read from annotations. A JRebel plugin that knows about Blossom internals would be required to accomplish this.

Comment by Joerg von Frantzius [ 18/Apr/15 ]

Hi thomas.kratz
I just came across your blog posting Magnolia with Blossom and Spring-Loaded, and it seems that your code snippet does for Spring-Loaded what a similar JRebel plugin would have to do?

@tmattsson: unfortunately ?restartApplication doesn't help, according to stefan.jahn. So if the above is correct, it would be great if Blossom would have some way of manually (by URL parameter) triggering something like these 3 lines of Thomas' code:

       ConfigurableApplicationContext applicationContext = (ConfigurableApplicationContext) dispatcherServlet.getWebApplicationContext();
       applicationContext.refresh();
       applicationContext.publishEvent( new BlossomDispatcherInitializedEvent(dispatcherServlet));

That could enable usage of JRebel without having a JRebel plugin for Blossom, at least by manually invoking a URL (parameter).

Comment by Thomas Kratz [ 19/Apr/15 ]

Hi Joerg, Tobias,

I did not do much testing with the spring-loaded post, but it seems to work at least for the most common cases. One Drawback of the solution is that it does multiple refreshs if you reload more than one changed template. Another improvement would be to autodetect the BlossomDispatcherServlet for e.g. like the Spring Plugin does with the HandlerDetection etc. Be it JRebel or Spring-Loaded it appears to be not so hard to solve this problem, even if it is not the most sophisticated solution. I have seen JRebel has already a Magnolia Plugin, is Magnolia involved with this? Probably we could hack something in there like the proposed solution for Blossom. This could be a REAL time saver for developers.

Comment by Tobias Mattsson [ 29/May/15 ]

I've gone ahead and created a plugin for Spring Loaded which incorporates the improvements you mention Thomas. It postpones refreshes for 500 ms and detects DispatcherServlets as they are instantiated. It's enough to include the JAR to use it. I've opened BLOSSOM-210 for this and will be releasing it soon.

jfrantzius: ?restartApplication won't make Blossom scan for changes but it sometimes helps when Admincentral has stopped working due to class changes.

jfrantzius: Yes, a JRebel plugin would need to do the exact same thing that the Spring Loaded plugin does, those 3 lines. It should be possible to do, I have looked at JRebel plugins on GitHub and briefly browsed their SDK and it seems doable.

jfrantzius: I'm not sure adding a URL like that to the module itself is such a great idea. It would need to be looked down to only certain roles and should ideally not be usable at all in production. I find the custom plugin approach much more appealing.

eiswind: As far as I know Magnolia hasn't been involved developing their JRebel plugin. They might be willing to add Blossom support in it.

I'm going to close this ticket, let's continue the discussion about Spring Loaded in BLOSSOM-210. File a new ticket in MAGNOLIA if the problem in the original post is still effecting you.

Comment by Jan Haderka [ 16/Jun/15 ]

No commit visible in jira related to this fix. Can you please provide link to it?

Comment by Tobias Mattsson [ 16/Jun/15 ]

had resolved as not an isssue.

Comment by Jan Haderka [ 17/Jun/15 ]

LOL. I'm an idiot. Sorry.

Comment by chandan agarwal [ 22/Jun/17 ]

It still does not work for me. I get the same error as before
Here is my config in pom.xml. I am using springloaded-1.2.7.RELEASE

-javaagent:${settings.localRepository}/org/springframework/springloaded/1.2.7.RELEASE/springloaded-1.2.7.RELEASE.jar
-noverify
-Xdebug
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=9000
-Xnoagent
-Djava.compiler=NONE
-agentpath:${project.build.directory}/../lib/lib/${jrebel.agent}
-DBlossomSpringLoadedPlugin.refreshOnAnyChange=true
-DBlossomSpringLoadedPlugin.refreshAllDispatcherServlets=true
 -Drebel.log=trace

here is the error

Caused by: info.magnolia.objectfactory.MgnlInstantiationException: Unable to resolve parameters for constructor public info.magnolia.ui.dialog.formdialog.FormDialogPresenterImpl(info.magnolia.ui.dialog.registry.DialogDefinitionRegistry,info.magnolia.objectfactory.ComponentProvider,info.magnolia.ui.dialog.actionarea.DialogActionExecutor,info.magnolia.ui.dialog.formdialog.FormView,info.magnolia.i18nsystem.I18nizer,info.magnolia.i18nsystem.SimpleTranslator,info.magnolia.ui.api.availability.AvailabilityChecker,info.magnolia.ui.vaadin.integration.contentconnector.ContentConnector,info.magnolia.ui.form.FormPresenter). Unresolved parameter(s) are: 3rd parameter which is of type info.magnolia.ui.dialog.actionarea.DialogActionExecutor
[INFO] [talledLocalContainer] 	at info.magnolia.objectfactory.ObjectManufacturer.newInstance(ObjectManufacturer.java:97)
[INFO] [talledLocalContainer] 	at info.magnolia.objectfactory.guice.GuiceComponentProvider.newInstanceWithParameterResolvers(GuiceComponentProvider.java:121)
[INFO] [talledLocalContainer] 	at info.magnolia.objectfactory.guice.GuiceComponentProvider.newInstance(GuiceComponentProvider.java:107)
[INFO] [talledLocalContainer] 	at info.magnolia.ui.dialog.formdialog.FormDialogPresenterFactoryImpl.createFormDialogPresenter(FormDialogPresenterFactoryImpl.java:80)
[INFO] [talledLocalContainer] 	at info.magnolia.ui.dialog.formdialog.FormDialogPresenterFactoryImpl.createFormDialogPresenter(FormDialogPresenterFactoryImpl.java:69)
[INFO] [talledLocalContainer] 	at info.magnolia.ui.framework.action.OpenCreateDialogAction.execute(OpenCreateDialogAction.java:99)
[INFO] [talledLocalContainer] 	at info.magnolia.ui.api.action.AbstractActionExecutor.execute(AbstractActionExecutor.java:62)

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