Oracle Portal Development Kit
PDK Services for Java Release Notes

System Requirements

Samples

What's New

Known Issues

Installation

Migrating your JPDK

### SYSTEM REQUIREMENTS

The following are the recommended and minimum requirements to use and install the PDK Services for Java version 3.0.9.8.4.

Portal Version | 3.0.6.3.3, 3.0.6.6.5, 3.0.7.6.2, 3.0.8.9.8, 3.0.9, 9.0.2
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.

### SAMPLES

The JPDK samples illustrate how to develop portlets using the JPDK. Portlet output may be rendered by generating HTML within Java methods, using Java servlets, Java Server Pages (JSPs) or static HTML pages in any combination. The following is a list of sample portlets included in this version of the JPDK.

- Hello World Portlet - JSP. Illustrates how to create a basic Web portlet using Java Server Pages. Build a portlet using two lines of code and two lines of HTML. The source for this portlet is located in the jpdk/htdocs/helloworld directory.

- Web Services Portlet. Illustrates a fully featured Web portlet with the render modes implemented in Java. The Web Services Portlet displays 6 show modes. It displays a welcome message and session information within the show mode. It displays information about the portlet in the about and help modes. The edit mode allows users to customize the portlet title and portlet greeting. The details mode allows users to view the portlet in a fullscreen page, view the current language, and clear the current session. Finally, the Web Services portlet allows administrators to set the default title and greeting using the editdefaults mode. The source for this portlet is located in the jpdk/src/oracle/portal/sample/devguide/helloworld directory.

- Hello World Portlet - Servlet. Illustrates how to create a Web portlet with the render modes implemented using a combination of servlets, JSP pages and HTML pages. This example also uses the FilePersonalizationManager and NameValuePersonalizationObject classes that were introduced in JPDK version 1.3. The source for this example is in the jpdk/htdocs/helloservletworld and jpdk/src/oracle/portal/sample/devguide/helloservletworld directories.

- Lottery Portlet - JSP. Learn how to use the portlet renderer utilities to place images in your portlets. The lottery portlet uses the personalization manager to handle user customization. The source for this portlet is located in the jpdk/htdocs/lottery and jpdk/src/oracle/portal/sample/devguide/lottery directories.

- MultiPage Sample. Illustrates how to switch between two screens within the context of a Portal page. This portlet sample uses the <pageParameterName> tag in the provider.xml to pass parameters within the Portal page. This portlet is a JSP and the source code is located in the jpdk/htdocs/multipage directory.

- Expires Sample. Illustrates expiration (time) based caching in a Web portlet. This portlet is a JSP and the source code is located in the jpdk/htdocs/cache directory.

- Validate Sample. Illustrates validation based caching in a Web portlet. This portlet is a JSP and the source code is located in the jpdk/htdocs/cache and jpdk/src/oracle/portal/sample/devguide/validatecache directories.

- Form Input Portlet - JSP. Learn how to process form input as well as use the different portlet show modes. Note that the help and about links are mapped to HTML while the others are all JSPs. It uses the standard provider.xml way of mapping show modes. The source for this portlet is located in the jpdk/htdocs/forminput directory.

- Snoop - JSP. This portlet shows the information passed in requests to that page. It is meant for informational purposes and the source for this portlet is located in the jpdk/htdocs/snoop directory.

- Slow Rendering Portlet - JSP. This portlet demonstrates the use of oracle.portal.provider.v1.PortletExecutionTracker to see whether the execution time for a show request has exceeded the provider level warning timeout. It sleeps for up to 3 minutes, checking every 10 seconds whether the warning timeout has elapsed in which case it exits early. The source for the portlet is located in jpdk/htdocs/slowportlet. The timeout specified in provider.xml is set high (60 seconds) so that the portlet content may be returned to and seen in a portal page.

### WHAT'S NEW

### Release 3.0.9.8.5A

- New Feature: Added a new initArg to enable the provider test page without turning on debug logging. The new argument, show_test_page, can have the following values:
  - 0 (zero) - test page disabled (enabled if debug logging is on for backwards compatibility)
  - 1 - show the standard test page
  - 2 - show the standard test page. If an error occurs while processing the provider definition, include a stack trace in the test page

- Bug 2701149 - Previously, the auto-reload functionality was triggered refreshing the Portlet Repository. However, this approach does not work in load balanced environments because only one provider in the farm receives a call to "getPortletList". Auto-reload has been modified so that it now operates based on a timer, comparing the last modified date of the provider definition file that was loaded with that on disk. The frequency of the checks defaults to once every 5 minutes, but this can be modified using servlet initArgs. The arguments for controlling auto-reload are now:

- auto_reload - true/false
- reload_interval - time between reload checks in milliseconds. Default=300000 or 5mins

- Bug 2701187 - Errors are now logged to the log file when a portlet cannot be found

- Bug 2753830 - Added English resource bundles. Previously, the only resource bundles for English were the defaults. However, when installed in an environment where the default locale is something other than English (eg Japanese), links did not get translated correctly

- Bug 2764973 - Provider Test Page can now render multibyte characters. Previously, the Provider Test Page could only render characters from the ISO-8859-1 character set. It is now rendered using UTF-8

- Bug 2769772 - Modified the Hello World Portlet to bring it in line with the equivalent portlet JPDK v2 portlet

### Release 3.0.9.8.5

