# Oracle Application Server Portal Developer Kit (PDK)
PDK-Java V2 Release Notes

Last Updated: | December 7, 2004
Status: | Production
Version: | PDK Release 9.0.4.1.0

### Contents

> System Requirements
> Release 9.0.4.1.0
> Release 9.0.4.0.2
> Release 9.0.4.0.0
> Release 9.0.2.6.2
> Release 9.0.2.6.0
> Release 9.0.2.4.0
> Release 9.0.2.0.2
> Release 9.0.2.0.1
> Release 9.0.2.0.0
> Installation
> Known Issues

## System Requirements

The following are the recommended and minimum requirements to use and install this release of PDK-Java

Note: Starting with PDK 9.0.4.1.0, the PDK download is intended to be installed and deployed in a standalone OC4J instance only. If you plan to use PDK in an Oracle Application Server instance, you must get and install the corresponding Oracle Application Server releases or patchsets.

Application Server | Standalone OracleAS Containers for J2EE (OC4J) 10g (9.0.4) only
OracleAS Portal Version | 3.0.9.8.2 (and later). Some functionality may require a later release of OracleAS Portal
Browsers | Netscape 4.0.8 and above, Microsoft Internet Explorer 4.0.1 with Service Pack 1 and above

Note: You may encounter JavaScript errors when using a browser older than what is listed above

## Release 9.0.4.1.0

### New Features

#### Edit Defaults Mode configures Sample Portlets across all Locales

To simplify the configuration and upgrade requirements for all our sample portlets, we now use a localePersonalizationLevel of none in all the XML Provider Definition (provider.xml) files we ship in jpdk.ear. This means that the changes you make in Edit Defaults mode will apply to all users, no matter what their or your Portal session language is. If you want to use the samples with existing locale-specific data from previous releases and continue using the old Edit Defaults behaviour, simply modify the localePersonalizationLevel tag to a value of language or locale appropriately (see 9.0.4.0.2 Notes for a description of these settings). If you are upgrading from a release prior to 9.0.4.0.2, you should also use the upgrade utility described below to ensure existing locale-specific data uses an appropriate naming format for your chosen localePersonalizationLevel.

#### Preference Store Migration / Upgrade Utility

A new command line utility has been included in pdkjava.jar that allows users upgrading from previous releases of PDK-Java and OracleAS Portal to manage portlet preference data generated by existing portlets. The tool allows upgrading users to ensure that their existing locale specific portlet preference data uses a naming format compatible with the latest PDK and Portal releases, and also allows users to migrate existing data between different preference stores (e.g. from FilePreferenceStore to DBPreferenceStore).

##### Modes

The utility supports 6 basic modes, specified by the -mode option. Two of these are "upgrade" modes where data is upgraded in place. These are

- file: data in a FilePreferenceStore is to be upgraded
- db: data in a DBPreferenceStore is to be upgraded

The upgrade modes can be used to modify existing locale specific preferences in the preference store so that they use a naming format compatible with the current Portal and a given localePersonalizationLevel setting (added in Release 9.0.4.0.2). They would typically be used in the following scenarios:

- You have upgraded from PDK 9.0.4.0.0 or earlier and you want to run existing portlets with the new default localePersonalizationLevel setting of language (in prior releases, the default was effectively locale).
- You have upgraded your Portal from version 9.0.2.0.0 or earlier and you want to run existing portlets with a localePersonalizationLevel setting of locale (OracleAS Portal now uses different names for some locales since this release, so some existing data must be remapped).
- You want to change the localePersonalizationLevel for an existing portlet from locale to language or vice-versa.

If you specify one of the upgrade modes, you must use the -remap option to specify which localePersonalizationLevel (language or locale) that you are upgrading to. You may also use the -countries option to specify a prioritized list of ISO country codes, indicating your order of preference should any 'collisions' between remapped preferences for different countries occur. For example, if you specify "-remap language -countries GB,US", it means that should the utility come across both US English and British English preferences (en_US and en_GB) in a given preference store, it will remap the British English preference to become the English-wide preference (en) and leave the US English preference alone.

The other four basic modes are "migration" modes in which data is copied from a source preference store to a target preference store. These are

- filetodb: data is to be coped from a FilePreferenceStore to a DBPreferenceStore
- filetofile: data is to be copied from a FilePreferenceStore to a FilePreferenceStore in a different location
- dbtofile: data is to be coped from a DBPreferenceStore to a FilePreferenceStore
- dbtodb: data is to be copied from a DBPreferenceStore to a DBPreferenceStore based on a different database table

If specifying one of these migration modes, you may also (but need not) use the -remap and -countries options described above to specify that the data should be upgraded in the course of being migrated, i.e. locale-specific preferences should be remapped appropriately.

The other options accepted by the utility are used to specify the properties of the preference store(s) involved in the upgrade or migration operation. These should correspond to the tags you would use in provider.xml to describe the preference store(s).

Properties beginning with the prefix "-pref1" correspond to properties of the source preference store (in an upgrade mode, this is of course the only preference store). So, for example, specifying "-pref1UseHashing true -pref1UseHashing true -pref1RootDirectory j2ee/home/applications/jpdk/jpdk/WEB-INF/providers/sample" would set the useHashing and rootDirectory properties of a source FilePreferenceStore. Similarly, when one of the migration basic modes has been selected, properties beginning with the prefix "-pref2" correspond to properties of the target preference store. So, for example, specifying "-pref2User portlet_prefs -pref2Password portlet_prefs -pref2URL jdbc:oracle:thin:@myserver.mydomain.com:1521:mysid" would set the database connection details on a target DBPreferenceStore. Consult the XML tag reference for more information about the properties you can set on a PreferenceStore.

