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

Sunday, January 17, 2010

Literature for the "Business IT Alignment" Course, ITU spring semester 2009

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

In the spring semester of 2009 I've taken the course "Business IT Alignment". My preparation has been quite crippled by what seems to be a continuous stream of influenza that I've picked up since the day before new year (I've coined it The ultra-flu). In my effort to prepare for the exam I've several times found my self searching for the right articles and the related course slides, so here I've decided to create a post to build up that information (probably only of real interest for myself).

The Course seems to have run at least since 2005, with Lars Andersen taking part in 4 consecutive years. This semester with a completely new duo of teachers. The base reference is the course program [PDF]. Supplemented with the course homepage/slides from this and the previous semester:

Books

IT Governance: How Top Performers Manage IT Decision Rights for Superior Results

Spring 2009

Spring 2008


Innovation: The Five Disciplines for Creating What Customers Want

Spring 2009

Spring 2009


The Innovator's Dilemma: The Revolutionary Book that Will Change the Way You Do Business

Slides

Articles

Strategies for Information Technology Governance

Chapter II - Integration Strategies and Tactics for Information Technology Governance (pages 37-74).

Slides


"Linking the IT Balanced Scorecard to the Business Objectives at a Major Canadian Financial group" [PDF] Wim Van Grembergen, University of Antwerp (UFSIA),Ronald Saull, Information Services Divisions of Great-West Life, London Life, Investors Group Steven De Haes, University of Antwerp Management School (UAMS)

Spring 2009


Cultures of Technology And the Quest for Innovation.
The Introduction [PDF] (pages 1-23).

Spring 2009

Xtras for the eager pupil

"Using the Balanced Scorecard as a Strategic Management System" [PDF], Robert S. Kaplan, David P. Norton.

Read more

Tuesday, August 11, 2009

Resolving the XHTML1 DTD locally - avoiding problems with the W3C 503 access blocking

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

Currently I'm doing a project that need some simple web scraping where I'm using CyberNeko HTML Parser (nekoHTML) which relies on Xerces. As I was running my first simple spike I encountered:

Exception in thread "main" java.io.IOException: 
Server returned HTTP response code: 503 for URL: http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd

Whaoo, my first guess was that the URL was wrong, but it turned out to be okay. After a quick search I found the reason to be a deliberate move as can be read on W3C Systems Team Blog post "W3C's Excessive DTD Traffic". The essence of the problem is:

..In particular, software does not usually need to fetch these resources, and certainly does not need to fetch the same one over and over! Yet we receive a surprisingly large number of requests for such resources: up to 130 million requests per day, with periods of sustained bandwidth usage of 350Mbps, for resources that haven't changed in years.

Oouch, that's a lot of bandwidth. I've heard of a simliar problem, though of much smaller scale, with Schemas for OIOUBL Invoice version 0.7 from the former ISBs (Info Structure Base) repository.

Solution

Lucklily it is quite easy to do right yourself with XML Catalogs, pulling from a local repository. cbowditchs guide "Resolving DTD system URI with XMLCatalogResolver" helped me a lot and I didn't have any problems with it like he had. First you'll need to fetch the DTD and it's depencies:

create a catalog file:

    1 <?xml version="1.0"?>
    2 <catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
    3   <public publicId="-//W3C//DTD XHTML 1.0 Transitional//EN"
    4           uri="xhtml1-transitional.dtd"/>
    5 </catalog>

and adding it's use to the code like:

..  
XMLCatalogResolver resolver = new XMLCatalogResolver();
resolver.setCatalogList(new String[] {"etc/dtd/xhtml1-catalog.xml"});

DOMParser parser = new DOMParser();
parser.setProperty("http://apache.org/xml/properties/internal/entity-resolver", resolver);
..

Read more

Monday, July 6, 2009

Performing a Conconi running test

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

Second update: did a competition like 5 km run on 1. september and did a comparison. Updated: did a new test in the start of august which is compared at the bottom. I'm a typical gadget rich amateur athlete and my favorite tool is a Heart Rate Monitor (HRM). For many years it was my trusty Polar xTrainer, later Polar CS200C and for the last year a Garmin Forerunner 305. The HR is an indicator of the work/stress done, but to really put it into use it can be used to structure the workouts. Any matter the exact structuring you like there's the need for tests to identify some boundaries, primarily the anaerobic threshold. Another value of tests is to track progress through season. One test that everybody can do is the Conconi test and for the first time in a looong time I did one yesterday.

Background

Back in the late nineties I bought the book "Trening melkesyre hjertefrekvens", a norwegian translation of of Peter G. J. M. Janssen book Training Lactate Pulse-Rate. An excellent book that's easily read and based on facts around HRM training and riaerch with examples. The book recommends real lactate tests (for those that can afford it/professionals) or the Conconi test. Back when I bought the book I did several tests with varying success in terms of finding the anaerobic threshold (da: "knækpunktet"). I guess that there could be many reasons why my practical tests didn't follow the textbook: one being that I'm not top athlete.

While getting ready for the test yesterday I first remembered the theory falsely. My own subjective experience is that when truing to keep a high speed/pace extra pulse points (heart beats per minutes) doesn't seem to translate into speed, which lead my to think that after the threshold the pulse would increase with little increase in speed. That's just opposite to the book where the pulse doesn't increase much with speed since it's anaerobic!

The Test

I did the test on a treadmill since that'll give me an even pace, and after at 10 min warmup (maybe not hard enough) I was ready. I expected my threshold to be around 5 min/km (12 km/h) and started at 9,2 km/h and increased the speed with 0,4 km/h foreach 200 m, and ended at 14 km/h. Nothing impressive (I know) and I would have liked to reach 15 km/h, but is simply out of reach. I tracked my HR with the FR and made a voice recording where I said the speed and HR just before increasing speed, since this gives assurance that I didn't miss anything and was certain of the speed correlation that the FR knew nothing about. Here the workout as it's seen in SportsTracks:

There's a clear trend but it's a little bumpy. Putting the data into a table and producing a diagram with Calc give this graph:

It does not fit that clearly with the textbook as there is no real significant change, but that'll not hold me back! So here's my best guess:

According to this my anaerobic threshold should be at 162 bpm with a speed (pace) of 12,8 km/h (4:41 min/km).

Reflection

Funny enough this is similar to the tests I did approximately 10 years ago. It does seem a little high since my PB for 5 km is 24:40 (3 weeks ago) and I felt like 160 bpm was a limit. It can be true but certainly an important fact is that I bike much more than I run, so maybe i have cardiovascular capacity for this, but there more to than that.

This evening i tried a interval workout aiming for 160 bpm, which was quite hard to reach, but the pace was a little better. One thing is hitting the level, the theory says that it sould be able to kepp it for an hour, which i consider highly unlikely

New test in start of August

After about a month of training in my summer vacation I was eager to repeat the test and measure up my progress - what a disappointment! During the test I concluded that I had made no progress at all and in fact as the graph shows there's a general set back. Just like the first test there's no clear breaking point to indicate the threshold (just as Joe Friel has experienced).

I've got no real explanation for it. The conditions seemed very similar with a hot gym and my only ideas are that I did a much more thorough warmup and maybe a slight bit of flue. Another guess could be that progress is discrete and not as linear as some textbooks could indicate and I simply hadn't hit the next step.

My 5 km PB in the DHL Stafet 2009

I haven't participated in any competitions so this is my only competiton like result for comparison. It went fine with a PB of 23 minutes, the workout profile was like:<(p>

And my retro-splits were:

It should be added that this event is just as much a social as a sports event, and the last part was quite crinkly and crowded, but I could probably not cut off many more seconds at the present time and form.

With a pace of 4:36 min/km this in within proximity of a reasonable time compared with the tests. Since in principle I should be able to hold the LT for about an hour the 5 km pace should be considerable above LT.

Looking forward I've looked at a couple of prediction tables. First from the Furman institute EQUIVALENT PERFORMANCES AT DIFFERENT DISTANCES [PDF]:

and another one based on The McMillan Running Calculator :

They certainly raise my optimism with an outlook to a marathon in the range of 3:44 - I just hope I can keep up the pace for that long.

Links

Here's a list of links I've gathered while browsing for facts and examples on Conconi running test.

Read more