JDev & ADF Goodies

9. May 2012

Patch Numbers for ADF Runtime Libraries Update to 11.1.2.2.0

After the release of the new JDev version 11.1.2.2.0 I ask support for the patch numbers for the ‘Sherman Update 2′, which seams to be the official name.
Support just answered my question:

The 2 patches are :

Patch 13656274: SHERMAN UPDATE2: RT BASED ON JDEVADF_11.1.2.2.0_GENERIC_120418.2212.6183.1
Patch 13656372: SHERMAN UPDATE2: WEBCENTER COMPOSER PATCH FOR SHERMAN UPDATE 2

But I need confirmation if it can be installes on top of WLS 10.3.5.0
as from the crertification matrix it is only certified on top of WLS 10.3.6.0 :
Oracle JDeveloper Certification Information

So lets hope we can somehow update the WLS 10.3.5 server with installed ‘Sherman Update 1′ :)

UPDATE May-10-2012:
Got this from support regarding upgrade of an existing WLS 10.3.5 server:

There was a confusion if 11.1.2.2.0 could be installed on top of WLS 10.3.5.0 as per the cerfification matrix

http://www.oracle.com/technetwork/developer-tools/jdev/jdev11gr2-cert-405181.html#Application_Servers

11.1.2.2.0 is only certified for WLS 10.3.6.0.

I got confirmation that ADF 11.1.2.2.0 requires the Application Development Runtime 11.1.1.6.0 libraries.
ADR 11.1.1.6.0 can be installed on WLS 10.3.5 or WLS 10.3.6
So 11.1.2.2.0 can be installed on top of WLS 10.3.5.0

UPDATE May-19-2012:

I got some more info about the possible upgrade path from Oracle I like to share:

Q1) Are the ADF 11.1.2.2.0 ADF Runtimes certified against WLS 10.3.5?

Yes and we’ve updated the cert matrix to reflect this: http://www.oracle.com/technetwork/developer-tools/jdev/jdev11gr2-cert-405181.html

Q2) Is there a patchset to move from 11.1.2.0.0 or 11.1.2.1.0 to 11.1.2.2.0?

No. As you’ve correctly identified, the only way is to install the 11.1.1.6.0 Runtimes then apply the 11.1.2.2.0 patch.

The release notes do highlight this fact, but do not mention that there isn’t a patch from 11.1.2.0.0/11.1.2.1.0 to 11.1.2.2.0: http://www.oracle.com/technetwork/developer-tools/jdev/11gr2update2-1592225.html#deploy. I’ll seek to get a clarification put in the release notes.

Q3) If 11.1.2.2.0 is a patch on top of 11.1.1.6.0 are all of the 11.1.1.6.0 features available to 11.1.2.2.0?

No. The 11.1.2.2.0 patch overrides functionality in 11.1.1.6.0 so customers should not assume this.