##### Usage

For a complete description of the command line syntax for the migration tool, just invoke the command "java -classpath $ORACLE_HOME/portal/jlib/pdkjava.jar oracle.portal.provider.v2.preference.MigrationTool" once you have installed PDK Java in an OracleAS or OC4J Oracle home. Below are some example usages:

- java -classpath $ORACLE_HOME/portal/jlib/pdkjava.jar oracle.portal.provider.v2.preference.MigrationTool -mode file -remap language -countries GB,US -pref1UseHashing true -pref1RootDirectory j2ee/home/applications/jpdk/jpdk/WEB-INF/providers/sample
- java -classpath $ORACLE_HOME/portal/jlib/pdkjava.jar oracle.portal.provider.v2.preference.MigrationTool -mode filetodb -remap locale -countries AR,MX -pref1UseHashing true -pref1RootDirectory j2ee/home/applications/jpdk/jpdk/WEB-INF/providers/sample -pref2User portlet_prefs -pref2Password portlet_prefs -pref2URL jdbc:oracle:thin:@myserver.mydomain.com:1521:mysid

### Bug Fixes

- 3481626: When the PDK image struts tag was used in a JSP before the link tag, this would result in an incorrect image URL being generated.
- 2949204: A null value is only passed as the ExternalPrincipal argument to ProviderInstance.initSession() when no external application is associated with the provider registration.
- 3507207: Portlets using the DBPersonalizationManager for storage could throw "ORA-01000: maximum open cursors exceeded" errors under certain circumstances. Note that DBPersonalizationManager is provided purely for backward compatibility with JPDK v1 and the recommended approach to configuring database storage for portlet customizations is to use PrefStorePersonalizationManager with DBPreferenceStore.
- 3507150: The file ojmisc.jar was required in the libcommon/jlib directory in order for the Web Cache password obfuscation utility to be run from a standalone OC4J installation.

## Release 9.0.4.0.2

### New Features

#### Locale Personalization Level

