In this post, we will enumerate and explain some web.xml configurations that should be done before deploying ADF application for production environments.
Performance-related properties:
- org.apache.myfaces.trinidad.CHECK_FILE_MODIFICATION should be false. If this parameter is enabled, Trinidad will automatically check the modification date of your JSPs, and discard saved state when they change. This makes development easier, but adds overhead that should be avoided when your application is deployed. To disable checking for file modification, declare the following context parameter in your project's web.xml:
<context-param>
<param-name>
org.apache.myfaces.trinidad.CHECK_FILE_MODIFICATION
</param-name>
<param-value>false</param-value>
</context-param>
- org.apache.myfaces.trinidad.DISABLE_CONTENT_COMPRESSION should be false. When you run a page and view the html source, you will see style classes like class="x10". To see instead something more meaningful like class="af_inputText_content" you need to disable the styleclass compression which is enabled by default for performance reasons (1). To disable content compression, declare the following context parameter in your project's web.xml:
<context-param>
<param-name>
org.apache.myfaces.trinidad.DISABLE_CONTENT_COMPRESSION
</param-name>
<param-value>false</param-value>
</context-param>
The following snapshots illustrate the difference between enabling and disabling content compression:
![]() |
| CSS classes when org.apache.myfaces.trinidad.DISABLE_CONTENT_COMPRESSION is set to false |
![]() |
| CSS classes when org.apache.myfaces.trinidad.DISABLE_CONTENT_COMPRESSION is set to true |
- javax.faces.STATE_SAVING_METHOD should be set to client in general. This property identifies where the state of the view is stored between requests. By default state is saved in the servlet session. If you choose to save it at client-side then the state is encoded to a hidden variable placed in html code named com.sun.faces.VIEW. Client-side state saving helps you avoiding some issues like reposting a form. The object in servlet session can be updated in every post of the form while with client-side the deserialized object will be used at every post. Session-time outs will not a problem neither. Also a single server can be used by much more clients. Increasing in client numbers does not need an increase of server resources. Scalability is one of the benefits when using client. But it can be nasty with client-side if the size of the state exceeds reasonable lengths. For example if you embed h:forms in a datatable and have a huge collection in your backing bean binded to this datatable, the size of the state can grow in terms of megabytes which lowers response time. Also storing the state at client-side can be a security leak to a hacker eye :). But some encryption over the value can improve the client-state method I think (2). To enable client-side state saving, declare the following context parameter in your project's web.xml:
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
Scalability-related properties:
- oracle.adf.view.faces.CLIENT_STATE_MAX_TOKENS should be set according to back-button usage. The default value is 15. This parameter is responsible for setting the caching size to hold the state of posted pages so they are browser-back-button-friendly. What this means is that for every page that issued a POST back to the server a ViewState token will be held in memory to track back its client state. Note that this cache is session based, which means that increasing the number of CLIENT_STATE_MAX_TOKENS will increase the per-session memory footprint on your server. Notice that in 11g R2 this cache is kept per-session, per-browser-window(or tab). Suppose we have CLIENT_STATE_MAX_TOKENS = 2, and we have 3 pages in our application: Page1, Page2 and Page3, where we sequentially navigate in this order: Page1->Page2->Page3. In this case, 3 tokens will be created: Token1->Token2->Token3. Because we have set CLIENT_STATE_MAX_TOKENS = 2, the first token, Token1, will be removed and we will end up with Token2,Token3. Now, if we navigate back to Page1 using the brower's back button and re-post the page, we will receive a message saying "Because of inactivity you session is no longer active (...)" (3):
So as we said previously, oracle.adf.view.faces.CLIENT_STATE_MAX_TOKENS should be set according to back-button usage. To set the number of state tokens, declare the following context parameter in your project's web.xml:
<context-param>
<param-name> oracle.adf.view.faces.CLIENT_STATE_MAX_TOKENS </param-name>
<param-value>3</param-value>
</context-param>
- org.apache.myfaces.trinidad.COMPRESS_VIEW_STATE should be set to true. This property specifies whether or not to compress page state saved on the session. Each user session can have multiple pageState objects that heavily consume live memory and thereby impact performance. This overhead can become a much bigger issue in clustering when session replication occurs. The default is off. To enable state compression, declare the following context parameter in your project's web.xml:
<context-param>
<param-name>
org.apache.myfaces.trinidad.COMPRESS_VIEW_STATE
</param-name>
<param-value>true</param-value>
</context-param>
Security-related properties:
- oracle.adf.view.rich.security.FRAME_BUSTING should be at least differentDomain (default option) or always at best. This property enable using framebusting in your application. Framebusting is a way to prevent clickjacking, which occurs when a malicious web site pulls a page originating from another domain into a frame and overlays it with an illegally imitated page, allowing only portions of the original, or clickjacked, page (for example, a button) to display. When users click the button, they in fact are clicking a button on the clickjacked page, causing unexpected results. Framebusting prevents clickjacking by using JavaScript to block the application's pages from running in frames. If you configure your application to use framebusting by setting the parameter to always, then whenever a page tries to run in a frame, an alert is shown to the user that the page is being redirected. If your application needs to use frames, you can set the parameter value to differentDomain. This setting causes framebusting to occur only if the frame has the same origin as the parent page. To enable framebusting, declare the following context parameter in your project's web.xml:
<context-param>
<param-name> oracle.adf.view.rich.security.FRAME_BUSTING</param-name>
<param-value>always</param-value>
</context-param>
- oracle.adf.view.rich.versionString.HIDDEN should be true. This property reduces the amount of environment information returned by the ADF server in the HTML pages. These Information could be valuable to hackers or anyone profiling a system. Example of this information returned by the server is shown below:
</body><!--Created by Oracle ADF (ADF Faces API -
11.1.1.4.0/ADF Faces Implementation - 11.1.1.4.0, RCF-revision: 39851 (branch:
faces-1003-11.1.1.4.0, plugins: 1.2.3), Trinidad-revision: 1051544 (branch:
1.2.12.3-branch, plugins: 1.2.10), build: adf-faces-rt_101221_0830, libNum:
0355 powered by JavaServer Faces API 1.2 Sun Sep 26 03:21:43 EDT 2010
(1.2)), accessibility (mode:null, contrast:standard, size:medium),
skin:customSkin.desktop (CustomSkin)--></html>
To reduce all these information returned by the server, declare the following context parameter in your project's web.xml:
<context-param>
<param-name>oracle.adf.view.rich.versionString.HIDDEN</param-name>
<param-value>true</param-value>
</context-param>
Advanced properties:
- oracle.adf.view.rich.pprNavigation.OPTIONS could be set to onWithForcePPR. This parameter is used to turn partial page navigation on and off. By default, the value is off. Partial page navigation uses the same base page throughout the application, and simply replaces the body content of the page with each navigation. This processing results in better performance because JavaScript libraries and style sheets do not need to be reloaded with each new page. If pprNavigation.OPTIONS property is set to on, PPR navigation is turned on for the application and you need to set the partialSubmit attribute to true for any command components involved in navigation. If this property is set to onWithForcePPR , when an action on a command component results in navigation, the action will always be delivered using PPR as if the component had partialSubmit set to true.If the component already has partialSubmit set to true, the framework does nothing. If partialSubmit is not set to true, the entire document is refreshed to ensure that old page refresh behavior is preserved. The entire document is also refreshed if the action component does not contain navigation. Note that if you haven't used this feature before, please make sure to test your application with it. Do not blindly flip the switch! (4)