The answer to Q3) is probably the interesting one as it makes clear that even as we update from 11.1.1.6.0, we don’t get the features introduced with 11.1.1.6.0 in JDev 11.1.2.2.0 :-(
One other implication is that you can’t run applications from both versions on one WLS 10.3.6 server.

21. December 2011

JDeveloper 11.1.2.1.0: Stumbled uppon this Gem

Filed under: JDeveloper,Konfiguration — Timo Hahn @ 20:20
Tags: , ,

I don’t know why I never seen this before, but I like to share this (for me) hidden gem in the JDeveloper 11.1.2.1.0 IDE.
If you debug often I’m sure you like the possibility to change breakpoints so that they only hit under special conditions. In the older version you have to right click the breakpoint to get to the dialog to change the breakpoint conditions.

Old Breakpoint Edit Dialog

Old Breakpoint Edit Dialog

Well, today I happen to notice that using the current JDev 11.1.2.1.0 if you move the mouse over a breakpoint and wait for half a second you get this ‘Hoover’ edit breakpoint dialog.

New Hoover Edit Breakpoint Dialog

New Hoover Edit Breakpoint Dialog

The old dialog (which allows to reach all possible changes) can be reached as before using a right mouse click on the breakpoint.

For more information about how to manage breakpoints refer to the docs here.

Have fun playing with this.

23. September 2011

ADFLogger: Using a Custom Formatter Class to Print Log Messages

Based on some posts on the OTN JDeveloper forum this article shows how to implement a custom fdormatter class to use with ADFLogging and how to integrate it with the embedded WLS instance in JDeveloper. Sample workspace for the custom logger is available at the end of the article.
For this post I assume you now your way around java.util.logging. I show how to implement a custom formatter class to format the log messages with more information and a different style. The picture below shows the general java logging model:

General Logging Model

General Logging Model


As the model shows the formatter is used by the log handler which gets a log record and processes it by piping the record through a filter and then through a formatter to finaly pass it to the attached output target. In most cases the output target is a file, a db table, a system log or a stream. For the console logger its most often a stream (e.g. stdout and/or stderr).

A typlical JDev log message from the ConsoleFormatter looks like this:

<AdfcAppInitializer> <loadDebugFacades> ADFc: Initializing ADF Debugger

I’ll change this to:
FINE: 22.09.2011 13:18:17 - de.hahn.blog.popupregion.backingbeans.pageflow.SelectionBean$beaVersion0_39.selectionListenerEmp(SelectionBean.java:92) - 15 - de.hahn.blog.popupregion.backingbeans.pageflow.SelectionBean
  Selected: oracle.jbo.Key[105 ]

The general layout of the log message is
data in [] is customizable, data in {} is printed only if available
level: date time [- threadId] [- class] [- method] [- message] {- throwable.message}
These parameters configure which information to print
       t = thread
       n = logger name
       l = line number; if 'l' is selected 'c' and 'm' are not used
       c = class name
       m = method name

As you see there is more information printed, e.g. source and line number and log level. As this creates long log lines I made this customizable. How the parameters are passed to the logger is shown later.

First of all I implement a class DebugFormatter which extends java.util.logging.SimpleFromatter as this class is an implementation of the abstract class java.util.logging.Formatter the base of all formatter attached to a log handler. The key part of this class is the method

public String format(LogRecord record) {...}

which gets a log record and returns a string of the information which send to the handler for further action. The format method checks the parameters given and returns a string according to them.

To wire things up I modify the logging.xml file which can be reached from the ‘Application Server Navigator’. Right click on the integrated WLS and select ‘Configure Oracle Diagnostic Logging for …’. This will open a nice graphical overview

Logging.xml

Logging.xml


Now I add a new logger by clicking the green ‘+’ sign and specifying the log level and the name of the logger, which is actually the part of the class path the logger reacts on.
Add  Logger

Add Logger


this creates a new line in the logging.xml file looking like
Added Line

Added Line


Next I set up a new log handler in the logging.xml file which uses my DebugLogger class as formatter. Together with the log handler I specify the parameters which configure the output format of the string. The DebugLogger is not used directly, but instead a wrapper class WLSConsoleFormatter used which specifies default parameter set to the DebugFormatter. This way you can omit the parameters in the setup. Below is the resulting log handler entry in the logging.xml file:
        <log_handler name='blog-console-handler'
                     class='de.hahn.blog.consoleformatter.logger.BlogConsoleHandler' level='ALL'
                     encoding='UTF-8'>
            <property name='formatStyle' value='tnlcm'/>
            <property name='formatter'
                      value='de.hahn.blog.consoleformatter.logger.WLSConsoleFormatter'/>
        </log_handler>

To add this you need to change to the source view for the logging.xml file.
Finally I change the added logger to use the new handler
        <logger name='de' level='TRACE:1' useParentHandlers='false'>
            <handler name='blog-console-handler'/>
            <handler name="odl-handler"/>
        </logger>

I have to set the useParentHandlers to false to prevent that the messages get printed multiple times. To be able to analyze the messages with the log analyzer I add the ODL handler too. Now all log messages are printed to the console and to the ODL logger.

Now that the logger are setup in the logging.xml all I need to do is to make the classes available to the WLS instance. For this I build a jar from the project and put the resulting BlogConsoleFormatter.jar in a folder where WLS picks it up while starting. There a a couple of folder, but I choose <ide.system.dir>/DefaultDomain/lib folder. ide.system.dir is also known as the systemfolder of your JDeveloper installation. If you don't know where to find it check this blog. You can either copy the jar into the folder or setup the deployment profile to generate the jar in this folder.

Sample Oiutout

Sample Oiutout

The picture above show a small code sample with the generated output from DebugFormatter. As you see the log lines are marked as links. If you click on such a line you see that you are transfered to the code location of the message.

You can download the source code for the BlogLogConsoleFormatter.zip and a BlogPopupRegion.zip using the ADFLogger to generate messages in different log levels. After downloading the files you need to remove the ‘.doc’ suffix and rename them to ‘.zip’ as the files are normal zip files.
The sample workspaces are developed with JDeveloper 11.1.2.0.0, BlogPopupRegion uses the HR schema as DB connection.

28. August 2011

Remove Automatic Component Bindings

The last couple of day I spend some time investigating the ‘Automatic Component Binding’ feature. A code review I did lately showed that about 40% of the jspx pages of one project (about 60 pages in total) had automatic component binding on. As each page thus have a bean defined where the ui components are bound to, the project also contains a lot of beans. The beans are generated automatically and in this case don’t do anything but eat memory.

So two questions came up:
1) Why where automatic component binding on in so many pages, as we don’t use this feature?
2) How to get rid of the bindings and the (for us) useless beans?

This blog entry answers the second question and at least gives one hint for the first one. Lets start with the second question.

Reading the documentation Oracle® Fusion Middleware Web User Interface Developer’s Guide for Oracle Application Development Framework shows how to turn on/off the automatic component binding via JDeveloper for a page or fragment

Automatic Component Binding On/Off

Automatic Component Binding On/Off


If you turn the automatic binding on you’ll notice a comment line in your jsxp file

</f:view>
  <!--oracle-jdev-comment:auto-binding-backing-bean-name:backing_view11-->
</jsp:root>

This entry in the file triggers the automatic binding. Removing it has the same effect as turning the feature off in the above dialog.
So, as the doc stated, turning the automatic binding off only has an effect for components which are put onto the page in the future. If your page contains e.g. one or more forms, there are many components which are bound needlessly to a bean. It’s an error prone task to go through the source and remove all the bindings properties by hand.
JDeveloper allows us to use regular expressions in search and replace operations (even in search and replace in files). Looking to the source of the jspx page reveals

