Sunday, February 28, 2010

Picky Tomcat parsing of function taglib descriptor element 'function-signature'

pencil icon, that"s clickable to start editing the post

After spending way way to much time figuring out what kind of an error I had introduced into my webapp it turned out the Tomcat/Jasper does what seems to be as a very non-xml'ish parsing of the tld. Here's to those of you out there that stumble upon these error messages. The heart of my learning is that the element defining the function-signature should be on one line! This example is bad:

<function>
   <description>.....</description>
   <name>myTagLibFunction</name>
   <function-class>my.package.taglib.functionClass</function-class>
   <function-signature>my.package.returnValue[] 
myTagLibFunction(java.lang.String,java.util.Calendar)</function-signature>
   <example>.....</example>
</function>

and this one should be fine:

<function>
   <description>.....</description>
   <name>myTagLibFunction</name>
   <function-class>my.package.taglib.functionClass</function-class>
   <function-signature>my.package.returnValue[] myTagLibFunction(java.lang.String,java.util.Calendar)</function-signature>
   <example>.....</example>
</function>

It was my pretty formatting the ruined it for me. Here's first an error message that at least make sense (contrary to the next one):

Exception: org.apache.jasper.JasperException: Invalid syntax for function signature in TLD. Tag Library: myChoosePrefix, Function: myTagLibFunction

and the complete stacktrace:

org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:51)
org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:409)
org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:164)
org.apache.jasper.compiler.Validator$ValidateVisitor.getMethod(Validator.java:1536)
org.apache.jasper.compiler.Validator$ValidateVisitor.processSignature(Validator.java:1523)
org.apache.jasper.compiler.Validator$ValidateVisitor.access$400(Validator.java:411)
org.apache.jasper.compiler.Validator$ValidateVisitor$1FVVisitor.visit(Validator.java:1499)
org.apache.jasper.compiler.ELNode$Function.accept(ELNode.java:129)
org.apache.jasper.compiler.ELNode$Nodes.visit(ELNode.java:200)
org.apache.jasper.compiler.ELNode$Visitor.visit(ELNode.java:242)
org.apache.jasper.compiler.ELNode$Root.accept(ELNode.java:56)
org.apache.jasper.compiler.ELNode$Nodes.visit(ELNode.java:200)
org.apache.jasper.compiler.Validator$ValidateVisitor.validateFunctions(Validator.java:1503)
org.apache.jasper.compiler.Validator$ValidateVisitor.checkXmlAttributes(Validator.java:1139)
org.apache.jasper.compiler.Validator$ValidateVisitor.visit(Validator.java:819)
org.apache.jasper.compiler.Node$CustomTag.accept(Node.java:1512)
org.apache.jasper.compiler.Node$Nodes.visit(Node.java:2343)
org.apache.jasper.compiler.Node$Visitor.visitBody(Node.java:2393)
org.apache.jasper.compiler.Validator$ValidateVisitor.visit(Validator.java:515)
org.apache.jasper.compiler.Node$JspRoot.accept(Node.java:566)
org.apache.jasper.compiler.Node$Nodes.visit(Node.java:2343)
org.apache.jasper.compiler.Node$Visitor.visitBody(Node.java:2393)
org.apache.jasper.compiler.Node$Visitor.visit(Node.java:2399)
org.apache.jasper.compiler.Node$Root.accept(Node.java:489)
org.apache.jasper.compiler.Node$Nodes.visit(Node.java:2343)
org.apache.jasper.compiler.Validator.validate(Validator.java:1737)
org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:165)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:314)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:294)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:281)
org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:566)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:317)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:337)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:630)
org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:436)
org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:374)
org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:240)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:258)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1174)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:901)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:809)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
java.lang.Thread.run(Thread.java:619)

The cryptic one had me doing all kinds of odd stuff for trying to isolate the problem. Unfortunately I've deleted the local logfiles but it said something with substring indexoutofbounds -19

Currently I'm just happy to have found the it's Tomcat/Jasper that's picky (during compilation) but I haven't looked at neither specification nor code.

Read more

Saturday, February 13, 2010

An example on Common Look and Feel - The University of British Columbia

pencil icon, that"s clickable to start editing the post

