SurfBug

cancel
Showing results for 
Search instead for 
Did you mean: 

SurfBug

ddraper
Intermediate II
0 10 9,772

Introduction

In my previous blogs I've been introducing some of the new extensibility features that are currently available in the current Alfresco Community source and that will be available in Alfresco Enterprise 4.0. In many of these blogs I've demonstrated the use of a new Spring Surf debug tool called 'Surf Bug' without providing much additional information about it. In this blog I'm going to describe Surf Bug in greater detail.

Background

When I first started working on the Alfresco Share user interface the most immediate challenge was identifying the various components that comprise each page. It's was something of an art to find the source file in which the actual HTML on any given page is defined - and that was after you understood how a Spring Surf page is built!

This posed a major challenge for anyone extending a page in Alfresco Share as the first task was always identifying the  files that actually needed extending. In order to assist with this problem we have introduced 'SurfBug' which (as its name suggests) took its inspiration from the FireFox add-on 'FireBug' and when enabled is designed to highlight Components or Sub-Components that comprise the current page and provide information on the files and properties that define them.

SurfBug is a part of Spring Surf rather than Alfresco Share and as such is actually available to any Spring Surf application. It is enabled by the 'surfBugStatus' WebScript (i.e. accessed through '<application context>/service/surfBugStatus').

Toggle Surf Bug

