Can a TC plugin add *two* build-type tabs?

My plugin adds a tab to build configurations. Now I am trying to add another tab, again a build-configuration one. Is that possible?

My solution consists of a JSP file backed by a class that extends BuildTypeTab. That class has
static String getTabCode() { return "sin-city"; }
where "sin-city" is my plugin's ID, as found in

  • teamcity-plugin.xml, XPath /teamcity-plugin/info/name
  • pom.xml, XPath /project/artifactId


Am I right thinking that the getTabCode() value must match what's declared in the XML files?

If I add another JSP file, and another backing class that extends BuildTypeTab, and let it also return "sin-city", then the two build-type tabs overwrite each other.

Please advise.

4 comments
Comment actions Permalink

You definitely can create more than one build configuration tab. But you need to use different tabCode and it is not necessary to have the same tabCode as name of plugin defined in teamcity-plugin.xml.

0
Comment actions Permalink

Thanks, Pavel. I've tried using a non-matching tabCode and the tab doesn't display.

For this testing, I've commented out one build-type tab, so I only have one left. All I'm trying is to make the tabCode different from the name of the plugin.

I have:

  • teamcity-plugin.xml, XPath /teamcity-plugin/info/name = "sin-city"
  • pom.xml, XPath /project/artifactId = "sin-city"
  • public class FailureCulpritOverviewTab extends BuildTypeTab {
     
    ...
     
        static String getTabCode() { return "sin-city-overview"; }
     
    ...
     
    }
  • build-server-plugin-sin-city.xml contains
  •  
    <bean class="sferencik.teamcity.sincity.failureCulpritOverview.FailureCulpritOverviewTab">
        <property name="includeUrl" value="failureCulpritOverview.jsp"/>
    </bean>


The build-type tab is displayed but when I click it it's empty. The server log gives a hint (see below). It seems it's looking for the JSP file in the "sin-city-overview" subdirectory. Is there a way to fix this?

Thanks,
Sam

[2015-11-20 12:28:17,984]  ERROR -   jetbrains.buildServer.SERVER - Error javax.servlet.jsp.JspException: javax.servlet.jsp.JspException: javax.servlet.jsp.JspException: javax.servlet.ServletException: javax.servlet.ServletException: File &quot;/plugins/sin-city-overview/failureCulpritOverview.jsp&quot; not found while processing request: GET '/viewType.html?buildTypeId=Sam_SinCity&tab=sin-city-overview', from client 10.98.134.64:64561, authenticated as 'ferencis' (Ferencik, Samuel: Markets (PRG)) {id=14}
javax.servlet.jsp.JspException: javax.servlet.jsp.JspException: javax.servlet.jsp.JspException: javax.servlet.ServletException: javax.servlet.ServletException: File &quot;/plugins/sin-city-overview/failureCulpritOverview.jsp&quot; not found
 at org.apache.jsp.viewType_jsp$Helper.invoke(viewType_jsp.java:2342)
 at org.apache.jsp.tag.webpage_tag.doTag(webpage_tag.java:569)
 at org.apache.jsp.viewType_jsp._jspService(viewType_jsp.java:260)
 at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
 at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
 at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:395)
 at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:339)
 at jetbrains.spring.web.TeamCityJSPServletImpl.access$001(TeamCityJSPServletImpl.java:16)
 at jetbrains.spring.web.TeamCityJSPServletImpl$2.apply(TeamCityJSPServletImpl.java)
 at jetbrains.buildServer.util.Util.doUnderContextClassLoader(Util.java:78)
 at jetbrains.spring.web.TeamCityJSPServletImpl.service(TeamCityJSPServletImpl.java:6)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
 at jetbrains.spring.web.JspController.doHandle(JspController.java:13)
 at jetbrains.buildServer.controllers.BaseController.handleRequestInternal(BaseController.java:75)
 at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:154)
 at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:50)
 at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
 at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
 at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
 at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
 at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
 at jetbrains.buildServer.maintenance.TeamCityDispatcherServlet.service(TeamCityDispatcherServlet.java:32)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
 at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
 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.ApplicationDispatcher.invoke(ApplicationDispatcher.java:748)
 at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:486)
 at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:411)
 at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:338)
 at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:209)
 at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:267)
 at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1221)
 at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1005)
 at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:952)
 at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
 at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
 at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
 at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
 at jetbrains.buildServer.maintenance.TeamCityDispatcherServlet.service(TeamCityDispatcherServlet.java:32)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
 at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
 at jetbrains.buildServer.web.DependencyParametersCalculationContextFilter.doFilter(DependencyParametersCalculationContextFilter.java:8)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
 at jetbrains.buildServer.web.DisableSessionIdFromUrlFilter.doFilter(DisableSessionIdFromUrlFilter.java:5)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
 at jetbrains.buildServer.diagnostic.web.DiagnosticFilter.doFilter(DiagnosticFilter.java:48)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
 at jetbrains.buildServer.web.ResponseFragmentFilter.doFilter(ResponseFragmentFilter.java:25)
 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.StandardHostValve.invoke(StandardHostValve.java:170)
 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
 at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1074)
 at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
 at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1739)
 at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1698)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
 at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
 at java.lang.Thread.run(Thread.java:744)