I've for some time been intrigued to figuring out what (Common) Look & Feel can be defined as. In this post I'll have a look at an real life example from University of British Columbia. Here's first their own definition of it:

The UBC CLF, or "common look and feel", is a web design framework that supports the visual identity and online reputation of the University of British Columbia by providing a common look, feel and functionality to UBC websites.

with the stated goal to:

  • Create a predictable user experience across the web at UBC (e.g. allow users to easily navigate from one UBC site to another, provide some consistency in user interface elements across UBC sites)
  • Provide easy access to high-frequency-use UBC web tools (e.g. Search, Directories) and key UBC web properties
  • Ensure that UBC websites consistently support the visual identity of the university.

These goals are achieved through standardization of university-wide website elements in terms of:

  • content
  • visual appearance
  • interaction behaviour

I like this definition as it is clear and understandable. It would not be fair to start dissecting it before having a closer look at how it's defined in practice, in the Design Specifications of the CLF.

The CLF Framework is devided into Primary- and Secondary-CLF Elements.

The Primary-CLF Elements are:

  1. Required content, design, links and functionality that
    1. Warrant placement in every UBC website across the university due to their high level of use or their strategic value from a web communications perspective, and
    2. Are relevant to all campus locations.
  2. Optional content, links and functionality that adhere to a university-wide standard.
  3. Reserved space for these required and optional university-wide elements.

The Secondary-CLF Elements are:

  1. Required content, design, links and functionality to mark campus location where appropriate.
  2. Site-specific content, design, links, and functionality that can be customized on a site-by-site basis to accommodate localization of unit-level needs (e.g. Campus location, Faculty / Departmental-specific information etc.).
  3. Reserved space for these site-specific elements.

Honestly I don't really understand what this distinction is except the difference between global and site specific elements. Anyway they have defined two levels of compliance. First the Minimum CLF require the following elements:

  • UBC CLF Background
  • Global Utility Header
  • Visual Identity Header
  • Visual Identity Footer
  • Global Utility Footer

and it's visualized in this graphic where the required elements are highlighted in green:

The Full CLF requires the following elements:

  • UBC CLF Background (Minimum CLF Element)
  • Global Utility Header (Minimum CLF Element)
  • Visual Identity Header (Minimum CLF Element)
  • UBC CLF Primary Navigation
  • UBC CLF Secondary Navigation
  • UBC CLF Content Space
  • Sub Footer
  • Visual Identity Footer (Minimum CLF Element)
  • Global Utility Footer (Minimum CLF Element)

The difference is explained as:

The Full CLF consists of the Minimum CLF elements and the optional content areas of the templates including CSS styles and layouts. The area highlighted in red in the graphic image below indicates the optional content areas which together with the green areas make up the Full CLF.

UBC has a list of complying websites: websites have completed CLF implementation. I've picked some of these sites to have a closer look for one to see the variation and to ensure that it actually runs on different servers/setups.

Board of Governors

The Board of Governors has the URL: http://www.bog.ubc.ca/. Fetching the index pages gives the following headers:

$ wget -S http://www.bog.ubc.ca/
--15:08:57--  http://www.bog.ubc.ca/
           => `index.html.1'
Resolving www.bog.ubc.ca... 137.82.105.5
Connecting to www.bog.ubc.ca|137.82.105.5|:80... connected.
HTTP request sent, awaiting response...
  HTTP/1.1 200 OK
  Connection: keep-alive
  Date: Sun, 07 Feb 2010 14:14:38 GMT
  Server: Microsoft-IIS/6.0
  X-Powered-By: ASP.NET
  Content-Length: 361
  ETag: "baf57961e646ca1:663"
  Last-Modified: Wed, 07 Oct 2009 00:37:42 GMT
  Content-Type: text/html
Length: 361 [text/html]

and the page looks like:

Engineering

Engineering has the URL http://www.engineering.ubc.ca/. The sites respond with the headers:

$ wget -S http://www.engineering.ubc.ca/
--15:10:40--  http://www.engineering.ubc.ca/
           => `index.html.2'