Enabling SurfBug and refreshing a page will overlay red boxes on the screen indicating the location of the Components or Sub-Components on the page (the information shown is based upon the Surf application configuration - if the Component interfaces is being fulfilled by the 'org.springframework.extension.surf.type.AdvancedComponentImpl' class (which is the default) then Sub-Component information will be shown. When you mouse click on a box, a pop-up will be displayed that hopefully provides all the information about the Sub-Component that you could possibly need.

Surf Bug Data

Things To Note

SurfBug is not guaranteed to show every Sub-Component on the page if the DOM elements for that page have been manipulated in certain ways (e.g. you won't see highlights for the Sub-Components that make the pop-up panels for site creation, file upload, etc) and since the highlights are absolutely positioned on the page (to avoid affecting the DOM structure) they are not guaranteed to be in pixel perfect position - the rough position of a highlight and the information contained in its pop-up should hopefully be sufficient though!

You should also not attempt to drive an applications user interface with SurfBug enabled. The most effective way we've found of using it is to navigate to the page you're interested in, toggle SurfBug on from another tab in your browser and then refresh the application page. If you need to move onto another page - simply toggle SurfBug back off, reload the page, navigate and switch back on.

One other important point is that Surf Bug gets enabled for the entire application - NOT just for the user that enables it. It's intended to be used in development, not production. It's 'admin' protected so regular users won't be able to switch it on, but if it gets enabled then every user will see the highlights until it's switched off again.

Information Provided

The following table provides a breakdown of the information that SurfBug provides:

Page ID:The ID of the Page being displayed
Template ID:The ID of the Template being displayed
Template Type:Typically this is the path of the FreeMarker template used to render the Spring Surf Template referenced by the Page.
Component Details
ID:The ID of the Component that the Sub-Component belongs to.
Definition Location:The runtime path of the file containing the configuration for the Component
GUID:Generated unique id of the component
Region-id:The id of the region the template into which the component has been bound
Source-id:The id of the object at which the component is defined (this will typically be a Page id, a Template id or will be 'global')
Scope:The scope at which the Component has been defined (this will typically be 'global', 'page' or 'template').
Custom Properties:Any custom properties that have been configured for the component. These are not used by Spring Surf to perform any rendered but may be used by the Component itself if it is parameterized in any way (this may be the case for Components backed by JSPs, WebScripts or FreeMarker).
Sub-Component Details
ID:The id of the Sub-Component - this is always prefixed by the parent Component id and a '#' indicates the start of Sub-Components identification
Contributing Paths:The runtime paths of all the files that have provided input into this Sub-Component (a Sub-Components property, index and evaluation configuration can all be updated by zero or more extension modules). If no extensions have been applied then this will only contain a single path.
Index:The specifically set index of the Sub-Component within the Component. This is the final index after all extensions have been applied. If nothing is shown it means that the default is being used.
Processor:The processor that has been used to render the Sub-Component. If this Sub-Component has been generated from legacy configuration then this could be either WebScript, WebTemplate or JSP (or some custom processor) - but AdvancedComponents only currently support WebScript processors and if the Sub-Component is not legacy generated then this will be blank.
Evaluated URI:The URI used to render the Sub-Component. This is the URI that is generated as a result of processing all Evaluations across all extensions - so is not necessarily the value configured in the source configuration file.
Evaluated By:This is the id of the first successful Evaluation and therefore the one that returned the 'Evaluated URI' field. If this is blank it means that no Evaluations were performed on the Sub-Component.
WebScript Location:If the Sub-Component was rendered by a WebScript then this will show the runtime path of the WebScript descriptor file. The other WebScript files (template, controller, etc) will be co-located.
WebScript Details:This provides a link to the WebScript information which will be opened in a new tab/window.
Evaluated Properties:The properties for the Sub-Component as returned by a successful Evaluation. Properties can be overridden by Evaluations to change how a Sub-Component is rendered.
Extensibility Directives:A list of the extensibility directives that have been applied to the Sub-Component.
10 Comments
blog_commenter
Active Member
hey,
looks like it is already in 3.4.4 enterprise.
this is soo cool.

thanks a lot for your post
blog_commenter
Active Member
[...] external libraries (Peerbind and jQuery) as well as the extension XML using details I grabbed from SurfBug. I decided to extend the node-header in the document-details page. These are the files I [...]
blog_commenter
Active Member
I tried this on 3.4.3 and it caused Share to only return blank pages. I can't disable it as the status page does not say it is enabled. Any ideas?
ddraper
Intermediate II
This tool was intended to work with 4.0 onwards and there could be some issues with the 3.4.x releases (it has been reported in an earlier comment that it works in 3.4.4 though).  This is a Spring Surf feature rather than part of Alfresco Share so its development was not specifically tied to any release. Spring Surf libraries that contain SurfBug have been included in the later 3.4.x releases which is why it appears as an option.
blog_commenter
Active Member
Thanks for the feedback. I didn't necessarily expect it to work in 3.4.3 but I also didn't expect it to 'break' Share. I've tried restarting the server... it still comes back with only blank white pages (I think in Firefox this is an empty response).
ddraper
Intermediate II
That's very strange... SurfBug only dynamically changes the content and neither its output nor configuration status is persisted - so recycling the server should ensure that it's disabled.  When you view /share/page/surfBugStatus is it showing up as enabled? I'm assuming you've done the usual things like cache clearing the browser, etc?
blog_commenter
Active Member
I did all of that and still it doesn't work. But oddly enough I tried a different browser (IE) and did get the following stack trace:

10:13:27,231 ERROR [org.alfresco.web.site] org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.extensions.surf.exception.UserFactoryException: Unable to retrieve user from repository
org.springframework.extensions.surf.exception.UserFactoryException: Unable to retrieve user from repository
at org.springframework.extensions.surf.support.AlfrescoUserFactory.loadUser(AlfrescoUserFactory.java:188)
at org.springframework.extensions.surf.support.AbstractUserFactory.initialiseUser(AbstractUserFactory.java:176)
at org.springframework.extensions.surf.support.AbstractUserFactory.initialiseUser(AbstractUserFactory.java:99)
at org.springframework.extensions.surf.RequestContextUtil.initialiseUser(RequestContextUtil.java:203)
at org.springframework.extensions.surf.RequestContextUtil.populateRequestContext(RequestContextUtil.java:176)
at org.springframework.extensions.surf.RequestContextUtil.populateRequestContext(RequestContextUtil.java:131)
at org.springframework.extensions.surf.mvc.AbstractWebFrameworkView.populateRequestContext(AbstractWebFrameworkView.java:350)
at org.springframework.extensions.surf.mvc.AbstractWebFrameworkView.renderMergedOutputModel(AbstractWebFrameworkView.java:260)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1060)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:798)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
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 org.alfresco.web.site.servlet.MTAuthenticationFilter.doFilter(MTAuthenticationFilter.java:74)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.alfresco.web.site.servlet.SSOAuthenticationFilter.challengeOrPassThrough(SSOAuthenticationFilter.java:596)
at org.alfresco.web.site.servlet.SSOAuthenticationFilter.doFilter(SSOAuthenticationFilter.java:333)
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:127)
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:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:662)
Caused by: org.json.JSONException: A JSONObject text must begin with '{' at character 47
at org.json.JSONTokener.syntaxError(JSONTokener.java:413)
at org.json.JSONObject.(JSONObject.java:180)
at org.json.JSONObject.(JSONObject.java:420)
at org.springframework.extensions.surf.support.AlfrescoUserFactory.loadUser(AlfrescoUserFactory.java:182)
... 34 more
10:14:44,648 ERROR [org.alfresco.web.site] org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.extensions.surf.exception.UserFactoryException: Unable to retrieve user from repository
org.springframework.extensions.surf.exception.UserFactoryException: Unable to retrieve user from repository
at org.springframework.extensions.surf.support.AlfrescoUserFactory.loadUser(AlfrescoUserFactory.java:188)
at org.springframework.extensions.surf.support.AbstractUserFactory.initialiseUser(AbstractUserFactory.java:176)
at org.springframework.extensions.surf.support.AbstractUserFactory.initialiseUser(AbstractUserFactory.java:99)
at org.springframework.extensions.surf.RequestContextUtil.initialiseUser(RequestContextUtil.java:203)
at org.springframework.extensions.surf.RequestContextUtil.populateRequestContext(RequestContextUtil.java:176)
at org.springframework.extensions.surf.RequestContextUtil.populateRequestContext(RequestContextUtil.java:131)
at org.springframework.extensions.surf.mvc.AbstractWebFrameworkView.populateRequestContext(AbstractWebFrameworkView.java:350)
at org.springframework.extensions.surf.mvc.AbstractWebFrameworkView.renderMergedOutputModel(AbstractWebFrameworkView.java:260)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1060)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:798)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
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 org.alfresco.web.site.servlet.MTAuthenticationFilter.doFilter(MTAuthenticationFilter.java:74)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.alfresco.web.site.servlet.SSOAuthenticationFilter.challengeOrPassThrough(SSOAuthenticationFilter.java:596)
at org.alfresco.web.site.servlet.SSOAuthenticationFilter.doFilter(SSOAuthenticationFilter.java:333)
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:127)
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:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:662)
Caused by: org.json.JSONException: A JSONObject text must begin with '{' at character 47
at org.json.JSONTokener.syntaxError(JSONTokener.java:413)
at org.json.JSONObject.(JSONObject.java:180)
at org.json.JSONObject.(JSONObject.java:420)
at org.springframework.extensions.surf.support.AlfrescoUserFactory.loadUser(AlfrescoUserFactory.java:182)
... 34 more
10:14:57,267 ERROR [org.springframework.extensions.webscripts.AbstractRuntime] Exception from executeScript - redirecting to status template error: Failed to initialize RequestContext for local WebScript runtime: Unable to fault user as safeguard during init request context
java.io.IOException: Failed to initialize RequestContext for local WebScript runtime: Unable to fault user as safeguard during init request context
at org.springframework.extensions.webscripts.LocalWebScriptRuntimeContainer.executeScript(LocalWebScriptRuntimeContainer.java:202)
at org.springframework.extensions.webscripts.AbstractRuntime.executeScript(AbstractRuntime.java:352)
at org.springframework.extensions.webscripts.AbstractRuntime.executeScript(AbstractRuntime.java:189)
at org.springframework.extensions.webscripts.servlet.mvc.WebScriptView.renderMergedOutputModel(WebScriptView.java:99)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1060)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:798)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
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 org.alfresco.web.site.servlet.MTAuthenticationFilter.doFilter(MTAuthenticationFilter.java:74)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.alfresco.web.site.servlet.SSOAuthenticationFilter.challengeOrPassThrough(SSOAuthenticationFilter.java:596)
at org.alfresco.web.site.servlet.SSOAuthenticationFilter.doFilter(SSOAuthenticationFilter.java:333)
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:127)
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:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:662)