<f:view>
    <af:document id="d2" binding="#{backingBeanScope.ffff.d2}">
      <af:messages id="m2" binding="#{backingBeanScope.ffff.m2}"/>
      <af:form id="f2" binding="#{backingBeanScope.ffff.f2}">
        <af:panelStretchLayout topHeight="50px" id="psl2"
                              binding="#{backingBeanScope.ffff.psl2}">

that the automatic bindings all are looking like ‘binding=”#{backingBeanScope.ffff.<id>’, so we only need a regular expression looking for this string and replace it with nothing.
Replace Dialog

Replace Dialog


Running the dialog above shows that the expression finds the desired targets
Running Replace

Running Replace


After all references to the bean have been deleted, we can simply delete the bean itself. This concludes the answer to the second question.

The answer to the first question is not that easy to give. First of all I found out, that if you once turned the automatic component binding on, it stays on for all other pages you put into the same task flow. It may stay on for all pages, but I couldn’t confirm this in all cases. At some time a developer turned this feature on in the dialog you see when you create a new page (or fragment) in the bounded task flow

Create Page Dialog

Create Page Dialog


You have to click the ‘+’ sign by ‘Page Implementation’ to see the option. The thing is, the next time you create a new page the ‘Page Implementation’ is disclosed and you have to open it to see the current state. As I mentioned before, the option keeps its setting in the task flow. This answers the question of how we end up with so many pages using this feature. A developer turned this on for some reason and all pages added to the task flow later on inherited the behavior.
One interesting thing to note is, that you don’t see the ‘Bindings’ property for components, if you have the automatic component binding turned on
Bindings visible - Automatic Component Binding Off

Bindings visible - Automatic Component Binding Off


Binding invisible - Automatic Component Bindings On

Binding invisible - Automatic Component Bindings On

A summery of this is that you should only use the ‘Automatic Component Binding’ feature if you really need it. If you turn it on, make sure to check its status often and turn it off when not needed.

13. August 2011

How to find and reset the system11.x.x.x folder for a JDeveloper installation

Filed under: JDeveloper,Konfiguration — Timo Hahn @ 20:20
Tags: , ,

Lately users on the OTN forum asking how to change the system configurations or re install a specific version of JDeveloper when some undefined error persists.

Often the questions can be answered by rename or delete the system11.1.x.x.x folder which holds the system configuration and the integrated Weblogic Server (WLS) in a sub directory (DefaultDomain). If the problem only affects the integrated WLS you can just delete the DefaultDomain folder. The next time you run or debug an application the WLS DefaultDomain will be recreated.
The same is true for the system11.x.x.x folder with one difference. When JDeveloper detects an other system11.x.x.x folder on your system, it asks you if you want to migrate from the other version. In this dialog you can select or search (if you click the magnifying glass) a version to migrate from. You can force the dialog to appear if you start JDeveloper with the option ‘-migrate’ from a command shell.

Systemfolder11.1.1.4.0JDeveloper Migrate

Migrate system folder

You should be careful with the migration as it tends to migrate any error too. So if you have to delete the system11.x.x.x folder because of an error, you should first rename the folder, answer the dialog with ‘No’ and see if the problem is solved. Then you can delete the freshly created system11.x.x.x folder and try again with migrating from the renamed folder. If you are lucky the error will not be migrated. After any such action you should check the preferences again, as all changes you made have been erased.

By default JDeveloper put the system11.x.x.x folder in the “USER_HOME\AppData\Roaming\JDeveloper\” Folder (windows), as long as you did not specify an other location by changing an environment variable or changing the jdev.boot file.

#
# The ide.user.dir.var specifies the name of the environment variable
# that points to the root directory for user files.  The system and
# mywork directories will be created there.  If not defined, the IDE
# product will use its base directory as the user directory.
#
ide.user.dir.var = JDEV_USER_HOME,JDEV_USER_DIR
ide.user.dir = C:/Oracle/Middleware/jdeveloper/system

or specify the it as startup parameter
<path_to_jdev_install>\jdeveloper\jdeveloper.exe -J-Dide.user.dir=c:\JDeveloper\11.1.1.4

I find it helpful to use non-default locations for the JDeveloper user directory (which will contain the system.x.y.z folder) – in fact I find it so helpful, that I usually have several launcher shortcuts for the same version of JDeveloper pointing to different user directories (instead of specifying it in jdev.boot).
However, if you have many different launcher shortcuts I sometimes loose track which I’m currently running.

Well, there are a couple of ways to find out the location from within JDeveloper:
1) When you start an application in the internal WLS you get the path in the log window as part of the deployment messages