Caused by: javax.servlet.jsp.JspException: javax.servlet.jsp.JspException: javax.servlet.ServletException: javax.servlet.ServletException: File &quot;/plugins/sin-city-overview/failureCulpritOverview.jsp&quot; not found
 at org.apache.jsp.viewType_jsp$Helper.invoke(viewType_jsp.java:2342)
 at org.apache.jsp.tag.webrefreshable_tag.doTag(webrefreshable_tag.java:146)
 at org.apache.jsp.viewType_jsp$Helper.invoke19(viewType_jsp.java:2051)
 at org.apache.jsp.viewType_jsp$Helper.invoke(viewType_jsp.java:2301)
 ... 76 more
Caused by: javax.servlet.jsp.JspException: javax.servlet.ServletException: javax.servlet.ServletException: File &quot;/plugins/sin-city-overview/failureCulpritOverview.jsp&quot; not found
 at org.apache.jsp.tag.webext.includeExtension_tag.doTag(includeExtension_tag.java:159)
 at org.apache.jsp.tag.webext.showTabs_tag._jspx_meth_ext_005fincludeExtension_005f0(showTabs_tag.java:632)
 at org.apache.jsp.tag.webext.showTabs_tag._jspx_meth_c_005fif_005f5(showTabs_tag.java:607)
 at org.apache.jsp.tag.webext.showTabs_tag.doTag(showTabs_tag.java:232)
 at org.apache.jsp.viewType_jsp$Helper.invoke26(viewType_jsp.java:2146)
 at org.apache.jsp.viewType_jsp$Helper.invoke(viewType_jsp.java:2322)
 ... 79 more
Caused by: javax.servlet.ServletException: javax.servlet.ServletException: File &quot;/plugins/sin-city-overview/failureCulpritOverview.jsp&quot; not found
 at jetbrains.spring.web.TeamCityJSPServletImpl.service(TeamCityJSPServletImpl.java:11)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
 at jetbrains.spring.web.JspController.doHandle(JspController.java:13)
 at jetbrains.buildServer.controllers.BaseController.handleRequestInternal(BaseController.java:75)
 at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:154)
 at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:50)
 at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
 at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
 at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
 at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
 at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
 at jetbrains.buildServer.maintenance.TeamCityDispatcherServlet.service(TeamCityDispatcherServlet.java:32)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
 at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:748)
 at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:604)
 at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:543)
 at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:954)
 at org.apache.jsp.tag.webext.includeExtension_tag._jspx_meth_c_005fif_005f3(includeExtension_tag.java:521)
 at org.apache.jsp.tag.webext.includeExtension_tag._jspx_meth_c_005fif_005f0(includeExtension_tag.java:184)
 at org.apache.jsp.tag.webext.includeExtension_tag.doTag(includeExtension_tag.java:148)
 ... 84 more
Caused by: javax.servlet.ServletException: File &quot;/plugins/sin-city-overview/failureCulpritOverview.jsp&quot; not found
 at org.apache.jasper.servlet.JspServlet.handleMissingResource(JspServlet.java:417)
 at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:384)
 at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:339)
 at jetbrains.spring.web.TeamCityJSPServletImpl.access$001(TeamCityJSPServletImpl.java:16)
 at jetbrains.spring.web.TeamCityJSPServletImpl$2.apply(TeamCityJSPServletImpl.java)
 at jetbrains.buildServer.util.Util.doUnderContextClassLoader(Util.java:78)
 at jetbrains.spring.web.TeamCityJSPServletImpl.service(TeamCityJSPServletImpl.java:6)
 ... 106 more

0
Comment actions Permalink

Since relative path to jsp is specified, TeamCity by default tries to locate it under /plugins/tabCode/ directory.
You can fix this by asking for jetbrains.buildServer.web.openapi.PluginDescriptor class in constructor of your tab and then use something like this:

PluginDescriptor pluginDescriptor = ...;
setIncludeUrl(pluginDescriptor.getPluginResourcesPath(/some/path/to/your/jsp/from/buildServerResources/dir));

0
Comment actions Permalink

Thank you, that did the trick!
Sam

0

Please sign in to leave a comment.