- New Feature: Mobile extensions are now included in JPDK v1. These extensions let you create portlet content that is designed specifically for mobile devices

- Bug 2375975 - various changes to URL Services for thread safety

- Bug 2425296 - sample portlets now explicitly set the content type so their content is generated in UTF8. This means that multibyte content such as usernames are now displayed correctly.

### Release 3.0.9.8.4A

- Bug 2485509 - The Customize link in the MOC renderer was not correctly aligned. It is now correctly aligned based on the display direction

- Bug 2481347 - If a SecurityManager denied a user access to a Portlet, the Performance Monitor would not be able to gather some of the portlet information and this would result in a NullpointerException. Since the user was denied access to the portlet, this was a benign error, but it did result in an error stack being written to the log file. This situation is now handled correctly.

### Release 3.0.9.8.4

- PDK-Java releases are now numbered relative to the Oracle Portal releases or patch releases. PDK-Java releases that are include in Oracle Portal releases or patches will have the same release number as the Portal release. If it is necessary to create a PDK-Java release between Oracle Portal releases, the PDK-Java release will have the same numeric release as the previous Portal release with an alphabetic suffix (eg 3.0.9.8.4a). This numbering scheme will make it easier to determine which release of Oracle Portal a specific PDK-Java release conicided with.

- New Feature: You can now record Performance statistics in the provider log file. To enable this feature the debuglevel initialization argument must be set to 0 or greater. 0 (zero) will enable performance logging only. Higher levels will enabled more detailed logging. 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. This 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 (eg 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", or "SYSTEM".
- expiryTime - the length of time in minutes a portlet will be cached by the Portal. This is used only by portlet requests with a cache status of "MISS,EXPIRES"
- cacheRequestKey - the value of the cache key recieved 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 is "HIT,PING". If they are different, the cache status is "MISS,STALE"
- cacheResponseKey - the value of the cache key that was returned to the Portal. This is used in show requests for portlets using validation based caching. see cacheRequestKey for more details.

- New Feature: A request monitor has been added that:

  1. logs a warning message if a portlet does not complete execution within a specified "portlet timeout"
  2. allows a portlet to voluntarily terminate execution if the "portlet timeout" has been exceeded
  3. forcefully terminates a portlet request if that request exceeds a specified "kill timeout"

This feature was added because the Parallel Page Engine (PPE) that makes requests to web providers has a request timeout mechanism and if a portlet request does not complete within that timeout, the PPE stops waiting for the portlet and returns the page to the user. However, the web provider cannot be notified of this condition and may continue executing very slow portlets. If a portlet is very slow and consuming excessive resources for some reason, it is possible for a single portlet bring an entire application server down. This is not just theoretical - we have actually seen it happen in a load-balanced production environment. This occurs because the PPE continues sending new requests that it subsequently times out. However, the requests are continuing to execute on the application server. The load on the application server climbs exponentially as resource usage and contention increases.

The "portlet timeout" lets you identify portlets that are consistently slow and need to be examined, quarantined, or even removed from your Portal. The "portlet timeout" is specified in milliseconds as a provider servlet initialization argument called portletTimeout. The default value is 30 seconds. The value you use should be generally be greater than the timeouts you specify in your provider definition file (provider.xml) but do not have to be. This setting only controls the logging of a warning message. It is a good idea to set performance goals for all portlets you include in your portal. If you have such a goal, the portalTimeout should be set equal to that goal so can identify portlets that are not achieving the goal.

The oracle.portal.provider.v1.PortletExecutionTracker interface (implemented by PortletRenderRequest) lets a portlet take control of its own destiny and clean halt execution if it has exceeded the "portlet timeout" (by which time the PPE will most likely have stopped waiting for the response anyway). The interface includes several methods, the most important being hasPortletTimeoutElapsed(), which lets the portlet periodically check it's progress against the timeout. It is recommended that this method be called after performing operations that might be expensive or time-consuming. For example, after executing complex SQL statements. If the timeout has expired, the portlet should release all resources it is holding and exit as quickly and cleanly as possible. It should not attempt to write any more data to the response because the PPE is most likely timed out the request and discarded the HTTP Connection. For more information about this interface please refer to the Java Doc.

In order to demonstrate these features a "slow" portlet is now included in the PDK-Java samples.

- Bugs 2306094, 2306104, 2389373: Bi-Directional rendering support. Corrected various rending issues that surfaced when rendering portlet containers in a right-to-left direction (Arabic or Hebrew)

- Bugs 1857407, 2045159: Resources bundles for sample providers are now translated in to all languages supported by Oracle Portal. This also corrects a bug where some strings in the Japanese resource bundle where not translated.

- Bug 1756647: Removed the JSPServices portlet from the samples. This is part of an effort to consolidate the existing samples. The JSPServices portlet duplicated much of the functionality demonstrated by the HelloWorld portlet.

### Release 3.0.9.0.7

- Bug 2221714: User specific info in show requests will be passed as headers in Portal 9.0.3 to allow middle tier system level caching. PDK-Java now looks for user specific parameters in the show request headers if they are not present in the request body.

### Release 3.0.9.0.6

- Bug 2169764 Removed logging of access denial messages to the jserv error logs when a user is denied access to a portlet by a security manager. This was removed so the error logs show only true error messages.

- Bug 2135581: PortletRendererUtil.RenderPortletHeader/Footer did not use the Writer object that was passed to them. Instead, they always retrieved the Writer object from the PortletRenderRequest. This caused JSP portlets to be displayed below the portlet container. These methods now use the Writer object that is passed to them and if that parameter is NULL, they get the Writer from the PortletRenderRequest

### Release 3.0.9.0.5

- New Feature: This version of PDK-Java includes a new set classes to simplify the creation and use of custom portlet containers. oracle.portal.provider.v1.PortletContainerRenderer is an abstract class that provides methods for rendering the portlet container (that is the header and footer) for each of the portlet render modes. In addition, the PDK-Java includes 3 implementations of this class:

- oracle.portal.provider.v1.DefaultContainerRenderer - renders standard Oracle Portal headers and footers
- oracle.portal.provider.v1.MocContainerRenderer - renders portlet headers and footers like those on my.oracle.com
- oracle.portal.provider.v1.ContainerRenderer306 - renders portlet headers and footers like Oracle Portal release 3.0.6

You can specify a container renderer at the provider or portlet level in your provider definition file (provider.xml) using the following syntax:

<containerRenderer class="<container renderer class>" />

If you specify a container renderer at the provider level, it will be used for all portlets belonging to that provider unless the portlet overrides the setting with it's own container renderer. If you do not specify a container renderer, the DefaultContainerRenderer will be used.

For backwards compatibility, the methods in PortletRendererUtil that used to be used for rendering the portlet container now use the new container renderers. These methods first determine which container renderer should be used based on the provider/portlet settings so you can leverage this new functionality without changing your existing code.

- New Feature: Added APIs that allow you to construct parameterized links for "help" or "detail" views of your portlet. Parameterizing the links lets you create a portlet with multiple "detail" views and context sensitive help links. Context sensitive help links could be included in any of the other render modes. To take advantage of this feature you would include parameterized links in appropriate places in your portlet and then look at which parameters are set to determine which "view" you should render in your help or detail renderer. The new methods are:

- PortletRendererUtil.ConstructDetailLink()
- PortletRendererUtil.ConstructHelpLink()

sample code using PortletRendererUtil.constructDetailLink():

PortletRenderRequest prr;
...
// initialize parameters for link
NameValuePair[] params = new NameValuePair[2];
params[0] = new NameValuePair("detailMode", "1");
params[1] = new NameValuePair("detailContext", "context information"); // call API to construct the link
String link = PortletRendererUtil.constructDetailLink(prr,params,true,false); // display link in portlet
...

The last 2 arguments of the method allow you to specify whether the parameters should be encoded and whether they should replace any parameters of the same name that exist in the base link.

- New Feature: PDK-Java now lets you control the visibility of the customize link based on the authentication level of the user. This feature replaces the previous controls which only allowed you to hide the customize link from "public" users (users who are not authenticated). The levels you can set are "PUBLIC", "WEAK" and "STRONG". The authentication level is set using following tag in the provider definition file:

<portlet>
....
<minEditAuthLevel>STRONG</minEditAuthLevel>
....
</portlet>

Weak authentication is a feature that is planned for release in Oracle Portal 9.0.2

- Bug 2116499: In certain circumstances, ServletProviderSession could throw a NullPointerException because the internal reference the HttpSession had been cleared. This was caused by poor management of ServletProviderSession objects when multiple requests were being processed concurrently. Management of ServletProviderSession objects has been cleaned up so only 1 ServletProviderSession object can exists per user session. This object, which is simply a wrapper for the HttpSession, is now shared by all threads that need to access the session and construction/initialization is synchronized to prevent multiple instances being created.

- Bug 2008636: PDK-Java used to throw an IllegalStateException if the portal did not send any content types in the "accept" HTTP header. This could happen in rare cases if the portal was not correctly configured. The PDK-Java now defaults content types for HTML, mobile XML and XML content.

### Release 3.0.9.0.4

- Bug 1935057: Parameter values are now correctly encoded and decoded when operating in a multi-byte environment. Under certain circumstances, data could be lost during the decoding process that resulted in parameter data being corrupted.

### Release 3.0.9.0.3

- New Feature: This version of PDK-Java includes a new Data Base Personalization Manager, `oracle.portal.provider.v1.DBPersonalizationManager2`. Previous versions included a data base personalization manager wich stored, in addition to other relevant information, the user's locale. This behaviour is different to PDK-Java's other two implementations of the `PortletPersonalizationManager` interface, `oracle.portal.provider.v1.FilePersonalizationManager` and `oracle.portal.providet.v1.http.DefaultPortletPersonalizationManager` . The new class stores data in the database in the same way as those. A new sample, dbPersonalization2, has been added which includes a SQL script to create a new preference store in the target database and a sample XML Provider Definition. `DBPersonalizationManager2` uses the same connection pool as `DBPersonalizationManager` .

- New Feature: This version of PDK-Java includes a command-line utility which migrates customizations stored using `oracle.portal.provider.v1.FilePersonalizationManager` to the database table used by `oracle.portal.provider.v1.DBPersonalizationManager2`, the new database personalization manager released with this version of PDK-Java. Thus Provider administrators can now move customizations off thier file systems and into the database ready for retreval by `DBPersonalizationManager2` .

The utility is designed to run on JVM versions 1.1.8 and higher and is invoked in the following manner:-

`java -DConnectionManager.config=/path/to/connectionManager.xml oracle.portal.provider.tools.v1.FileToDatabase` [mandatory arguments] [optional arguments]

where:-

Mandatory Arguments | `/path/to/provider.xml` | Location of the XML Provider Definition of the provider whose portlet's customizations are to be migrated.
| `/path/to/rootDir` | Root directory holding the customizations. PDK-Java defaults this to the provider_root.
| `connectionName` | The name of the connection to be used. This is specified in `connectionManager.xml`
Optional Arguments | `-t tableName` | Name of the table into which customizations will be inserted. Default: `jpdk_preference_store2`
| `-p providerID` | ID of the provider whose portlet's customizations are to be migrated. Default: all directories below the `rootDir` whose names may be parsed as `long`s are searched for customization files.
| `-o portletID` | ID of the portlet whose customizations are to be migrated. Default: all portlets who are declared to use `FilePersonalizationManager` or `DefaultPortletPersonalizationManager` by the XML Provider Definition supplied. This optional argument may be specified without a `providerID` argument.
| `-c transformClassName` | The name of a loadable class which implements `oracle.portal.utils.v1.Transform` . If this argument is supplied, an instance of the class will be used to transform data objects before they are written to the database by a call to the `public Object transform(Object)` method. It is thus possible, for example, to migrate data from the deprecated `oracle.portal.provider.v1.http.BaseCustomization` class to the more robust `oracle.portal.provider.v1.NameValuePersonalizationObject` class. Note that the user of this utility must supply the logic to migrate the actual data by providing an implementation of the public `Object transform(Object)` method.
| `-l logFile` | File to which log messages are to be written. Default: the console.

Run this utility with the same `classpath` used to start up the JServ JVM. A database table equivalent to that created by the `/jpdk/providers/dbPersonalization2/jpdk_preference_store2.sql` script must exist in the target database before this utility is invoked.

- New Feature: FileRenderer now caches the contents of the file so that it doesn't have to read the contents on each subsequent request. The last modified time on the file is used to determine if the cache needs to be reloaded.

- Bug 1989986: Performance tuning. This release of the JPDK includes performance improvements to minimize the overhead associated with reading and decoding parameters.

- Bug 1949420: ExternalPrincipal now includes the names of the form fields that should contain the external application username and password values. In addition, when other form field names/value pairs were declared, a NullPointerException was thrown if a pair specified a name, but the value was not specified. In this situation, the value is now converted to an empty String ("").

- Bug 1989984: JSP's rendering multibyte characters will now display correctly if the charSet property declared in the provider definition file matches the charset declaration in the JSP. This property is available to any renderer that extends BaseManagedRenderer.

- Bug 1987733: Calls to HttpServletRequest.getParameter() now returns an empty String if the parameter does not have a value. Similar calls used to return NULL which usually indicates that the parameter does not exist

- Bug 1816155: ServletPortletRenderRequest now correctly separates the content type from the charset when setContentType() is called passing a single string of the form "text/html;charset=utf-8". Previously, "text/html" was truncated to "text/htm"

- Bug 1819194: An exception used to be thrown if a provider was associated with an external application and the mapped username or password contained an ampersand (&). The same error could occur if other fields contained reserved XML characters. All data is now encoded to prevent this type of error.

- Bug 1788506: An exception used to be throws if a provider associated with an external application was accessed by a user that did not have an appropriate username/password mapping for that application

- Bug 1810741: In release 3.0.8 and earlier of Oracle Portal a single parameter was used to communicate both the username and the logged in status. With the addition of an authentication level in Oracle Portal release 3.0.9, logic was modified to separate the username and logged-in status into separate parameters. The change in usage of the original parameter broke backwards compatibility with Oracle Portal release 3.0.8. This release of the JPDK is compatible with all releases of Oracle Portal.

### Release 3.0.9.0.2

- Bug 1863246: User's cookies are now available at all times and do not depend on the existence of a servlet session.

### Release 3.0.9.0.1

- Bugs 1810741 and 1832878: ProviderUser.isPublicUser() was broken when Oracle9iAS Portal release 3.0.8 was released. This would cause the customize link to be displayed to users who are not logged on to the portal. There are two patches for this bug.

If you are using Oracle9iAS Portal release 3.0.8 you should download the patch for bug 1832878. This patch is for the portal, not the JPDK.

If you are using Oracle9iAS Portal release 3.0.9 you should download the patch for bug 1810741 which includes this release of the JPDK and patches for the portal and database and mid-tier.

- Bug 1788506: When an exception occurs in the JPDK while processing a SOAP message, a stack trace is sent to the portal along with a description of the error. However, if the exception occurred within a constructor, the stack trace would include the string '<init>'. This caused the portal to fail while parsing the XML response. The JPDK now wraps all stack traces so they are ignored by the XML parser

- Release 3.0.9.0.0 of the JPDK did not include the Java source code for the sample providers. The source is included in this release.

### Release 3.0.9.0.0

- The JPDK version numbering scheme has been changed so it reflects the version of Oracle Portal the JPDK is released with. The first 3 digits represent the major version number of the portal. The remaining 2 digits will be used to indicate patch releases to the JPDK.

- New Feature: Multibyte Support. Previous versions of the JPDK included the ability to display multi-byte content in a portlet. This release extends that support to allow you to include multi-byte parameters in URLs. If you need to encode any parameters, you should use PortletRenderUtil.encodeParameter() to encode them. Do not use java.net.URLEncoder or URLDecoder since these classes do not support multibyte characters. As with regular URL encoding, parameters that you encode will be automatically decoded.

NOTE: if you are using JSPs to render your portlet content you must explicitly specify the character set of your content otherwise your JSP engine will default the character set to ISO8859-1 (Western European ASCII). This is a feature of the JSP 1.0 and 1.1specification. If you are displaying portal usernames in your content you should either hard-code the character set to "utf-8" or get the character set using PortletRenderRequest.getCharacterSet(). This is necessary because Portal release 3.0.9 allows usernames to contain multibyte characters & usernames may not be displayed correctly if you do not specify the character set.

- New Feature: Database Personalization Manager (Beta). Previous versions of the JPDK only included a file-based implementation of the PortletPersonalizationManager interface. This release includes a database-based implementation, including built-in connection pooling. The Database Personalization Manager can be substituted for the FilePersonalizationManager (or any other personalization manager) simply by updating your provider.xml file to reference the new class. A new sample, dbPersonalization, has been added to the JPDK. The sample includes installation instructions describing how to configure the Database Personalization Manager and create the database table it uses to store your customizations.

- New Feature: Hosted Portal Support. If your provider is registered in a portal that is operating in hosting mode (with multiple virtual portals operating independently within a single physical installation), user objects will include a company name. The company name is the name associated with the virtual portal - usually a company or organization. You can still rely on provider id being unique so your provider does not need to be coded any differently to be used in this type of environment. However, you may want to display the company name in your portlets or use it for some other purpose.

- New Feature: Simplified Subscription Support. Previous releases of the JPDK only communicated the subscriber id (if specified) during the provider registration process. The JPDK now sends the subscriber id as part of the user information. This means that you no-longer need to maintain a persistent mapping of provider id to subscriber id in order to use the subscription feature. The subscriber id is now available using ProviderUser.getSubscriberId().

- New Feature: Sample provider.xml files now include a centralized definition for <appPath> and <appRoot> . These values are commonly the same for all portlets within a provider and any change, such as installing the samples, requires you to modify many entries in a file. Sample provider.xml files now include two XML entity definitions at the top of the file. These definitions are similar to global variables in a program and all references to the entities will be replaced by the values associated with them. The two entities are called:

  - virtualRoot - referenced in <appPath> elements
  - physicalRoot - referenced in <appRoot> elements

You do not need to use these entity definitions. They were simply added as a convenience. If you find you have other sets of repeating information, you can add your own.

- Bug 1645299: Previous releases of the JPDK made it difficult to add new arguments to the HttpProvider servlet and access those arguments via you provider. To rectify this situation a new interface has been added. The new interface, Initializable, defines a single method:

public void init(ParameterMap parameters)

ParameterMap is also an interface so you can use the Initializable interface anywhere you need to be able to initialize an object with a variable (and unknown) number of arguments.

If your provider implements this interface, HttpProvider will call this method instead of the Provider.init() methods. DefaultProvider now implements the Initializable interface and the default implementation calls the old Provider.init() method so you will not see any change in behaviour unless you override the method above. DefaultProvider also exposes the ParameterMap it receives during initialization via the getProviderContext() method. This means the parameters are easily accessible throughout the framework. For example, from within a renderer, call the following:

PortletRenderRequest.getProvider().getProviderContext();

- JPDK 1.4 added the ability to define static parameters for JSP and Servlet renderers. In the original implementation, the framework would first look at the static parameters and if a value was not found, it would look at the request parameters. This release of the JPDK reverses that order so that the framework first looks for parameters in the request and then looks at the static parameters. This allows you to use the static parameters as defaults for request parameters which may or may not be present.

- Bug 1677332: The provider test page, which displays information about your provider, is now only displayed if debug mode is turned on. This prevents unnecessary provider information being exposed on production systems.

- Bug: 1634405 - ExternalPrincipal.java now includes the authentication URL and authentication method settings for the external application. A method has also been added to allow you to enumerate the names of the fields associated with the external application.

### Release 1.4

- New Feature: RenderManager is a new type of renderer that manages a set of simplified renderers that implement the new ManagedRenderer interface. RenderManager takes care of determining the mode and drawing the appropriate header and footer - all your ManagedRenderer needs to do is render the content for a single mode. This model makes it extremely easy to add new renderers and to mix/match renderers on an as-needed basis. As new rendering functionality is added to the JPDK it will follow this model rather than extending PageRenderer or ServletPageRenderer.

- New Feature: FileRenderer is a ManagedRenderer that is designed to plug into a RenderManager. FileRenderer lets you render portlet content using static files. The character encoding of the files can be specified as a parameter. This allows you to use files that include content encoded in a multibyte character set such as UTF-8.

See <charSet> tag definition in the provider.xml for specification of file character set

- New Feature: JspRenderer is a ManagedRenderer that is designed to plug into a RenderManager. JspRenderer lets you render portlet content using Java Server Pages (JSPs).

- New Feature: Servlet20Renderer is a ManagedRenderer that is designed to plug into a RenderManager. Servlet20Renderer lets you render portlet content using a servlet.

- New Feature: JavaRenderer is a ManagedRenderer that is designed to plug into a RenderManager. JavaRenderer is a new kind of renderer that allows you to call a method in a Java class to render content. Using a JavaRender you can cleanly separate the code for rending different modes into individual methods. RenderManager will take care of determining the mode and calling the correct method.

- New Feature: JSP and Servlet Parameters: You can now specify static parameters that should be passed to your JSP or servlet whenever it is called. You can define the parameters in your provider.xml file or set them programmatically during the initialization of your provider. Static parameters registered this way are accessed by calling the standard 'get' methods defined by the javax.servlet.ServletRequest interface. As with request parameters, you can define multiple parameter values that are identified using the same parameter name.

See <parameter> tag definition in the provider.xml for details

- New Feature: Support for Content Types: In older releases of the JPDK, you could only define a single renderer for a show mode. Since Oracle9iAS Portal and the JPDK will shortly be supporting mobile devices the JPDK now includes the ability to specify multiple renderers for a single portlet/show mode combination. This allows you to register renderers for a show mode based on the content-type that renderer will generate. For example, you can now register different JSPs for returning standard HTML and mobile content. This is necessary because the size of mobile devices is so much smaller than conventional browsers and requires data to be returned in a different format, possibly filtered or summarized. This behaviour is supported by RenderManager, PageRenderer and ServletPageRenderer.

See <showPage> tag definition in the provider.xml for details

- New Feature: DefaultSecurityManager. Previous releases of the JPDK did not include a default implementation of the PortletSecurityManager interface. This implementation uses the authentication levels feature that is currently scheduled for Portal release 3.0.9. This feature introduces the concept of authentication levels - an authentication level representing the degree to which a user has been authenticated by the Portal. There are 3 main levels:

  - public - the user has never logged on to the portal
  - weak - the user has logged on the portal in the past and been authenticated using a persistent cookie, but has not logged on in the current portal session
  - strong - the user has logged on and been authenticated by entering a password in the the current session

You can use the DefaultSecurityManager to specify the minimum authentication level necessary to view a particular portlet. If the user's current authentication level is not high enough, they will be denied access.

This class can be used with older portal versions (3.0.8 and earlier) but the only effective settings will be 'public' and 'strong' since the concept of weak authentication does not exist in these releases.

- New Feature: Extensible Provider Registry: DefaultProvider utilizes a registry in the form of an XML file called provider.xml. The format of provider.xml has been revised in this release of the JPDK so we can support arbitrary extensions to the information to support custom implementations of existing interfaces or even implementation of completely new functionality.

If you currently use DefaultProvider, or have extended DefaultProvider, your registry will be automatically upgraded whenever your provider is loaded. You can permanently upgrade (and save the cost of real-time conversion) using the following

java.exe - classpath <jar_path>/xmlparserv2.jar
oracle.xml.parser.v2.oraxsl -w -l provider.xml -s <pdk_home>/pdk/jpdk/src/oracle/portal/provider/v1/http/resource/upgrade_v1_to_v2.xsl -r upg

where <jar_path> is the location of xmlparserv2.jar
<pdk_home> is the location where you unzipped your PDK

This command will upgrade your registry file and create a file called provider.xml.upg in the current directory

- New Feature: Registry Naming. In older releases of the JPDK, if you used DefaultProvider you had to create a registry file and that file had to be named "provider.xml". You can use any name for your registry file by specifying the name as an argument to the provider's servlet.

For example: servlet.myprovider.initArgs=provider_definition=myprovider.xml

- New Feature: Improved Handling of Registry Parsing Errors. Errors in a registry file could cause alot of problems because there was no easy way to locate the error. The JPDK now includes an enhanced test page that lets you verify the structure of your registry file. Simply enter the URL of your provider's servlet in your browser and you will see the provider's test page. This page has been enhanced to load your registry file and display any errors it finds (including line numbers and character positions if available). If your registry was loaded successfully, you will see a list of portlets owned by your provider.

- New Feature: Auto-Reload of Provider Registry. You can now configure your Provider to automatically reload it's provider registry (provider.xml) file. If configured for automatic reload, the provider checks to see if the registry file has been updated since it was last loaded. In order to minimize the performance impact of this feature and allow it to be used in a production environment, the reload is only triggered when your provider receives a get_portlet or get_portlets message from a portal. You can force this to occur from the portal by refreshing an individual provider or refreshing the entire portlet repository

To enable auto-reload of your provider registry, add auto_reload=true to the initArgs of your provider servlet. For example

servlet.myProvider.initArgs=provider_root=c:/provider/root/,sessiontimeout=1800000,auto_reload=true

NOTE: Reloading the provider registry only reloads the provider and portlet definitions from the registry. It will not force Java classes or JSPs that have already been loaded into memory to be reloaded.

### Release 1.3

- New Feature: ServletPageRenderer extends the existing PageRenderer allowing you to implement one or more of your render modes using Servlets that conform to the Java Servlet SDK version 2.0. Since this class extends the existing PageRenderer so you can use any combination of Servlets, JSP pages or HTML pages to implement the various render modes of your portlet.

  If you are using the DefaultProvider, ServletPageRenderer supports the same set of provider.xml tags as PageRenderer with the addition of the following:

  > <showServlet>
  > <previewServlet>
  > <helpServlet>
  > <aboutServlet>
  > <editDefaultsServlet>
  > <editServlet>
  > <detailsServlet>

  In each case, the value associated with the tag is the fully qualified name of a Java class that extends javax.servlet.http.HttpServlet. For example, if you want to render the SHOW mode of your portlet using a servlet you would include the following in your provider.xml file:

<provider ....>
<portlet ....>
.....
<portletRenderer class=oracle.portal.provider.v1.http.ServletPageRenderer>
<showServlet>my.servlet.class</showServlet>
.....
</portletRenderer>
</portlet>
</provider>

Since ServletPageRenderer also supports the same tags as PageRenderer, it is possible to include 2 sets of information for the same show mode. For example, a servlet and a jsp page. If multiple sets of tags for the same show mode are encountered, the servlet will be used.

ServletPageRenderer will automatically load your servlet class when it is needed so you do not need to register the servlet classes with your servlet engine. Registration is not necessary because the servlet is not accessed via a virtual path from the listener. Instead it is invoked programmatically from within the JPDK.

- New Feature: FilePersonalizationManager is a new implementation of the PersonalizationManager interface that uses the file system to store customization information. This differs from the original DefaultPortletPersonalizationManager in the following ways
  1. DefaultPortletPersonalizationManager was provided simply to get you started with customizations. Since it uses Java Serialization it is brittle and prone to error when you evolve your providers (or upgrade your JPDK). FilePersonalizationManager solves this problem by delegating the reading/writing of customization information to the object containing the information using the PersonalizationObject interface. Using the PersonalizationObject interface, an implementation of PersonalizationObject simply reads or writes customization information from or to a stream. With the FilePersonalizationManager, the stream is a FileInputStream or FileOutputStream. Future additions to the JPDK will include other personalization managers that allow you to read/write to other types of streams
  2. This object containing the customization information must be an instance of PersonalizationObject. The PersonalizationObject interface contains the read() and write() methods the FilePersonalizationManager uses when reading/writing customizations. These methods read or write from/to a stream that is controlled by the FilePersonalizationManager. The FilePersonalizationManager takes care of creating, deleting, copying the file - all you need to do is read or write from/to the file.
  3. You can optionally spread files across a large number of sub-directories using a hashing algorithm. The algorithm limits the number of customization files that can be stored in a single directory and therefore allows the file system to more efficiently handle large numbers of customization files. By default, hashing is not used.

<personalizationManager ....>
.....
<useHashing>true</useHashing>
</personalizationManager>

- New Feature: NameValuePersonalizationObject is an implementation of the PersonalizationObject interface. It allows you to easily store/retrieve customization information as a series of name/value pairs. The Object equivalent of almost all the primitive data types (String, Integer, Long, Double etc) are supported. Arrays are also supported.

- External Application integration improvements (with Portal release 3.0.8). In Portal release 3.0.7 (and previous release of the JPDK), external applications had to trust the portal to authenticate users since the login server did not expose the external application mapping information. The only information the login server exposed was the "mapped" username - that is the portal user's username in the external application. With Portal release 3.0.8 and JPDK release 1.3, external applications now have access to the following:
  - external application username (mapped Name)
  - external application password
  - any hidden fields and associated values that were registered with the login server

To expose this information, a new initSession() method has been added to the Provider interface.

- Bug 1585848. Modified PortletRendererUtils.java to render customize page headers and footers using the style sheets introduced in Portal release 3.0.7. Users of Portal release 3.0.6 should include the following tag in provider.xml to continue using the 3.0.6 style UI. The tag (<useOldStyleHeaders>) should be added immediately following the opening <provider> tag as follows:

<provider ....>
<useOldStyleHeaders>true</useOldStyleHeaders>
<portlet ....>
.....
</portlet>
</provider>

If you do not use DefaultProvider.java (or a subclass of DefaultProvider) you should add a method to your provider as follows:

> > public boolean getUseOldStyleHeaders() {
> > return true;
> > }

- Bug 1580792. Modified PageRenderer.java to read default customization using the correct locale.

- Bug 1577146. Modified PageRenderer.java to correctly display portlet headers and footers in preview mode

- Bug 1573504. Remove JDK 1.2 dependencies introduced in JPDK release 1.2

- Bug 1554618. Previous versions of the JPDK did not allow you to access existing cookies within the Provider.initSession() method. A new method has been added to the ServletProviderUser class which implements the ProviderUser interface. The new method (getCookies()) returns an array of cookies that were received with the initSession request.

- Bug 1539625. Modified DefaultProvider.getPortlets() to return the correct subset of portlets based on the start and count parameters. Previously all portlets were returned.

- Bug 1487519. Various performance improvements to DefaultProvider.java

### Release 1.2

- Four new samples: JSP Services Portlet, MutilPage Portlet, Validatecache Portlet, and Expirescache Portlet. Please review the samples section to get more information about these portlets.

- Fixed bug #1480881: JPDK now throws an IllegalStateException if it doesn't receive a user name in a call from the portal. It used to ignore this situation commonly resulting in a NullPointerException from elsewhere when the user was referenced.

- Fixed bug #1492711: On Solaris, when error message were multi-lined, the JPDK wasn't correctly truncating this message when setting the response status.

- This caused an Internal Server Error 500 to be returned with a logged problem of "cannot scan response headers".

- New feature: added methods in PortletRendererUtil for rendering portlet error messages using a common portal look and feel. Methods are renderError(), renderErrorHeader(), renderErrorLine(), renderErrorFooter().

- Behavior change: it is now valid for the Portal to omit the login time and sessionId when it calls the portlet. Impact is that these ProviderUser attributes may now be null. If you are using these attributes you need to check to see if they are non-null before referencing.

### Release 1.1

- BaseCustomization object has changed to reflect new model for Multi-language support. As noted in the 9/22/00 release, the BaseCustomization object was changed to support an initial design for multi-language support. In this design the title member of the BaseCustomization object represented many values; one per language. To get/set the title the method took an additional Locale parameter to identify the particular language being requested. In this release this has been changed back to the original style supported in the 8/24/00 release. The title member now represents a single value. The Locale parameter is no longer needed to get/set the title. For the sake of backwards compatibility, the get/setTitle methods that take Locale have been deprecated. They are still supported in the current release (we just ignore the Locale) but will be removed in a (near-term) future release. The correct methods to use are:

- String getTitle(); or setTitle(String title);

Any portlet that relies on the BaseCustomization object will need to delete the existing user customization data before upgrading/rerunning. That is this change is incompatible with the existing format. The new version is unable to read customization data generated by the previous version.

- The exists() method in the PortletPersonalizationManager interface has changed. It now can throw an AccessControlException. This reflects our desire that this method authorize the user prior to checking for the existence of the personalization data. The DefaultPersonalizationManager has been updated to reflect this. Clients calling the exists() method directly will have to recode to include the call in a try/catch block.

- The PortletReference interface has been updated to support the new multi-language scheme. In particular the following methods have been added:

  - public Locale getDefaultLocale();
  - public boolean translateDefaultCustomizations();
  - public boolean isLanguageDefault();

Consult the JavaDoc to determine the particular function. Note however, the portal doesn't current support the new multi-language scheme. It neither passes the Portal's default language nor ever indicates you are in "translate" mode.

- Static strings used by PortletRenderUtil to render default titles or button labels have been moved to a resource bundle so they can be localized.

- PortletRenderUtil.getEditData() and submitEditData has been updated to support the new multi-language scheme introduced in this release. No API changes. And until the portal starts supporting the new multi-language scheme there should be no function changes.

- Added 2 new methods to the PortletRenderRequest interface. Each are placeholders for the new multi-language scheme that the Portal doesn't yet support. See the JavaDoc for further details.

  - public Locale getDefaultLocale();

  - public boolean translateDefaultCustomizations();

- DefaultPersonalizationManager updated: implements copy and destroy uses temp files for writes to avoid read/write inconsistencies.

- Added capability to PageRenderer for managing/setting expiry cache headers for html/jsp pages it renders. When the PageRenderer is defined as the PortletRenderer in the provider.xml file the subtag <pageExpires> can be set to express the number of minutes the PageRenderer should automatically set as the expiration cache setting for pages it renders when receiving a request in "show" mode.

### Known Issues

- Even if showPreview is specified as false in the provider.xml, Oracle9iAS Portal displays MODE_SHOW as a preview of the portlet. This is bug#1625843 and it will be fixed in Oracle9iAS Portal 3.1. Until then, we recommend that you simply create a preview page that displays the text "Preview Not Available".

### Installation

- Follow the instructions within the Installing the JPDK and Samples article.

### Migrating YOUR JPDK

Multiple JPDK installs is not available for one Oracle HTTP Server at this time. Because of this, you will need to migrate your JPDK to the current version. Migrating your JPDK is fairly quick and simple. Below are the steps to migrate the JPDK

- Download the current JPDK and extract it to a different location than the current JPDK. For example: jpdk309.

- Replace samples.jar in the current JPDK\lib directory with the one provided in the current JPDK.

- Replace provider.jar in the current JPDK\lib directory with the one provided in the current JPDK.

- Replace provider.xml in the current JPDK\provider\sample directory with the one provided in the current JPDK.

> Note: Remember to change the directory locations for the JSP portlets. There are 5 JSP portlets. Review step #9 under Configuring the Web Provider Samples within the Installing the JPDK and Samples article for more information.

- Replace the directories located under your default JSP directory such as $ORACLE_HOME/Apache/Apache/htdocs/jpdk with the directories located under jpdk/htdocs. This will make sure that you have the most current examples.

- Optional: Replace the current src and doc directories with the one provided in the latest JPDK. This only updated the documentation and source files for your own information and do NOT affect the samples.

- Stop and restart the Oracle HTTP Server.

- Login to Oracle Portal as an Administrator.

- Click on Administer.

- Click on Display Portlet Repository.

- Click on Refresh at the top-right of the page.

- Go to the Portal page that contains your samples and add the Web Services Portlet to your page

> Note: When registering a new provider with Oracle9iAS Portal, only the user who registered the provider has privileges to see the provider/portlets. If necessary, go to the Folder with the name of the provider within the Portlet Repository content area and update the provider privileges as required.

You have now successfully migrated to the current JPDK version.

Revision History:

- December 29, 2000
- January 25, 2001. Updated for JPDK v1.3
- February 2, 2001. Updated for JPDK v1.3
- March 15, 2001. Updated for JPDK v1.4
- April 14, 2001. Updated for JPDK v1.5
- April 27, 2001. Updated to rename JPDK 1.5 to JPDK 3.0.9.0.0
- June 14, 2001. Updated for JPDK 3.0.9.0.1 and corrected source code paths for samples
- August 10, 2001. Updated for JPDK 3.0.9.0.3
- October 8, 2001. Updated for JPDK 3.0.9.0.4
- February 1, 2002. Updated for JPDK 3.0.9.0.6
- February 26, 2002. Updated for JPDK 3.0.9.0.7
- June 7, 2002. Updated for JPDK 3.0.9.8.4