<13.08.2011 15:41 Uhr MESZ> <Notice> <WebLogicServer> <BEA-000360> <Server started in RUNNING mode> 
IntegratedWebLogicServer startup time: 26690 ms.
IntegratedWebLogicServer started.
[Running application xxyyzz on Server Instance IntegratedWebLogicServer...] 
[03:41:44 PM] ----  Deployment started.  ----
[03:41:44 PM] Target platform is  (Weblogic 10.3).
[03:41:45 PM] Retrieving existing application information
[03:41:45 PM] Running dependency analysis...
[03:41:45 PM] Deploying 2 profiles...
[03:41:47 PM] Wrote Web Application Module to P:\jdeveloper\system\system11.1.1.4.37.59.23\o.j2ee\drs\xxyyzz\xxyyzzViewControllerWebApp.war
[03:41:48 PM] Wrote Enterprise Application Module to P:\jdeveloper\system\system11.1.1.4.37.59.23\o.j2ee\drs\xxyyzz
[03:41:48 PM] Deploying Application..

2) you open the menu ‘Help’->’About’ and select the ‘Properties’ tab. Depending on the version you find multiple entries in the properties section.

Systemfolder11.1.1.4.0JDeveloper

System folder JDeveloper 11.1.1.4.0


and for JDeveloper 11.1.2.0.0
Systemfolder11.1.2JDeveloper

System folder JDeveloper 11.1.2

8. July 2011

JDev: Always Test Your App with ApplicationModule Pooling turned off

In the last couple of weeks I saw a couple of question which mentioned a sporadic misbehavior of the application under different circumstances. In the end they could be answered:

“Your application has not been tested with application module pooling turned off”

Whenever you encounter a sporadic misbehavior of the application under different circumstances, this should ring a bell. Most developers came across a situation like this when programming ADF applications. At some point the application does not react normal or throws exceptions. The errors are not reproducible (most of the times) and you only see them on the production server (never on the developer machine).

The first time I came across this problem it took me about a week to figure it out and solve it. Basically the problem has been private data (stored with the session) which is part of the application module and is stored in the user data hash map. This is not a problem as long as you can guarantee that each user always works with the same application module. This is the case when you test run your application on the developers machine (you are the only user and the application module pool always returns the same application module to the client). On a production server where more then one user uses the application at the same time, the application may be forced to reuse an application module which was formally used by a different user. At this point application module pooling take over.

The general algorithm used is that the application module pool has a number of application module available to use. If more requests arrive the pool generates the additional module until a high water mark is reached. Further requests getting rejected. Currently not used modules are given back to the pool and are available for the next request. The pool tries to return the same application module as long as it’s available to the same session for subsequent requests. If it is not available it uses a currently available module stores the current status of the module into a store (DB or file), clears the module from all information and reconstructs the state from the other session from saved state information. Once the application module is restored you can’t distinguish if it’s a new application module or a reused one. This way your application don’t need an module for each user request, but it shares the available modules between the requests, saving lots of resources.

All this can be read about here 43.2 Introduction to Fusion Web Application State Management.

After this more theoretical prologue, lets do a practical project (workspace for JDev 11.1.2 available, see end of article). To make it as simple as possible, but still useful for anybody running into problems with activation/passivation, we use the HR schema and try to emulate a scenario where a user only sees employee data which depends on a department number. This department number should be set in the application module and be accessible for all queries. In a real world scenario this information is connected to the login of a user and stored in a central place. In the sample we use the user data of the application module to store the number.
The applications start page (I do spare the login part) has a af:query panel to select employees which might be filtered by their last name. As there is no login I added a field to enter the department number which should be used to further filter the result set.The Web UI lokke like

Test app UITest Application UI

As you see there is an input field for the last name, in the bottom era an input field to insert the department number and an other panel to retrieve the currently set department number from the application module.
Lets have a look at the service method to get/set the department number and how it is stored:

    private static final String PRIVATEDATA = "privData";

    public void setPrivateToUserData(String aVal) {
        mLogger.info("Set PrivData:" + aVal);
        if (aVal == null)
            return;

        Session lSession = getSession();
        if (lSession == null) {
            mLogger.warning("getSession returned null!");
            return;
        }
        Hashtable lHashtable = lSession.getUserData();
        if (lHashtable == null) {
            mLogger.warning("getUserData returned null!");
            return;
        }
        lHashtable.put(PRIVATEDATA, aVal);
    }

    public String getPrivateToUserData() {
        Session lSession = getSession();
        if (lSession == null) {
            mLogger.warning("getSession returned null!");
            return null;
        }
        Hashtable lHashtable = lSession.getUserData();
        if (lHashtable == null) {
            mLogger.warning("getUserData returned null!");
            return null;
        }
        String lData = (String) lHashtable.get(PRIVATEDATA);
        mLogger.info("Get PrivData: " + lData);
        return lData;
    }

As you see the string from the UI is stored and retrieved under the key PRIVATEDATA = “privData” in the userData hash map of the application module. This is the place to store data for the current user session (Storing Information About the Current User Session)
The configuration of the application module is the default you see after generating a ‘Fusion Web Application’.
ApplicationModule Default Configuration

ApplicationModule Default Configuration


As you can see ‘Application Module Pooling’ is on. When we run the application, set the department number to e.g. 30, send the data to the AM and hit the search button in the query panel we see
Pooling On

Pooling On


You can hit the edit button in a row to edit the employee and come back to the page and see the application running as expected.
Now, we switch ‘Application Module Pooling’ off and run again:
Application Module Pooling Off

Application Module Pooling Off


Doing the same actions as earlier it look like the application does not see the department number at all:
Application Module Pooling Off

Application Module Pooling Off