Resolving www.engineering.ubc.ca... 142.103.119.227
Connecting to www.engineering.ubc.ca|142.103.119.227|:80... connected.
HTTP request sent, awaiting response...
  HTTP/1.1 200 OK
  Date: Sun, 07 Feb 2010 14:12:16 GMT
  Server: Apache/2.2.9 (Debian) PHP/5.2.6-1+lenny4 with Suhosin-Patch mod_ssl/2.2.9 OpenSSL/0.9.8g
  X-Powered-By: PHP/5.2.6-1+lenny4
  Vary: Accept-Encoding
  Connection: close
  Content-Type: text/html; charset=UTF-8
  Content-Language: en-US
Length: unspecified [text/html]

Ombudsperson for Students, Office of the

Office of the Ombudsperson for Students has the URL http://www.ombudsoffice.ubc.ca/.

$ wget -S http://www.ombudsoffice.ubc.ca/
--15:12:49--  http://www.ombudsoffice.ubc.ca/
           => `index.html.3'
Resolving www.ombudsoffice.ubc.ca... 67.220.228.80
Connecting to www.ombudsoffice.ubc.ca|67.220.228.80|:80... connected.
HTTP request sent, awaiting response...
  HTTP/1.1 200 OK
  Date: Sun, 07 Feb 2010 14:18:31 GMT
  Server: Apache
  X-Powered-By: PHP/5.2.11
  X-Pingback: http://www.ombudsoffice.ubc.ca/xmlrpc.php
  Set-Cookie: PHPSESSID=9da99fe72307b2b27fd6d5fb3d515af8; path=/
  Connection: close
  Content-Type: text/html; charset=UTF-8
Length: unspecified [text/html]

President's Office

The President's Office has the URL http://www.president.ubc.ca/

$ wget -S http://www.president.ubc.ca/
--15:14:30--  http://www.president.ubc.ca/
           => `index.html.4'
Resolving www.president.ubc.ca... 137.82.105.16
Connecting to www.president.ubc.ca|137.82.105.16|:80... connected.
HTTP request sent, awaiting response...
  HTTP/1.1 200 OK
  Content-Length: 15234
  Content-Type: text/html
  Content-Location: http://www.president.ubc.ca/index.html
  Last-Modified: Fri, 15 Jan 2010 00:23:45 GMT
  Accept-Ranges: bytes
  ETag: "10007995ca1:663"
  Server: Microsoft-IIS/6.0
  X-Powered-By: ASP.NET
  Date: Sun, 07 Feb 2010 14:20:12 GMT
  Connection: keep-alive
Length: 15,234 (15K) [text/html]

Wayfinding at UBC

Wayfinding at UBC has the URL http://www.maps.ubc.ca/

wget -S http://www.maps.ubc.ca/
--15:16:18--  http://www.maps.ubc.ca/
           => `index.html.5'
Resolving www.maps.ubc.ca... 199.175.106.55, 199.175.106.53, 199.175.106.54, ...
Connecting to www.maps.ubc.ca|199.175.106.55|:80... connected.
HTTP request sent, awaiting response...
  HTTP/1.1 302 Found
  Date: Sun, 07 Feb 2010 14:22:01 GMT
  Server: Apache
  X-Powered-By: PHP/4.4.4
  Location: /PROD/index.php
  Connection: close
  Content-Type: text/html
Location: /PROD/index.php [following]
--15:16:19--  http://www.maps.ubc.ca/PROD/index.php
           => `index.php'
Connecting to www.maps.ubc.ca|199.175.106.55|:80... connected.
HTTP request sent, awaiting response...
  HTTP/1.1 200 OK
  Date: Sun, 07 Feb 2010 14:22:01 GMT
  Server: Apache
  X-Powered-By: PHP/4.4.4
  Connection: close
  Content-Type: text/html
Length: unspecified [text/html]

Conclusion

I certainly found it interesting to investigate the UBC CLF a little. It's evident that it's implemented on different sites, servers and platforms. At a glance it looks like the look part and common navigation is common. I haven't got into whether the sites actually comply with the minimum or full profile, but some of the site specific color schemes does make them stick out. What would be very interesting to know is whether UBC had gotten to collect and analyse the effects in terms of user feedback, changed use behavior etc. Not often this information is picked up systematically nor made available online, so it's no surprise I didn't find it.
Without knowing the effect or cost I still want to congratulate UBC for their work and making the material availble online.

Read more