Oracle, od slova věštit

Ano, ano. Dnes jsem po nasazení nového buildu opět strávil plodné čtyři hodiny věštěním z křišťálové koule zvané Oracle Application Server. Ještě ke všemu na prostředí, ke kterému není přímý přístup. Kód, který máme již na tuctu instalací, který bez problémů běží i na dvou testovacích strojích s "přibližně" stejnou konfigurací na produkci ne a ne.

Výsledkem mého pátrání bylo to, že pokud se na konkrétní verzi OC4J zavolá metoda getParameterMap() dřív než některá z metod getParameter, getParameterNames nebo getParameterValues, tak je výsledkem prázdná mapa, přestože se v requestu parametry nachází.

Protože nejsem žádný dokonalý programátor, šel jsem do specifikace, abych si přečetl jestli to nejsem náhodou já, kdo je lamka a kdo nezná specifikaci Servletu. No schválně ...

Citace ze specifikace Servlet 2.3:

SRV.4.1 HTTP Protocol Parameters

Request parameters for the servlet are the strings sent by the client to a servlet container as part of its request. When the request is a HttpServletRequest object, and conditions set out below are met, the container populates the parameters from the URI query string and POST-ed data.

The parameters are stored as a set of name-value pairs. Multiple parameter values can exist for any given parameter name. The following methods of the ServletRequest interface are available to access parameters:

  • getParameter
  • getParameterNames
  • getParameterValues

The getParameterValues method returns an array of String objects containing all the parameter values associated with a parameter name. The value returned from the getParameter method must be the first value in the array of String objects returned by getParameterValues.

Data from the query string and the post body are aggregated into the request parameter set. Query string data is presented before post body data. For example, if a request is made with a query string of a=hello and a post body of a=goodbye&a=world, the resulting parameter set would be ordered a=(hello, goodbye, world).

Path parameters that are part of a GET request (as defined by HTTP 1.1) are not exposed by these APIs. They must be parsed from the String values returned by the getRequestURI method or the getPathInfo method.

SRV.4.1.1 When Parameters Are Available

The following are the conditions that must be met before post form data will be populated to the parameter set:

  1. The request is an HTTP or HTTPS request.
  2. The HTTP method is POST
  3. The content type is application/x-www-form-urlencoded
  4. The servlet has made an initial call of any of the getParameter family of methods on the request object.

If the conditions are not met and the post form data is not included in the parameter set, the post data must still be available to the servlet via the request object’s input stream. If the conditions are met, post form data will no longer be available for reading directly from the request object’s input stream.

Když porovnám toto znění se specifikací Servletu 2.4 přibyla k vyjmenovaným metodám i metoda getParameterMap. Nicméně tato metoda již standardně byla už v rozhraní Requestu ve verzi 2.3. Pravděpodobně se tedy ve specifikaci na tuto metodu pozapomělo a programátoři Oracle místo přemýšlení otrocky přetvořili specifikaci do kódu.

Osobně bych větu "The servlet has made an initial call of any of the getParameter family" chápal přirozeně tak, že tam patří i metoda getParameterMap. Naštěstí jsem namátkou vygooglil existenci  über nastavení "webwork.dispatcher.parametersWorkaround" prastarého WebWorku:


if (paramsWorkaroundEnabled) {
   // simply read any parameter (existing or not) to "prime" the request
   request.getParameter("foo");
}

Z poznámek v kódu jsem vyrozuměl, že podobným výkladem trpí i WebLogic.

Opravdu mám rád kód a knihovny jejichž autoři přemýšlí nad tím, jak a k čemu se bude jejich dílo používat. Třeba takový Spring - ten prostě funguje. A nejen to - každou chvíli tam objevuji věci, které mi jako programátorovi výrazně ulehčují život. To se prostě s OC4J nedá vůbec srovnat.