Even if you set the department number and directly hit the ‘Get User Data’ button you’ll don’t get the department number back.

The reason for this behavior is that we store the department number in the user data hash map which is NOT passivated when the application module is given back to the pool and given to an other requester. This happens every time you go the the server when am pooling is switched off.
What we need to to is to passivate the session user data together with the other state data stored by the framework and load it back when the AM is requested the next time (when it gets activated again). To do this we have to overwrite two methodes in the ApplicationModuleImpl class.

    @Override
    protected void activateState(Element aElement) {
        super.activateState(aElement);
        mLogger.info("++++++++++ activateState");

        Hashtable lData = getSession().getUserData();
        if (aElement != null) {
            // 1. Search the element for any <PrivData> elements
            NodeList nl = aElement.getElementsByTagName(PRIVATEDATA);
            if (nl != null) {
                // 2. If any found, loop over the nodes found
                for (int i = 0, length = nl.getLength(); i < length; i++) {
                    // 3. Get first child node of the <PrivData> element
                    Node child = nl.item(i).getFirstChild();
                    if (child != null) {
                        // 4. Set the data value to the user data hashmap
                        String lDataString = child.getNodeValue();
                        String[] lSplitkeyval = lDataString.split(";");
                        for (int ii = 0; ii < lSplitkeyval.length; ii++) {
                            mLogger.fine("..."+lSplitkeyval[ii]);
                            String[] lSplit = lSplitkeyval[ii].split("=");
                            lData.put(lSplit[0], lSplit[1]);
                        }
                        break;
                    }
                }
            }
        }
    }


    @Override
    protected void passivateState(Document aDocument, Element aElement) {
        super.passivateState(aDocument, aElement);
        mLogger.info("---------- passivateState");

        // 1. Retrieve the value of the user data to save and build a string representation
        Session lSession = getSession();
        Hashtable lData = lSession.getUserData();
        String lDataString = "";
        Set<String> keyset = lData.keySet();
        if (!keyset.isEmpty()) {
            Iterator<String> keys = keyset.iterator();
            while (keys.hasNext()) {
                String key = keys.next();
                mLogger.fine("..."+key + "=" + lData.get(key));
                lDataString += key + "=" + lData.get(key) + ";";
            }
        }

        // 2. Create an XML element to contain the value
        Node node = aDocument.createElement(PRIVATEDATA);
        // 3. Create an XML text node to represent the value
        Node cNode = aDocument.createTextNode(lDataString);
        // 4. Append the text node as a child of the element
        node.appendChild(cNode);
        // 5. Append the element to the parent element passed in
        aElement.appendChild(node);
    }

The passivateState method gets a Document and an Element as parameter. After calling super() to let the framework do its work, we get the user data hash map and store each key-value pair in a string which is then appended as a node to the element we got as parameter. In a real world application I would use a java to XML serialization tool like XStream which is capable to store more complex data.
The activateState method gets an Element as parameter which we search for the node we save when passivateState was called and restore the user data hash map.

After putting the two methods in the ApplicationModuleImpl class (the one you get when you create the java classes for an application module) the application run OK again, application module pooling still turned off.

When you examine the sample workspace which you can get here BlogActivatePassivateSample_V1.zip (remove the ‘.doc’ extension after downloading the workspace!) you’ll notice, that EmployeesViewImpl class too have the two methods to store private data which is not automatically saved by the framework. Further there are log messages throughout the code to let you follow the action in the log window.

As you see it’s essential to test an application with application module pooling turned off to find activation/passivation errors before the application goes to production.

29. June 2011

Follow up: Upgrading WLS 10.3.5 with ADF Runtime 11.1.2.0.0 (Sherman Patch)

Since I published the article Upgrading WLS 10.3.5 with ADF Runtime 11.1.2.0.0 (Sherman Patch) and filing a SR about the documentation error, Oracle has put up a note in MOS (Note 1328698.1 “How To Install the ADF Runtime Libraries 11g Release 2 (11.1.2.0.0) in WebLogic Sever 10.3.5″) to clarify how to upgrade your WLS server.
In short you have to install two patches (12611176 and 12556632) before running the “upgradeADF(‘YOUR_DOMAIN_HOME’)” wlst command from ‘/oracle_common/common/bin/’.
Great, this could have saved my last weekend…

25. June 2011

Upgrading WLS 10.3.5 with ADF Runtime 11.1.2.0.0 (Sherman Patch)

A couple of weeks ago Oracle released JDeveloper 11.1.2.0.0 with many new features we all waited for.
Great news … but wait, what to do with your running test, QS and production environment. As usual I assumed a new WLS to use with the new JDev. However, this time Oracle did not ship a new WLS but olny a patch (patch 12611176), which is only available if you have a valid support contract. This patch upgrades an existing WLS 10.3.5 with the new ADF Runtime 11.1.2.0.0.
We are using Windows 7 64bit for our development PC and a Linux box for the WLS. Currently we are on jdev 11.1.1.4.0 and WLS 10.3.4. The task to do is the upgrade to 11.1.2.0.0. Here are the steps:

  1. update WLS 10.3.4 to WLS 10.3.5 (or do a fresh install if you like, doesn’t take more time). This is necessary as the patch requires WLS 10.3.5
  2. install ADF Runtime 11.1.1.5.0 on the WLS 10.3.5
  3. check the WLS 10.3.5 installation using JDev 11.1.1.5.0, check if Enterprise Manager (EM) is running
  4. load patch 12611176 from mos and read the instructions how to apply the patch
  5. apply the patch
  6. test the patch installation using JDev 11.1.2.0.0, check if EM is running