The PDK-Java now provides more control over how much information from the portal session language is used when writing/reading default portlet customization data. Prior to release 9.0.4.0.2, all such available information was used when writing/reading default values (for anything other than the portlet's default locale). For example, if a portlet's defaults were edited by a user in locale "en-US" and by a user in "en-GB", those default customizations would always be stored separately. Using a new setting, the locale personalization level, the PDK-Java can now be instructed to write/read this type of customization with only the language code, with both the language and country code, or not at all.

The locale personalization level may be set using either PortletDefinition.setLocalePersonalizationLevel(int) or ProviderDefinition.setLocalePersonalizationLevel(int) using constants defined in PortletConstants. If the XML Provider Definition technology (provider.xml) is being leveraged, a new tag, <localePersonalizationLevel>, may be included at portlet or provider definition level with portlet level settings taking precedence over the provider level. For example,

> <portlet class="oracle.portal.provider.v2.DefaultPortletDefinition">
> ...
> <name>StockQuotePortlet</name>
> <title>StockQuotePortlet</title>
> <localePersonalizationLevel>language</localePersonalizationLevel>
> ...
> </portlet>

Possible values for <localePersonalizationLevel> are:

- none: in this case, there will be no localized default data. All edit default operations affect the same data set, irrespective of the user's locale.
- language: in this case, localized default data will be stored and queried using the language code from the user's locale. For example, provided there are no user level customizations, users in locales "en-US" and "en-GB" will see the same localized defaults.
- locale: in this case, localized default data will be stored and queried using the language and country codes from the users locale. This is equivalent to functionality prior to release 9.0.4.0.2

If omitted from the provider/portlet definition, the locale personalization level defaults to language. Thus, to recover localized defaults written with a release prior to 9.0.4.0.2, it is necessary to explicitly set this to locale. Note: this setting in no way affects user level customizations, only what defaults a user will see before customizing the portlet for themselves.

#### Extensible Provider Test Page

The PDK-Java SOAP servlet now supports an extra deployment property called testPageURI that allows you to specify a path to a resource to be used to render the markup that is returned in response to an HTTP GET request to the provider's base URL (http://<host>:<port>/jpdk/providers/<service name>), commonly known as the "test page". This allows you to configure your own servlet or JSP to act as the test page for your providers. Like all other deployment properties, this setting can be controlled by adding an appropriate line to the <service name>.properties file in the WEB-INF/deployment directory of your web application. For example, in sample.properties we have the line:
testPageURI=/htdocs/testpage/TestPage.jsp

A sample test page JSP is now included in jpdk.ear that uses UIX technology to render the provider test pages with a standard Oracle "look and feel".

#### Integration with Apache Struts

PDK-Java now provides integration with the Apache Struts framework through a new renderer class called StrutsRenderer. For more information, refer to the article Using the Struts Sample.

### Bug Fixes

- 3029417: The web services relied on by the "Weather" and "Messaging" sample web service portlets have moved to new locations.
- 3040109: The value of the HttpCommonConstants.ORIGINAL_PROVIDER_PATH request attribute was invalid for web provider URLs that did not include a service name.
- 3044019: Web Cache Invalidation API needed extra method to control service name
- 3173547: Corrections to setPortletReference() in Web Cache invalidation API so it works for system default (non locale-scoped) customizations.
- 3067934: Web.xml in template.ear contained invalid values for sharedkey and definition environment entries
- 3099271: Poor error reporting when OIDManager configured incorrectly
- 3132442: Private form submission sample did not work for users who were not logged in; edit page is password protected so use show details page instead.
- 3135874: ServletProviderUser.getCookies() always returned null
- 3138140: NameValuePair class was deprecated but still being used throughout JPDK API; now replaced by NameValue
- 3160751: Exception raised if debug level is not present even though this is optional
- 3166940: Event form sample localizations not working correctly
- 3169587: Partner app sample relied on desupported "Same Cookie Domain" feature
- 3218605: Compatibility problems between JPDK and OID 9.0.4

## Release 9.0.4.0.0

### New Features

Release 9.0.4.0.0 does not add any functionality over and above that included in the 9.0.2.6 releases. However, it does include changes necessary to be compatible with the OracleAS 10g technology stack.

### Bug Fixes

- Bug 3137989 Resource bundle for ESI sample portlet contained an invalid key
- Bug 2952279 It is now possible to create an subclass of NameValuePersonalizationObject that does not store the portlet title (subclass NVPO & override the init() method to do nothing)
- Bug 2949204 ExternalPrincipal passed to ProviderInstance.initSession() is now set to null if the provider is not associated with an external application
- Bug 2848990 The Contact portlet demonstrating OID integration now gives more detailed information if OID is not configured correctly
- Bug 2847035 JNDI Environment variable to set the root directory of a file based preference store now works correctly.
- Bug 2823096 Header links are now correctly aligned in preview mode when using MOCContainerRenderer
- Bug 2823074 The sample Event portlet now displays a dummy form in preview mode. Previously it displayed a "live" form that caused errors
- Bug 2791374 The Provider Test Page now displays all portlets in a provider. Previously, the test page only displayed the first 99 portlets
- Bug 2767496 Sample portlets now render correctly when portlet borders are turned off. Previously, some portlets would not display correctly
- Bug 2761271 The sample providers included in jpdk.ear now support load-balancing. Previously, the web application containing the sample providers did not include the <distributable> tag indicating that the J2EE server can load balance it.
- Bug 2725833 The Provider Test Page now works correctly if the test page URL includes a trailing slash. Previously, this would cause an error
- Bug 2620268 The Form submission portlet now displays a dummy form in preview mode. Previously it displayed a "live" form that caused errors if the submit button was pressed.
- Bug 2484150 Authentication exceptions thrown by external application providers during ProviderInstance.initSession() are now logged as warnings. Previously they were logged as severe errors. Authentication exceptions are expected in this situation as they are used to signal to the portal that a user needs to update their external application login information in the Single Sign-On Server.
- Bug 2316766 XMLUTIL.EscapeXML() now works correctly. Previously there were problems if the first character of the string to be escaped needed escaping.

## Release 9.0.2.6.2

Release 9.0.2.6.2 is primarily a maintenance release supporting the accompanying Portal Tools release.

### Bug Fixes

- Bug 3011905 - Thread interrupt can cause JSP compilation errors.

  PDK-Java no longer interrupts threads which have been processing a single request for a long time. This behaviour could cause a JSP compilation thread to halt prematurely, resulting in invalid class files. Instead, verbose log messages are written to serve as warnings to the administrator.

## Release 9.0.2.6.0

### New Features

#### OracleAS Internet Directory (OID) Integration

PDK-Java now integrates with OID allowing you to obtain user profile and group information from your OID server. This built-in integration allows you to obtain user profile information via the ProviderUser class and includes methods to determine if the current user belongs to a specific group. In addition to ProviderUser, the PDK-Java also provides a Security Manager that lets you secure your portlets based on portal groups.

If you need access to other information stored in your OID server, you can obtain a connection to the OID server which you can then use to query custom data.

This feature requires OracleAS Portal release 9.0.2.6 or later

#### Configure Providers using JNDI

Earlier releases of PDK-Java included deployment-specific configuration information in several locations including the provider definition file, the web application's web.xml file and the provider's deployment properties file. The problem with these approachs is that all these files are included in a provider WAR file. This means that in order to configure a provider for a specific deployment, you had to know how OC4J deploys applications and then update the configuration settings after you have deployed the provider.

In production environments, this is likely to require the intervention of multiple people to get access to the correct files and then there is always the risk of corrupting one of the files.

In this release of the PDK-Java, all the settings that you might want to modify are exposed as JNDI environment variables. This means that they can all be set via OracleAS Enterprise Manager (OEM) or, if your OC4J instance is not managed by OEM, by updating the orion-web.xml file.

#### Provider Validation

PDK-Java now includes a comprehensive set of provider validation rules that are checked whenever a provider definition is loaded. The validation system does not stop when it finds the first error, unlike older releases, but validates as much of the provider as it can, reporting the errors via the Provider Test Page and log files. The goal of the provider validation system is to catch any and all errors that might cause your provider to fail either during registration or at runtime.

#### Automatic Invalidation After Customization

PDK-Java now automatically invalidates portlet content cached in Web Cache whenever you customize a portlet. This feature is enabled by specifying the <autoInvalidate> tag in your provider definition file. A typical entry for a portlet that uses invalidation caching with auto-invalidate enabled might look like this:

> <renderer class="oracle.portal.provider.v2.render.RenderManager">
> ...
> <useInvalidationCaching>true</useInvalidationCaching>
> <pageExpires>5</pageExpires>
> <autoInvalidate>true</autoInvalidate>
> ...
> </renderer>

This feature requires OracleAS Portal release 9.0.2 or later

#### ResourceRenderer Can Now Read HTML Files in Any Character Encoding

In earlier releases of PDK-Java, ResourceRenderer could only read static files encoded in ISO-8859-1. You can now specify the encoding ResourceRenderer should use when reading static files using a similar mechanism to that used by FileRenderer. For example, to render a static HTML file that is encoded in UTF-8, you would use the following:

> <renderer class="oracle.portal.provider.v2.render.RenderManager">
> ...
> <showPage class="oracle.portal.provider.v2.render.http.ResourceRenderer">
> <resourcePath>/path/to/file/utf8.html</resourcePath>
> <charSet>utf-8</charSet>
> <contentType>text/html</contentType>
> </showPage>
> ...
> </renderer>

#### Whitespace is Now Trimmed From Values Specified in a Provider Definition File

Earlier releases of PDK-Java took values entered in a provider definition file literally - including any whitespace that might be between the value itself and the opening/closing XML tags. Even though this is standard XML parsing behavior, some people found it inconventient. Consequently, the default behavior is now to trim all whitespace from the value returned by the XML parser.

If you want to retain the whitespace surrounding a specific value, you can do so by including the attribute "trim=false". For example:

<description trim=false> I want extra white space </description>
<description> I don't want any white space </description>

### Bug Fixes

- Bug 2757320 - All resource bundles now have explicit translations for English (resource bundles ending in _en)
- Bug 2774974 - Provider test page can only display ISO-8859-1 characters
- Bug 2322909 - Web providers are now restricted to using one and only one type of caching in a specific request
- Bug 2599226 - NodeHandler now allows empty elements in provider definition files
- Bug 2618443 - Cell padding for web provider portlet containers now matches that of database portlets

## Release 9.0.2.4.0

### New Features

#### Caching Level Specified for Each Portlet

PDK-Java now lets you specify a portlet's cache level on a per-portlet basis. Previously the cache level used to cache portlet content was determined by the registration settings of the Web Provider.

The supported caching levels are:

- System - Portlet content is generated once and then shared by all Portal users until the cached content expires or is otherwise invalidated. Portlets using System level caching should not expose the Edit or Customize function to users.
- User - Portlet content is generated and cached independently for each portal user. Each user may have their own customization settings or may see different data sets. With User level caching, the portlet content for a specific user may remain cached over the life of many Portal sessions.
- Session - Portlet content is generated and cached independently for each portal user. However, the content is only cached for the life of a user's Portal session. When a user logs out and logs back into the Portal, the portlet content will always be regenerated.

You can define the cache level for a portlet via the provider definition file by specifying a cache level tag at either the portlet level, the provider level or both. If cache level is specified at both the portlet and provider level, the portlet level takes precedence. If no cache level is specified at any level, the default will be User. For details on the provider definition file entries, please refer to the Provider Definition File Tag Reference.

This feature requires OracleAS Portal 9.0.2.5 or later

#### Support for JSP/Servlet Forwarding

In previous v2 releases, portlets using JSPs or Servlets were always invoked using the RequestDispatcher.include() method. This meant that included JSPs or Servlets could only invoke other JSPs or Servlets using the include() method. However, some MVC frameworks use the RequestDispatcher.forward() method to forward a request from a controller to the JSP or Servlet that will handle the actual request. Consequently, these frameworks could not be used in conjunction with the PDK-Java.

PDK-Java now invokes all JSPs and Servlets using the RequestDispatcher.forward() method. This allows you to use MVC frameworks to implement your portlets. Any portlets that use include() method will continue to work as before.

#### ESI Portlets

You can now build portlets that utilize Edge Side Includes (ESI) to construct a portlet from multiple parts. The portlet itself generates the ESI "framework" of the portlet and the "pieces" are requested separately and merged into the portlet by OracleAS Web Cache. This allows you to build portlets that consist of a combination of dynamic and static content. The different pieces can be cached independently by Web Cache allowing you to optimize cache usage and minimize the amount of content that must be generated by the web provider for each request.

The new ESI Portlet included in the Invalidation Web Provider demonstrates this feature.

This feature requires OracleAS Web Cache release 9.0.2 or later

#### Enhanced Partner Application Support

In previous releases, creating a partner application required you to use the SSO SDK to create application SSO session cookies. However, you can now use mod_osso to protect your partner application and mod_osso will automatically challenge unauthenticated users for you. Now you can focus your attention on the integration between the Web Provider and the application rather than the process of making your application an SSO Partner Application.

The new Partner Application Sample demonstrates this feature.

#### Enhanced LogManager

The LogManager utility, which is used for logging within the PDK-Java, has been enhanced to allow Web Providers installed in different web applications to write log messages to different application log files regardless of which class loader is used to load it. Previously, if ptlshare.jar was included in the system classpath, all log messages would go to 1 log file. Log messages for a specific web application will now always go to the application.log associated with that web application. You can also configure different log levels for each web application.

### Bug Fixes

- 2087134 - Edit Defaults and Edit forms containing a single field can now be summitted using "Enter" key
- 2091497, 2134333, 2138160, 2138172 - various fixes for bi-directional language support
- 2215440, 2215449 - Feedback and Guest Book portlet samples now work correctly. Submitted data is no longer added to the page URL
- 2239243 - URL Services documentation updated to indicate that relative URLs containing "../" will not work
- 2266177, 2273323 - various fixes for XMLFilters in URL Services
- 2324550 - PDK-Java deployment descriptors in sample web.xml file are now DTD compliant
- 2333350 - Portlet headers rendered by PDK-Java are now identical to those rendered by database portlets
- 2387738 - Invalidation APIs have been extended to add missing APIs
- 2413477 - URL Services sample portlets now show images correctly. Previously some images where not displayed correctly
- 2486812 - Private Form Submission Portlet now works correctly again
- 2497501 - Additional application fields associated with external applications are now correctly sent to the web provider again
- 2550518 - Portlet borders are now drawn correctly, respecting the region level flag in the portal page.
- 2559283 - Reading of web-inf/deployment/xxx.properties files now copes with trailing spaces
- 2586705 - The HelloWorld sample portlet now includes fully translatable text. Previously, all the text was customizable which gives the impression that the portlet does not support internationalization.
- 2608266 - getQualifiedParameter() now works in all render modes.

## Release 9.0.2.0.2

### New Features

#### Performance Logging/Monitoring

You can now record performance statistics in the provider log file or view them in your web browser beneath each portlet.

##### Viewing Performance Statistics in the Provider Log File

To enable this feature, set the logging level in your web.xml file to "performance" level (a value of 5 or higher). Each performance log entry consists of a label, [perf-provider], followed by a list of name-value pairs separated by spaces. The log entries always follow the same format regardless of the operation that was timed - all operations are timed, not just "show" calls. The consistent format simplifies parsing of the entries for performance analysis. If an attribute is not relevant or a value was not captured for a request, a value of '(null)' is recorded. The attributes recorded for each request are listed below.

- id - the request id generated by the PPE. This allows you to track requests across tiers
- providerId - the id of the provider
- portletId - the id of the portlet
- portletName - the name of the portlet, as specified in provider.xml
- portletInstance - the portlet instance name
- user - the name of the portal user making the request
- operation - the type of request (e.g. showPortlet, initSession)
- requestTime - the overall time to process a request in milliseconds
- processingTime - time in milliseconds spent in your provider code
- frameworkTime - time in milliseconds spent in the PDK-Java framework code before and after invoking the provider's code (ie preparation, and cleanup)
- headerRenderTime - time in milliseconds taken to render a portlet header, present in show requests only
- footerRenderTime - time in milliseconds taken to render a portlet footer, present in show requests only
- readCustTime - time in milliseconds taken to retrieve customization object values, present in show requests only
- writeCustTime - time in milliseconds taken to update customization objects, present in show requests only
- cache - the cache usage status associated with a show request, if any. values are:
  - "MISS,EXPIRES" - the portlet is using expires-based caching. The Portal cache either did not contain a matching entry or the matching entry had expired. The portlet had to generate new content.
  - "MISS,NEW" - the portlet is using validation-based caching. The Portal cache did not contain a matching cache entry so new content had to be generated
  - "MISS,STALE" - the portlet is using validation-based caching. The Portal cache contained a matching cache entry, but the portlet determined that the entry was "stale" (ie no longer valid) so new content had to be generated.
  - "HIT,PING" - the portlet is using validation-based caching. The Portal cache contained and matching entry and the portlet determined that the entry was valid. A message was sent to the Portal telling it to use the cache entry. The portlet did not have to generate new content.
- cacheLevel - the level of caching used by the portlet associated with a show request. Non-null values are
  - "USER" - portlet content is cached on a per-user basis
  - "SYSTEM" - 1 copy of the portlet content is cached and shared by all users
- expiryTime - the length of time in minutes a portlet will be cached by the Portal. This is used only by portlets that utilize expiry based caching.
- cacheRequestKey - the value of the cache key received from the Portal. This is used in show requests for portlets using validation based caching. If the cacheRequestKey and cacheResponseKey are the same, the cache status should be "HIT,PING" indicating a successful ping check. If they are different, the cache status should be "MISS,STALE" indicating that the cache entry is stale and new content was generated
- cacheResponseKey - the value of the cache key that was returned to the Portal. This entry represents the new cache key returned to the portal when new content is generated by the portlet. This should be accompanied by a cache status of "MISS,STALE"
- status - the completion status of the request. Values are
  - "COMPLETE" - the request completed successfully
  - "INCOMPLETE" - the request did not complete for some reason. This status is used whenever a request fails to complete and usable performance statistics could not be gathered. Requests will not complete successfully if an unhandled exception is thrown or the request is terminated by the Request Monitor (see Request Monitor below).

##### Viewing Performance Statistics in a Portal Page

Performance statistics can also be viewed in the portal page itself by appending "&_debug=1" to the page URL displayed in your web browser's address window. A summary of the performance statistics and caching information are displayed below each web provider portlet.

Note: If your portlet is using caching, this information will be cached along with the portlet so the same information will be displayed whenever that cache entry is used. This means the statistics represent the time taken to generate the original content. The time taken to retrieve the cached copy is displayed below the portlet generated information. Even though the information is cached, other users will not see the cached copy unless they have also appended "&_debug=1" to their page URL so you need not worry about the use of this functionality impacting other users of your portal.

#### Request Monitoring

This is a new feature that monitors the execution of portlet requests and either logs a warning message if a portlet does not complete execution within a specified "warning timeout" or attempts to interrupt a hanging request if that request exceeds a specified "kill timeout". Portlets can also monitor their own execution with regards to the "warning timeout", voluntarily terminating themselves if the timeout has expired.

##### Why is Request Monitoring Necessary?

Real world experience has shown that it is possible for a single poorly performing portlet to literally bring an entire portal to its knees. When the Parallel Page Engine (PPE) makes requests to web providers, it has a request timeout mechanism. If a portlet request does not complete within that timeout, the PPE stops waiting for the portlet and returns the page to the user without it. However, the web provider cannot be notified of this condition and continues executing the request. The PPE continues to make new requests for the slow portlet, each time having to wait for the full timeout period to expire before returning the incomplete page. At the same time, requests for the slow portlet consume more & more resources on the provider's application server and begin slowing the execution of other portlets. Over time, more page requests are impacted as requests become backed up on the provider machine - the more requests are backed up, the more PPE resources are tied up waiting for requests to complete and page requests start getting backed up. Eventually new page requests are refused by the PPE effectively making the portal inaccessible.

This feature, along with other features in the PPE, aims to protect your portal from poorly performing portlets that can cause this type of denial of service. The "warning timeout" lets you identify portlets that consistently fail to meet performance targets and the "kill timeout" attempts to interrupt any requests that appear to be hanging.

It is a good idea to set aggressive performance goals for your portlets using the "warning timeout". This will allow you to identify portlets that do not meet your performance goals and need to be tuned. Requests that do not meet the target are not impacted - the framework simply writes a message to the log files. This means you can set and monitor aggressive goals without needing to worry those goals impacting your portal. Over time, you can address the consistent "offenders" and improve the overall performance of your portal.

##### Setting the Timeouts

Both the timeouts are specified in seconds in the provider's .properties file using the following properties:

- executionWarningTimeout (default value is 20 seconds)
- executionKillTimeout (default value is 80 seconds)

The "kill timeout" should be larger than the "stall" time in the PPE to ensure that the PPE is no-longer waiting for the request to complete when the framework attempts to interrupt the request.

##### Voluntary Termination

The framework also provides an API that portlets can use to monitor their own execution with regards to the warning timeout. If the API indicates whether the allowed execution time has elapsed and can be called after performing potentially time-consuming operations (such as reading/writing files or accessing a database). If the timeout has expired, the portlet can halt further processing, release any resources it is holding and exit as quickly as possible. If your portlets utilize this feature, you should set the warning timeout to be slightly larger than the PPE's stall time to ensure that your portlets only terminate themselves after the PPE has stopped waiting for the request to complete. The new API is

> PortletInstance.hasTimeoutElapsed()

#### Diagnostic Logging Context

All Web Provider log file entries are now prefixed with context information. This makes the log entries longer, but it also makes the log files much more useful since you can easily identify all the log messages for a particular portlet request - even when they are interleaved with many other portlet requests. The context information added to each message consists of:

- originating page request id
- portlet instance id

The combined context information, which is enclosed in square brackets, can be used to quickly locate all the log entries for a particular portlet request. This is done by locating all the log entries that share the same context information. Previously, this was very difficult to do - especially in a high-volume environment. The originating page request id can also be used to:

- locate all the log entries that correspond to the generation of a single portal page
- associate log entries in the provider's log file with the corresponding log entries in the PPE's log file, enabling you to trace the generation of a portal page through the PPE and the provider.

#### XML Tag Reference added for v2 API

A new XML Tag Reference document has been added to the PDK. The provider definition file does not have a DTD or XML schema definition because it is designed to be extensible based on the implementation classes it references. Different implementations of the interfaces or abstract classes will often require different configuration information.

The Tag Reference describes the predefined tags for all the known implementation classes that are included with the PDK-Java. The document is structured similar to Java Doc, describing the purpose and form of each tag along with a list of known implementation classes for that tag (if appropriate). Clicking on a known implementation will take you to the tags that are specific to that implementation class. Using this document you can quickly discover all the configuration parameters that are available for each implementation class.

#### Web Services rendering components promoted to "Production" status

Two classes for accessing and rendering Web Services were added to the PDK-Java in the 9.0.2.0.1.release. These classes have now been promoted to "production" status and will be supported as production level components of the API.

#### URL Services component "Production" status

URL Services was upgraded to work with the v2 API and released as a "Beta" component in the 9.0.2.0.0 release, This component has now been thoroughly tested and promoted to "production" status.

### Bug Fixes

- 2437326 - HelloWorld portlet now displays the names of locales in the correct language instead of always being in English
- 2426682, 2145942 - LogManager now correctly logs to the correct servlet context log regardless of the number of servlet contexts that are using the LogManager singleton. Previously, the LogManager could only be initialized once and all subsequent log messages would go to a single servlet context log.
- 2418878 - HelloWorld portlet now includes a ResourceBundle with translations explicitly in English. Previously, English was assumed to be the default language which is not always the case.
- 2400071 - ported URL Services v1 bug fixes to v2
- 2371665 - Modified build to add copyright notices to the Java Doc
- 2371110 - removed JSP Services portlet from the samples. This portlet duplicated functionality demonstrated by other portlets and did not add anything new
- 2361751 - Modified transactional management of DBPreferenceStore in preparation for certification against WebSphere.
- 2346205 - Implemented Preview mode for the HelloWorld portlet. Previously, the portlet indicated this mode was implemented when it was not. This resulted in an error when attempting to preview the portlet.
- 2341300 - Corrected issue with the DBPreferenceStore.list() that could result in an ExhaustedResultSetException
- 2312566 - Corrected exception handling in URLRenderer that caused an AccessControlException when the specified URL could not be contacted
- 2305576 - ProviderAdapter now uses the context classloader for loading ProviderLoader implementations. Previously, it did not specify a classloader and would fail to load the ProviderLoader if pdkjava.jar was on the system classpath, but the ProviderLoader was included in a WAR file.
- 2187684 - Oracle SSO Server requires you to register a logout link when you register a Partner application so that Partner applications can be correctly notified of a logout event. Modified the Partner Application sample to accommodate this requirement.
- 2173713 - Sample JSPs now explicitly set content type and character set in order to support customization in multibyte languages.
- 2169764 - Removed unnecessary calls to PortletInstance.hasAccess(). Access is checked once during the creation of the PortletInstance. Any operations involving the PortletInstance are therefore secured.
- 2134333, 2138160, 2138172 - Various changes to support bi-directional display for Arabic and Hebrew languages

## Release 9.0.2.0.1

### New Features

#### Web Services Integration

Two new renderer classes, RPCWebServiceRenderer and DocWebServiceRenderer, have been provided to allow easy integration of web services into your portlets. For more information, refer to the article Installing the Web Services Sample Portlets.

The Web Services Renderers are introduced as beta level features.

Note: If you want to generate your own Java stubs to use with RPCWebServiceRenderer, you will also require Oracle JDeveloper Release 9.0.2 or later

## Release 9.0.2.0.0

This release of the PDK-Java includes 2 versions of the web provider framework, version 1 and version 2. Version 1 of the framework is basically the same as PDK-Java 3.0.9, with some additional features for supporting delivering content to mobile devices. Version 2 of the API is evolution the includes migration to the OC4J platform and some API changes designed to promote stability and extensibility of the API.

There have been a number of changes since the last major release of the PDK-Java. The changes fall into 3 categories:

- migration from JServ to OC4J
- other new features
- infrastructure to enhance framework stability
- infrastructure to support planned functionality

### Migration from JServ to OC4J

One of the biggest changes in the PDK-Java is the migration from the JServ servlet engine to Oracle Containers for Java (OC4J). OC4J is a J2EE compliant application server that supports J2EE components, Servlets and JSPs. For the PDK-Java, the biggest impact of this migration is the switch from the Servlet 2.0 to the Servlet 2.2/2.3 API. This API change impacts the way a provider is deployed, which is discussed in more detail later in this document, and the way in which JSPs and Servlets are invoked by the framework.

PDK-Java now uses the RequestDispatcher service provided by the Servlet 2.3 API to invoke JSPs and Servlets instead of the custom approach used in earlier releases. This means that the functionality of several renderers has been merged into a single renderer - ResourceRenderer.

### Infrastructure to Enhance Framework Stability

PDK-Java v9.0.2 includes several changes that are designed to increase the overall stability of the framework and make it easier to introduce new features with minimal impact on existing code. These changes include:

- switch from Java interfaces to abstract classes for defining APIs
- re-organize the package structure to make code easier to locate and understand
- make framework more object-oriented so the flow of control is easier to understand

#### Abstract Classes Replace Interfaces

During the development of earlier releases of the PDK-Java, it became evident that the use of Java interfaces to define top level APIs made adding new features difficult. This was because new features often required API changes and those API changes had to be reflected in changes to the Java interfaces. For developers using the default implementations, these changes were not invasive. However, for developers writing more complex providers, any interface change potentially caused their code to break because their implementations no-longer matched the interface definitions.

To resolve this issue most of the Java interfaces have been replaced with abstract classes. The switch to abstract classes allows new features to be added without breaking any existing code. While this change does reduce flexibility a little (due to the lack of support for multiple inheritance in Java) and requires code changes to adopt the new release of PDK-Java, we feel that the the long term gains in stability are worth the cost.

#### Package Reorganization

In addition to replacing Java interfaces with abstract classes, the package structure of the JPDK has been modified to include a new version number and to organize the classes based on functionality.

All packages now include "v2" in the package name to indicate that the package belongs to version 2 of the the PDK-Java. The inclusion of a version number in the package name allows different versions of the PDK-Java to be included in the same classpath without worrying about collisions.

In addition to the version number change, the classes have been re-organized into a more logical structure. The new structure groups classes based on functionality. This makes it easier to find existing classes and organize new classes as new functionality is added.

#### Object-Oriented Framework

To make the code more understandable for developers and create a clean separation between the provider APIs that developers implement and the underlying code that communicates with OracleAS Portal, the provider and portlet interfaces have been modified.

Previously, the provider and portlet APIs were not very object-oriented and API calls from the communication layer of the framework sometimes bypassed these objects and accessed the "controller" objects directly.

In the new API, several changes have been made:

- the Provider interface has been split into 2 abstract classes - ProviderInstance and ProviderDefinition. The old Provider interface represented 2 things:
  - a registered instance of a provider (a registered instance representing a registered provider on a specific portal instance) and the metadata that defines the provider (currently it's portlets)
  - the provider's metadata that describes the provider.

> Splitting the information in this way makes the usage of the classes clearer for developers and allows a single set of metadata to be shared by many registered instances. It creates a platform for supporting provider instance specific behavior (for example provider configuration settings that are specific to a registered instance of that provider)

- the Portlet interface has been split into 2 abstract classes - PortletInstance and PortletDefinition

  The old Portlet interface really represented only the portlet metadata. All API calls that affected a portlet were actually routed directly to the appropriate controller. This architecture did not create a clean interface with the communication layer of the framework and made it difficult for developers working with more complex portlets to understand the flow of control within the framework.

  To rectify this problem, the PortletInstance and PortletDefinition were created. The PortletDefinition represents the sharable definition of the portlet and the PortletInstance represents a specific instance of that portlet being accessed by, or on behalf of, a specific user. The result of this split is that all APIs that affect an instance of a portlet (rendering, copying, security etc) have been brought together in the the PortletInstance class.

  This change in architecture also allows developers more freedom because they are not forced to use the rendering, personalization and security frameworks provided by the PDK-Java. The base class, PortletInstance, exposes all the methods you need and provides some level implementation. A complete implementation that exposes all the familiar rendering, security and personalization frameworks of the PDK-Java is provided in DefaultPortletInstance.

- all calls from the communication layer are now made via the ProviderInstance and (if necessary) the PortletInstance

  Now we have cleanly defined classes that represent instances of a provider and portlet, all the API calls from the communication layer of the PDK-Java can be neatly funneled through the ProviderInstance and PortletInstance interfaces giving developers making the framework easier to understand for new developers.

### Infrastructure to Support Planned Functionality

Under the covers, the communications layer of the PDK-Java has also undergone some renovation. The changes that have been made in the communication layer are primarily in preparation for the migration of the provider framework to a web service using Oracle SOAP.

As a result of this preparatory work, you can now support multiple provider definitions running on the same servlet (in the same way that a single SOAP engine can support multiple web services). This deployment option is demonstrated in the PDK-Java samples which are all deployed on a single servlet.

### ResourceRenderer

ResourceRenderer is a new implementation of the ManagedRenderer interface that replaces the JspRenderer, Servlet20Renderer and, in most situations, FileRenderer. It lets you render any resource (JSP, Servlet, static HTML or static XML file) that is hosted on the provider's listener in a simple and consistent manner by specifying the relative URI to that resource.

ResourceRenderer is a managed renderer that works with the familiar RenderManager framework introduced in earlier releases of the JPDK.

### Preference Store API

The persistence mechanism used by the PDK-Java for portlet customizations has now been 'generalized' to allow persistence, retrieval and management of data scoped at almost any level. This new generic persistence mechanism is represented by the PreferenceStore class. It currently has two implementations: FilePreferenceStore a lightweight implementation that persists data on a file system, and DBPreferenceStore, an implementation that persists data in a relational database. Consequently, we now have a single 'general purpose' PortletPersonalizationManager implementation that uses a PreferenceStore to persist portlet customizations, PrefStorePersonalizationManager. For more information about using the PDK-Java Preference Store API, refer to the article How to use the Preference Store API.

### Web Services Integration

Two new renderer classes, RPCWebServiceRenderer and DocWebServiceRenderer, have been provided to allow easy integration of web services into your portlets. For more information, refer to the article Installing the Web Services Sample Portlets.

### Revised Parameter Passing Model

The parameter passing model has been revised to allow portlets and portal pages to be "wired" together. In the new model, portlets declare their input parameters and also any events they raise. Events allow portlets to signal that the user has done something interesting. Each event may include a payload or set of values. A page designer can "wire" the payload of an event to the input parameters of other portlets on the same page or even another page through "page parameters". The new parameter passing model is described in several PDK articles.

### Portal Authentication

Portal Authentication is a security feature that allows a web provider to authenticate the source of an HTTP request thereby protecting confidential data from prying eyes. This feature uses a system of shared keys and dynamically generated checksums to ensure that HTTP requests originate from a known and trusted source. Any requests that cannot be authenticated are rejected by the web provider.

### Web Cache Integration

OracleAS release 9.0.2 includes a component called Web Cache. Web Cache is an in-memory cache that sits in front of the Oracle HTTP Server and caches content delivered by the HTTP Server. Subsequent requests for the same content are served from the in-memory cache and the requests never even reach the HTTP Server. Content is cached using an invalidation model - that is, content is cached for a specified period, as in expiry based caching, but the application the owns the content can invalidate the cache entries at any time. The advantage of invalidation based caching is that you can cache dynamic content without needing to issue a "ping" request to determine if the content is still valid. Whenever anything happens in the owning application that would render the content invalid, the application issues an invalidation request to remove stale entries from the cache.

PDK-Java 9.0.2 v2 lets you use web cache in front of your web providers, caching portlet content so portlet requests are served from the in-memory cache. In addition, it also includes APIs that allow you to invalidate portlet content based on commonly used portlet and user information. You can also construct invalidation requests for application specific parameters.

### Impact of Changes

For most developers, the impact of these changes is relatively small. The steps necessary to convert a provider from PDK-Java 3.0.9 to PDK-Java 9.0.2 are outlined in the article Migrating to PDK-Java 9.0.4

## Installation

Follow the instructions within the Installing PDK-Java 9.0.4 article.

## Known Issues

The following known issues exist in this release of PDK-Java:

- Same Cookie Domain Option Cannot Be Used When Registering 9.0.x Web Providers: The Web Provider registration screen contains the option Same Cookie Domain. Do not use this option with 9.0.x Web Providers. This option is only provided so that existing 3.0.9 Web providers (running in the JServ servlet container) can continue to use this functionality and be registered with OracleAS Portal 9.0.x. For more details, refer to the article Sharing Session Cookies Not Allowed in PDK-Java Release 2.
- bug 2644967: Portlet specific cache level settings do not work if you are using invalidation based caching. These settings do work for expires and validation based caching.

Revision History: |
Revision No | Last Update
9.0.2.0.0 | August 24, 2001
9.0.2.0.2 | March 18, 2002
9.0.2.4.0 | October 25, 2002
9.0.2.5.0 | November 2002
9.0.2.6.0 | February 7, 2003
9.0.2.6.1 | July 14, 2003
9.0.2.6.2 | September 10, 2003
9.0.4.0.0 | October 1, 2003
9.0.4.0.2 | November 5, 2003
9.0.4.1.0 | December 7, 2004

Oracle Corporation World Headquarters 500 Oracle Parkway Redwood Shores, CA 94065, USA http://www.oracle.com/ | Worldwide Inquiries: 1-800-ORACLE1 Fax 650.506.7200 | Copyright and Corporate Info