How-to share skin definition files across applications
By Frank Nimphius-Oracle on Nov 25, 2010
Skinning defines the look and feel of an ADF Faces web application. On OTN and on internal help lists, the question came up of how to share a single skin definition file across ADF Faces applications to ease skin administration and modification. The preferred solution among customers is a URL reference to a remote server that downloads the skin definition with the start of an application. Though it is possible to setup the "style-sheet-name" element in the trinidad-skins.xml configuration file to reference the skin CSS source file using an absolute URL to a remote host, I am not convinced this is best good practice:
- The remote host connection may fail, in which case all applications start with the simple look and feel, which is far away from any corporate design I am aware of
- In the past it happened that failed configuration on a router - or a defect - lead to bad response time of servers. If one of these servers hosts the remote CSS file, then most likely the application renders with the simple look and feel
- Hard coded URL references are hard to maintain, and even if the trinidad-skins.xml file allowed the use of EL to dynamically resolve the URL, the URL had to be configured for and deployed with the application
- Skin inheritance is from a base skin definition that is referenced by its skin family name and the ".desktop" or ".pda" extension. If both skin definitions reference remote servers for their CSS, then the original motivation to simplify administration is traded in for a more complex and error prone approach.
The better solution, which addresses all the problems listed for the URL reference approach, while still meeting the goal of simplified administration and configuration is to use skin definitions that are defined in and deployed as shared libraries to WLS.
- Shared libraries can contain a single skin definition or related definitions. For example, a base skin file can be shipped with skin definitions hat inherit from it
- Shared libraries contain a copy of trinidad-skins.xml in it, which simplifies skin detection and configuration
- Changing a skin only requires changing the deployed shared library. WLS takes care of making sure all servers in a cluster are equipped with the library
- Different application point to exactly the same skin definition, so that consistency is guaranteed
- No network latency between the application using a skin and the server hosting the skin
- Skin definitions are protected from unapproved changes. This ensures that a corporate skin does not degenerate over time by developers applying ad-hoc fixes
To implement the shared library approach, developers need to change their existing skin definition so it can be deployed in a JAR file. The steps for this include
- Creating a META-INF directory
- Creating a trinidad-skins.xml file that defines the skins deployed with the JAR file
- Creating an META-INF/adf sub directory for images and icons served from the JAR file
- Changing the image reference in the CSS to include the "adf" directory, which makes sure images and icons are handled by the ADF Faces resource loader, which can read resources from JAR files
- JAR the META-INF directory to create the library file
The "how-to deploy skin definitions in a JAR file" is
explained in the "Oracle Fusion Middleware Web User Interface Developer's
Guide for Oracle Application Development Framework" product documentation,
which you can access from here:
In the following, the steps to deploy the JAR file are listed in brief - though detailed enough to succeed.
In the following, I detail the steps for deploying a new skin definition "princessSkin" in a JAR file and configuring it as a shared library in WLS and Oracle JDeveloper.
First, create a folder structure as explained in the Oracle product documentation to host images, and CSS files. The trinidad-skins.xml file itself is located directly under the META-INF directory you created.
Make sure the JAR command is in the command path of your OS. If not, set the path and add a reference to the bin directory of a Java JDK 6 or 5. If you have no stand alone JSK installed, use the one within the Oracle JDeveloper installation.
Next, issue the JAR command shown below
jar -cvf <name of skin jar>.jar META-INF/
The command is expected to be performed from the parent folder of the META-INF folder you created to hold the skin sources and the trinidad-skins.xml file. In the example I built, I created a pricessSkin.jar file, using the following command
jar -cvf princessSkin.jar META-INF/
To configure the JAR file as a shared library, startup WebLogic server (either the integrated WLS in Oracle JDeveloper for testing, or a stand-alone server for production) and connect to the WLS console
http://host:7101/console or http://host:7001/console
Connect as weblogic/weblogic1 to connect as an administrator
Note: If you are in a production environment and weblogic/weblogic1 still allows you to authenticate to the server then you have a serious security problem
In the administration console, select the "Deployment" entry in the "Domain Structure"
Press the "install" button on top of the deployments table to register a new library
Browse to the location on the local server that has a copy of the skin definition JAR file and select it before pressing "Next"
The next screen shows an error message that you can ignore. Still on this screen however, you should pay attention to the "Name" field that shows the suggested share library name. You can keep the default name, or change it. However, it is important to remember the name as we need it later.
Still on the same screen, select the "Copy this application onto every target for me" option, to ensure all servers within a cluster are updated. Then press "Next"
You can then decide whether or not you want to review the configuration before pressing "Finish" on the next screen
Note: The WLS console may or may not ask you to activate the applied changes. What you should always do though is to re-start WLS server - even if the server says that this is not needed.
Open the application(s) that you want to use the skin definition in the shared library file in Oracle JDeveloper. Expand the "Application Resources" accordion in the Application Navigator and select the "weblogic-application.xml" file. Double click onto the file to open it.
With the "weblogic-application.xml" file opened in the visual editor, select the "Libraries" category
Press the "green plus icon" to create a new library reference for the application
In the library name filed, type the name of the shared library you just created. In the example I used, the name was "princessSkin"
Next time the application deploys, the shared library and its skin definitions become available for the application to use
Note: If you deploy the application to a server that does not have the shared library defined, then the deployment will fail because of the unresolved library reference
The same topic will be published, with supporting images, in the monthly OTN harvest document published on ADF Code Corner by the end of 11/2010 - http://www.oracle.com/technetwork/developer-tools/adf/learnmore/index-101235.html