This blog entry deals manly with the last two point in the list. The other points are documented well and it shouldn’t be a problem to do them.
After loading the patch and reading the instructions from the patch file, I installed the patch. This all was pretty straight forward, installation was OK.
After starting the WLS I noticed that the EM was not running. A look into the AdminSever log showed

         Stacktrace

A close look at the stacktrace shows a ClassNotFoundException. A search for the missing class reveals that it’s from the A JSF2.0 library

         Search for missing class

This clearly suggests that the new ADF runtime libs are not present in the WLS 10.3.5. Well, John Stegeman mentioned in a twitter entry that he too had the problem that the EM did not start after upgrading to 11.1.2.0.0 and filed a SR for this (this resulted in Bug 12691349). At the time I testes this the bug was not jet published. So I tried many different ways to install the patch and get EM working which all resulted in the above stacktrace:

  • update WLS 10.3.4 to WLS 10.3.5; install ADF Runtime 11.1.1.1.5 with EM installed; install patch
  • update WLS 10.3.4 to WLS 10.3.5; install ADF Runtime 11.1.1.1.5 without EM installed; install patch; install EM
  • Fresh install of WLS 10.3.5; install ADF Runtime 11.1.1.1.5 with EM installed; install patch
  • Fresh install of WLS 10.3.5; install ADF Runtime 11.1.1.1.5 without EM installed; install patch; install EM

After rereading all available information about how to apply the patch again and the now available bug on MOS, I noticed one difference. The ‘README.TXT’ for the patch, after which I applied the patch, did not mention the need of executing a wlst command ‘upgradeADF’. The bug on MOS stated calling the ‘upgradeADF’ command as a possible cause of the bug.
The information about the command is only given in the ‘Release Notes for 11.1.2.0.0′ in the ‘Deployment’ section.

In the end I used the following method: fresh install of WLS 10.3.5; install ADF Runtime 11.1.1.1.5 with EM installed; install patch
OK, so lets execute the ‘upgradeADF’ command. Here you have to be careful which wlst installation you use for the command.
The WLS server has it’s own wlst command interpreter installed at ‘$MW_HOME/wlserver_10.3/common/bin/wlst.sh’ whereas the patch installed a second on at ‘$MW_HOME/oracel_common/common/bin/wlst.sh’.
Using the first will throw errors like you see in the next picture:

         Error running wlst from false path

After running the wlst command ‘upgradeADF’ from the correct path ‘$MW_HOME/oracel_common/common/bin/wlst.sh’ and restarting all servers the result look like:

         Running WLS 10.3.5 with Sherman Patch

As you can see the EM is up and running. Note also that two JSF versions are running (1.2 and 2.0).

It looks like the bug John posted is dependent on the environment, as he uses a WIN 7 64bit installation whereas I’m using a Linux box. Still I would like Oracle to make clear in the patch documentation ‘README.TXT’ that you have to run ‘upgradeADF’ from the right location to get the patch installed properly.

31. March 2008

Contentcompression für CSS abschalten

Filed under: JDev11TP3,Konfiguration — Timo Hahn @ 09:09

Beim Erstellen von eigenen Skins für JD11 kommt man schnell an den Punkt, wo einem nicht mehr klar ist, warum die von einem Skin betroffenen Elemente sich nicht so darstellen, wie man es gewünscht hat.

Sieht man sich den Quellcode der erzeugten CSS Infromationen der Seiten an stolpert man über kryptische Namen, die bei der Erzeugung der Seiten angelegt werden, um die CSS-Infos (speichertechnisch) klein zu halten.

.AFInstructionText, .x0, .AFFieldText, .x6, .xk, .xl, .xm, .x23, .x24, .x2d, .x2f, .x2h, .x1u.x2n .x25, .x1u.p_AFDisabled.x2n .x25, .x1u.x2p .x25, .x1u.x2q .x25, .x1u.x2r .x25, .x1u.x2s .x25, .x22.x2n .x24, .x22.p_AFDisabled.x2n .x24, .x22.x2p .x24, .x22.x2q .x24, .x22.x2r .x24, .x22.x2s .x24, .x1t.x2n .x26, .x1t.p_AFDisabled.x2n .x26, .x1t.x2p .x26, .AFFieldTextLTR, .x94, .AFPhoneFieldText, .x96, .AFPostalCodeFieldText, .x98, .AFAddressFieldText, .x9a, .PortletSubHeaderText, .xbz, .PortletText1, .xc0, .PortletText2, .xc1, .PortletText3, .xc2, .PortletText4, .xc3, .portlet-font, .xc4, .portlet-msg-info, .xc6, .portlet-form-input-field, .xcn, .portlet-form-field, .xcs {
color:#000000;
font-family:Arial,Helvetica,sans-serif;
font-size:12px;
font-weight:normal;
}
.AFInstructionTextDisabled, .x1, .AFFieldTextDisabled, .x7, .x1u.p_AFDisabled.x2p .x25, .x1u.p_AFDisabled.x2q .x25, .x1u.p_AFDisabled.x2r .x25, .x1u.p_AFDisabled.x2s .x25, .x22.p_AFDisabled.x2p .x24, .x22.p_AFDisabled.x2q .x24, .x22.p_AFDisabled.x2r .x24, .x22.p_AFDisabled.x2s .x24, .x1t.p_AFDisabled.x2p .x26, .x61, .p_InContextBrandingText, .x8r, .AFFieldTextLTRDisabled, .x95, .AFPhoneFieldTextDisabled, .x97, .AFPostalCodeFieldTextDisabled, .x99, .AFAddressFieldTextDisabled, .x9b, .OraHGridNavRowInactiveLink, .xa5, .OraNavBarInactiveLink, .xac, .portlet-font-dim, .xc5 {
color:#7E807A;
font-family:Arial,Helvetica,sans-serif;
font-size:12px;
font-weight:normal;
}
.AFDataText, .x2, .PortletHeaderText, .xbs {
color:#000000;
font-family:Arial,Helvetica,sans-serif;
font-size:12px;
font-weight:bold;
}