The interesting thing is that after restarting the server (again), I only get a blank page in IE as well. I tried this from another computer connecting to the 'broken' server and I get the same result, blank page after restart.

When I access the /share/page/surfBugStatus (the first time) I get a webscript error (which I can't get back to to show, but believe it is the same as above). I was able to get through the login page for Share this time but after that got a page not found error. Subsequently after the restart, I only get a blank page when trying to login to share.

I will take a look at the stack trace and see what I can figure out.
ddraper
Intermediate II
I'm sorry that you're having these issues, but that stack trace doesn't appear to be related to SurfBug in any way. What URL are you hitting to see that stack trace? It appears to relate to loading a user from the UserFactory... have both the Share and Alfresco web applications started correctly? Can you log into the Alfresco application? This is where Share will attempt to authenticate and load user information. If these problems persist I'd suggest that we move this discussion onto the Alfresco forums.
blog_commenter
Active Member
I was accessing localhost:8080/share/page/site-index or localhost:8080/share/page/surfBugStatus... it doesn't matter every page gave that stack trace. Everything worked perfectly normally until I enabled SurfBug. I am still able to login to the Explorer interface. I really don't want to waste that much time on it, this is a development instance so I will just drop the DB and content store and start from scratch. Again, it is alarming that SurfBug seems to have caused Share to fail catastrophically.
blog_commenter
Active Member
Huh, turns out that after deleting my exploded war files in Tomcat everything appears to work fine.