Leider werden so einige zusammenhänge ebenfalls verschleiert. Unter JD10.1.3 konnte diese Komprimierung durch einen Eintrag in der web.xml abgeschaltet werden:


<context-param>

<paramname>oracle.adfinternal.view.faces.DISABLE_CONTENT_COMPRESSION</param-name>
<param-value>true</param-value>

</context-param>

Unter JD11 hat sich der Syntax leicht geändert (siehe forums.oracle.com/forums/thread.jspa?messageID=2432817&tstart=0#2432817) und lautet nun


<context-param>

<param-name>org.apache.myfaces.trinidad.DISABLE_CONTENT_COMPRESSION</param-name>
<param-value>true</param-value>

</context-param>

Hier das Resultat (wie oben mit der neuen Einstellung):

.AFInstructionText, .AFFieldText, .af_outputText, .af_outputFormatted, .af_outputDocument, .af_inputChoice_content, .af_inputChoice_content-input, .af_selectManyCheckbox_content, .af_selectOneChoice_content, .af_selectOneRadio_content, .af_inputText.AFFieldTextMarker .af_inputText_content, .af_inputText.p_AFDisabled.AFFieldTextMarker .af_inputText_content, .af_inputText.AFFieldTextLTRMarker .af_inputText_content, .af_inputText.AFPhoneFieldTextMarker .af_inputText_content, .af_inputText.AFPostalCodeFieldTextMarker .af_inputText_content, .af_inputText.AFAddressFieldTextMarker .af_inputText_content, .af_inputChoice.AFFieldTextMarker .af_inputChoice_content-input, .af_inputChoice.p_AFDisabled.AFFieldTextMarker .af_inputChoice_content-input, .af_inputChoice.AFFieldTextLTRMarker .af_inputChoice_content-input, .af_inputChoice.AFPhoneFieldTextMarker .af_inputChoice_content-input, .af_inputChoice.AFPostalCodeFieldTextMarker .af_inputChoice_content-input, .af_inputChoice.AFAddressFieldTextMarker .af_inputChoice_content-input, .af_inputNumberSpinbox.AFFieldTextMarker .af_inputNumberSpinbox_content, .af_inputNumberSpinbox.p_AFDisabled.AFFieldTextMarker .af_inputNumberSpinbox_content, .af_inputNumberSpinbox.AFFieldTextLTRMarker .af_inputNumberSpinbox_content, .AFFieldTextLTR, .AFPhoneFieldText, .AFPostalCodeFieldText, .AFAddressFieldText, .PortletSubHeaderText, .PortletText1, .PortletText2, .PortletText3, .PortletText4, .portlet-font, .portlet-msg-info, .portlet-form-input-field, .portlet-form-field {
color:#000000;
font-family:Arial,Helvetica,sans-serif;
font-size:12px;
font-weight:normal;
}
.AFInstructionTextDisabled, .AFFieldTextDisabled, .af_inputText.p_AFDisabled.AFFieldTextLTRMarker .af_inputText_content, .af_inputText.p_AFDisabled.AFPhoneFieldTextMarker .af_inputText_content, .af_inputText.p_AFDisabled.AFPostalCodeFieldTextMarker .af_inputText_content, .af_inputText.p_AFDisabled.AFAddressFieldTextMarker .af_inputText_content, .af_inputChoice.p_AFDisabled.AFFieldTextLTRMarker .af_inputChoice_content-input, .af_inputChoice.p_AFDisabled.AFPhoneFieldTextMarker .af_inputChoice_content-input, .af_inputChoice.p_AFDisabled.AFPostalCodeFieldTextMarker .af_inputChoice_content-input, .af_inputChoice.p_AFDisabled.AFAddressFieldTextMarker .af_inputChoice_content-input, .af_inputNumberSpinbox.p_AFDisabled.AFFieldTextLTRMarker .af_inputNumberSpinbox_content, .af_menuButtons_text-disabled, .p_InContextBrandingText, .AFFieldTextLTRDisabled, .AFPhoneFieldTextDisabled, .AFPostalCodeFieldTextDisabled, .AFAddressFieldTextDisabled, .OraHGridNavRowInactiveLink, .OraNavBarInactiveLink, .portlet-font-dim {
color:#7E807A;
font-family:Arial,Helvetica,sans-serif;
font-size:12px;
font-weight:normal;
}
.AFDataText, .PortletHeaderText {
color:#000000;
font-family:Arial,Helvetica,sans-serif;
font-size:12px;
font-weight:bold;
}

Danke an Frank Nimphius für diese Info!

Damit gestaltet sich die Suche etwas einfacher.

5. March 2008

Embedded OC4J startet nicht mit FAILED_IN_CONFIG

Filed under: JDev11TP3,Konfiguration — Timo Hahn @ 09:09
Tags: , ,

Manchmal (die genauen Zusammenhänge habe ich noch nicht herausgefunden) startet der Embedded OC4J Container nicht mehr mit einem Fehler

SCHWERWIEGEND: Server exiting: ApplicationServer entered state FAILED_IN_CONFIG
der auf ein Problem mit der Authentifizierung hinweist. Das passiert auch dann, wenn keine Security verwendet wird. Bevor der Container mit dieser Meldung abbricht, hat er schon eine weitere Meldung ausgegeben:

05.03.2008 09:25:00 oracle.security.jps.internal.credstore.ssp.CsfWalletManager openWallet
SCHWERWIEGEND: Could not open wallet. null
java.io.IOException: Could not open wallet. null
at oracle.security.pki.OracleWallet.open(OracleWallet)
at oracle.security.jps.internal.credstore.ssp.CsfWalletManager.openWallet(CsfWalletManager.java:136)
at oracle.security.jps.internal.credstore.ssp.SspCredentialStore.(SspCredentialStore.java:139)
at oracle.security.jps.internal.credstore.ssp.SspCredentialStoreProvider.getInstance(SspCredentialStoreProvider.java:109)
at oracle.security.jps.internal.credstore.ssp.SspCredentialStoreProvider.getInstance(SspCredentialStoreProvider.java:47)
at oracle.security.jps.internal.core.runtime.ContextFactoryImpl.findServiceInstance(ContextFactoryImpl.java:139)
at oracle.security.jps.internal.core.runtime.ContextFactoryImpl.getContext(ContextFactoryImpl.java:170)
at oracle.security.jps.internal.core.runtime.ContextFactoryImpl.getContext(ContextFactoryImpl.java:191)
at oracle.security.jps.internal.core.runtime.JpsContextFactoryImpl.getContext(JpsContextFactoryImpl.java:129)
at oracle.security.jps.internal.core.runtime.JpsContextFactoryImpl.getContext(JpsContextFactoryImpl.java:124)
at oracle.security.jps.internal.policystore.PolicyUtil$1.run(PolicyUtil.java:590)
at oracle.security.jps.internal.policystore.PolicyUtil$1.run(PolicyUtil.java:585)
at java.security.AccessController.doPrivileged(Native Method)
at oracle.security.jps.internal.policystore.PolicyUtil.getDefaultPolicyStore(PolicyUtil.java:584)
at oracle.security.jps.internal.policystore.PolicyDelegationController.(PolicyDelegationController.java:244)
at oracle.security.jps.internal.policystore.PolicyDelegationController.(PolicyDelegationController.java:238)
at oracle.security.jps.internal.policystore.JavaPolicyProvider.(JavaPolicyProvider.java:103)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at java.lang.Class.newInstance0(Class.java:355)
at java.lang.Class.newInstance(Class.java:308)
at oracle.security.jazn.JAZNConfig.setJAASPolicyProvider(JAZNConfig.java:2054)
at oracle.security.jazn.JAZNConfig.setSecurityProperties(JAZNConfig.java:2130)
at oracle.security.jazn.JAZNConfig.setSecurityProperties(JAZNConfig.java:2149)
at com.evermind.server.OC4JServer.main(OC4JServer.java:420)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at oracle.classloader.util.MainClass.invoke(MainClass.java:128)
at oracle.oc4j.loader.boot.BootStrap.main(BootStrap.java:41)

Diese gibt den Grund an, nämlich dass die Wallet-Datei nicht geöffnet werden konnte. Ein blick ins Dateisystem ins Verzeichnis

[USERDIR]AnwendungsdatenJDevelopersystem11.1.1.0.22.47.96o.j2eeembedded-oc4jconfigoc4j-credstore

Bild

Zeigt, dass die Datei leer ist (0 KB).

Es gibt nun zwei Möglichkeiten das Problem zu lösen:

  1. Löschen des Verzeichnis embedded-oc4j aus dem oben genannten Pfad. Beim nächsten Start wird es dann neu mit Standardeinstellungen neu angelegt. Dabei gehen aber leider z.B. Änderungen an den Logging-Einstellungen verloren!
  2. man kopiert die Datei cwallet.sso aus dem aktuellen Projekt in das Verzeichnis. Im aktuellen Projekt findet sich die Datei meist im Verzeichnis [Workspacename]/src/META-INF, wobei [Workspacename] das Verzeichnis ist, in dem die *.jws des Projektes zu finden ist.
Next Page »

Theme: Rubric. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 67 other followers