Wednesday, June 30, 2010

Part 1: How to configure the Node Manager to start Admin and Managed Servers

Before you can use the Node Manager utility, you need to configure/verify the Node Manager. 
  • For this start the Admin Server as usual by running the <Middleware_home>\user_projects\domains\soa_domain\startWebLogic.cmd.
  • Go to Weblogic Console and navigate to Machines-->LocalMachine-->Configuration Tab-->Node Manager Tab. Specify the ListenAddress (where Node Manager will run) and ListenPort as per you installation. By default the port is 5556. Be sure to provide the exact URL/Host name in ListenAddress as localhost will disallow starting the servers from remote location. See below image.

  • Go to <Middleware_home>\wlserver_10.3\common\nodemanager\nodemanager.properties. Set StartScriptEnabled=true.
  • Start WLST from <Middleware_home>\wlserver_10.3\common\bin\wlst.cmd in a separate command prompt window. You can double click on the wlst.cmd also to start WLST.
  • Once WLST starts, connect to Admin Server from the WLST console. To connect type the connect() command on the WLST console and press Enter. Accept defaults or provide inputs as required. Once it connects successfully, the WLST prompt will change to wls:/mydomain/serverConfig>.
  • Now type nmEnroll(<Middleware_home>\user_projects\domains\soa_domain). This command enrolls the current machine with the Node Manager and creates some properties file (nm_password.properties,SerializedSystemIni.dat).
  • If the message displays as "Successfully enrolled this machine with the domain directory at", Enrollment is successful. 
  • Exit from the WLST console using the exit() command and shut down your Admin Server and Close the Browser Console window.
  • Node Manager is configured. Further, to start the Admin and Managed Servers from this Node Manager, refer to this post. 

Thursday, April 29, 2010

Client side Error Handling with validateRegExp on Decimal fields

There are undoubtedly more than one ways of handling the errors gracefully for your ADF inputText component. One of which is at the Model Layer using Validation at the Entity Objects the details of which can be seen here.
However, in some of the cases where we have an editable table dropped on the page and we need to provide the validation on all its fields, some of which are decimals, the various ways would be to use the various validators and converters as described here. However, this post describes 2 ways to handle the errors on the Decimal fields.

Note : To demonstrate the use of Decimal fields I've created a column Weight in the Employees table. Further I've created an Employees Entity Object, View Object and Application Module.


I also created a jspx page to Create/Update an Employee



Using the Validate Double Range :
Drag the validateDoubleRange validator from the Component Pallette under the JSF Core Menu and rop it under the inputText component. Remove ConvertNumber if any present. Just specify the range here as shown below.


At run time whenever an error occurs it shows the result in the following format.


However, the limitations of using this approach are :

  • You can not customize the message.
  • The Error messages are displayed after Submitting the page which involves a server call.

 Many times customers want client side validation messages in JavaScript alert boxes. The second approach demonstrates the same.

Using validateRegExp :
Validate Regular expression is a very efficient means to check for any format of the STRINGS. But unfortunately it can not be used for Numerical or Decimal data types. Even if you try to drop a validateRegExp validator under inputText, it works properly in case of errors but in case of correct value it throws an exception.



500 Internal Server Error
java.lang.IllegalArgumentException: 'value' is not of type java.lang.String. at oracle.adf.view.faces.validator.ValidatorUtils.assertIsString(ValidatorUtils.java:36) at oracle.adf.view.faces.validator.RegExpValidator.validate(RegExpValidator.java:103) at oracle.adf.view.faces.component.UIXEditableValue.validateValue(UIXEditableValue.java:378) at oracle.adf.view.faces.component.UIXEditableValue.validate(UIXEditableValue.java:206) at oracle.adf.view.faces.component.UIXEditableValue._executeValidate(UIXEditableValue.java:522) at oracle.adf.view.faces.component.UIXEditableValue.processValidators(UIXEditableValue.java:302) at oracle.adf.view.faces.component.ChildLoop$Validate.process(ChildLoop.java:67) at oracle.adf.view.faces.component.ChildLoop.runAlways(ChildLoop.java:39) at oracle.adf.view.faces.component.ChildLoop.runAlways(ChildLoop.java:30) at oracle.adf.view.faces.component.UIXColumn.processValidators(UIXColumn.java:70) at oracle.adf.view.faces.component.UIXCollection.processComponent(UIXCollection.java:822) at oracle.adf.view.faces.component.TableUtils$3.process(TableUtils.java:256) at ...

To remove this error, just change the data type of your attribute to String in the Entity Object as shown under. Please note the same Entity Object can be used for other View Objects also. Hence make sure that all the View Objects are in tact.


So everything is set. Just run the page now and see the output.


Friday, April 2, 2010

no cache policy header, USE_APPLICATION_VIEW_CACHE not working properly

Problem : 
When I try to open a dialog box from my  page, I get the following error.


Apr 2, 2010 12:24:22 PM oracle.webcache.adf.config.AFCConfigFactory getConfig
INFO: ADF Config did not find the AFC config 
Apr 2, 2010 12:24:22 PM oracle.webcache.adf.config.AFCConfigFactory getConfig
SEVERE: Error in config : Cannot locate config file. Using default values
Apr 2, 2010 12:24:22 PM oracle.webcache.adf.config.AFCConfigFactory getConfig
SEVERE: Error in config. Using default values
Apr 2, 2010 12:24:22 PM oracle.webcache.adf.filter.PageCachingProcessor getResponseFromCache
INFO: page (__ADFv__) cache miss
Apr 2, 2010 12:24:22 PM oracle.webcache.adf.filter.PageCachingProcessor isResponseCacheable
INFO: response not cacheable - no cache policy header
Apr 2, 2010 12:24:22 PM oracle.webcache.adf.filter.PageCachingProcessor getResponseFromCache
INFO: page (PPAPListDialog.jspx) cache miss
Apr 2, 2010 12:24:22 PM aam.tooling.managedbeans.LoggedUserInfo
INFO: In Logged User Info Bean...
Apr 2, 2010 12:24:22 PM oracle.webcache.adf.filter.PageCachingProcessor isResponseCacheable
INFO: response not cacheable - no cache policy header


Due to this error, the following things happen.

  • I keep on getting the Row Currency Error on navigating time and again to my dialog pages.
  • I have an attachment dialog with command link to save the attachment on user's system. It often refers to the firstly clicked attachment always even when I have clicked on the different link this time.
  • It does not update the dialog view properly. Sometimes newly added rows do not get displayed there.

Solution :
After a long study it was clear that it has something to do with the cache. But I just wondered where. Finally it was  USE_APPLICATION_VIEW_CACHE in the web.xml file. I set it to false and all the above mentioned errors went.
    <context-param>
        <param-name>oracle.adf.view.faces.USE_APPLICATION_VIEW_CACHE</param-name>
        <param-value>false</param-value>
    </context-param>
Although more information about USE_APPLICATION_VIEW_CACHE  can be found here but there is no reference that I could make why this be causing problem in my application. But still if you face the same problem (probably when it's a day before the UAT as in my case), you can give a thought to apply this solution.

Friday, February 26, 2010

Can not start Jdeveloper : Unable to create instance of Java Virtual Machine

I had not thought that Jdeveloper 10g may throw some error depending on my disk space even. When I tried to restart my Jdeveloper 10.1.3.3.41.57, it popped up an error message to me as shown below. 


When Jdeveloper starts it tried to allocate some some heap size from the disk space. If that space is not avilable this error is popped up.

The same can be easily resolved by changing the AddVMOption parameter value to the desired value.

Location : JDEV_HOME\jdev\bin\jdev.conf
Parameter : AddVMOption
Value : <Any valid disk space value in MB>

#
# Set the maximum heap to 512M
#
AddVMOption -Xmx1024M

If you have lot of available disk space it is better to have this heap size around 1024 MB to accelerate the context switching of Jdeveloper.

Sunday, January 31, 2010

Setting the current row of a view object with custom key programmatically

I came across a use-case where I needed to set the key of a View Object manually through the backing bean. Usually setCurrentRowWithKey() or setCurrentRowWithKeyValue() can be used to set the current row of a view object. But What if you don't know the exact key but part of it and you want to create the key yourself and set the current Row programmtically.  Well you can use the following function on click of a command button or customize it happily to put to any specific use...

    public String setNewRowKey() {
        // Get the iterator displayed on the Page
         FacesContext ctx = FacesContext.getCurrentInstance();
         Application app = ctx.getApplication();
         ValueBinding bind = app.createValueBinding("#{bindings}");
         DCIteratorBinding iter = ((DCBindingContainer) bind.getValue(ctx)).findIteratorBinding("DepartmentsEmployeeVOIterator");
         if (iter == null) {
           throw new RuntimeException("Iterator not found");
         }
         
         // Create the key manually. It requires providing all primary keys for all 
         // the Entity Objects included in the View Object
         Object [] keyValues = new Object[2];
         keyValues[0] = null;  // Any Department
         keyValues[1] = "114"; // Employee ID
         
         // find all the rows matching the above criteria using the RowSetIterator. 
         // You can also use the same to find rows matching any key criteria.
         Row [] rows = iter.getRowSetIterator().findByKey(new Key(keyValues), -1);
        
         if (rows.length > 0)  {
             // get the first row and its key and set current row of iterator with this key string
             iter.setCurrentRowWithKey(rows[0].getKey().toStringFormat(true));
         }
         
        return "navigation-rule";
    }




Tuesday, January 19, 2010

"AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 0

While trying to run Application Module in Jdeveloper 10.1.3.3, I got the following error.
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 0
at oracle.sql.NUMBER._fromLnxFmt(NUMBER.java:3199)
at oracle.sql.NUMBER.toString(NUMBER.java:761)
at oracle.sql.NUMBER.stringValue(NUMBER.java:2090)
at oracle.jbo.domain.Number.toString(Number.java:390)
at javax.swing.table.DefaultTableCellRenderer.setValue(DefaultTableCellRenderer.java:298)
at javax.swing.table.DefaultTableCellRenderer.getTableCellRendererComponentDefaultTableCellRenderer.java:190)
at javax.swing.JTable.prepareRenderer(JTable.java:3924)
at javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:2070)
at javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:1972)
at javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1895)
at javax.swing.plaf.ComponentUI.update(ComponentUI.java:142)
at javax.swing.JComponent.paintComponent(JComponent.java:742)
at javax.swing.JComponent.paint(JComponent.java:1005)
at javax.swing.JComponent.paintWithOffscreenBuffer(JComponent.java:4963)
at javax.swing.JComponent.paintDoubleBuffered(JComponent.java:4916)
at javax.swing.JComponent._paintImmediately(JComponent.java:4859)
at javax.swing.JComponent.paintImmediately(JComponent.java:4666)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:451)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:114)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
BC4J Tester exit code(0)

As a basic human nature, I searched on the internet to find out that it was a bug as reported here.
http://forums.oracle.com/forums/thread.jspa?messageID=1617924?

But the same was fixed in Jdeveloper 10.1.3.3. Then why did it bug me now. It was then I realized that I had synchronized my Entity Object with the database. I opened one of my entity object and was wondering to see the Type of one of the attributes as String although it was a Number, something similar to this.




So I just modified all the Attribute types according to the ones in the database and hurrah it was working fine.

Saturday, January 9, 2010

Clear values in Search form fields

I have designed a Search form to search for specific records based on search criteria. But once I have searched I want to clear the criteria fields to conduct a fresh search. There are 3 ways





1. Reset the bind parameters of the view objects by calling them in the bean that can be found at the below links.
http://forums.oracle.com/forums/thread.jspa?messageID=2563498#2563498 


http://forums.oracle.com/forums/thread.jspa?messageID=1579998#1579998 


http://radio.weblogs.com/0118231/2006/11/21.html


2. Use ResetButton to reset the form parameters. But it will reset the form fields’ values to the previous search criteria parameters.


3. The third way originates from the user experience. According to my experience users are least concerned about the VO bind parameters being refreshed or not, but what they actually want is to clear the form instantly and preferably with no server call that means on the client-side itself. The reason for the same is that all countries/clients/users do not have very fast internet as to virtually diminish the time taken to reset the form. Hence this method came up to clear the search form using Java Script. This way might not be suitable for all the situations and also does not replace the other two mentioned above but still it is very much efficient and helpful to provide the end-users pleasant experience.
All you have to do is follow the below 3 steps and it is done.
  • Change your search form to <af:form> instead of <h:form>. After this the form looks like this.
<af:form id="searchForm">
   <af:panelPage title="Clear Search Form Parameters Example">
   <af:panelForm>





   <af:inputText id="firstName" value="#{bindings.TheFirstName.inputValue}"    label="#{bindings.TheFirstName.label}" required="#{bindings.TheFirstName.mandatory}"  columns="#{bindings.TheFirstName.displayWidth}">
      <af:validator binding="#{bindings.TheFirstName.validator}"/>
   </af:inputText>
   <af:inputText id="salary" value="#{bindings.TheSalary.inputValue}"  label="#{bindings.TheSalary.label}" required="#{bindings.TheSalary.mandatory}" columns="#{bindings.TheSalary.displayWidth}">
   <af:validator binding="#{bindings.TheSalary.validator}"/>
  </af:inputText>
  • Create a Clear CommandButton as shown below and set the onClick property as clearAllFormFields() function.
<af:panelButtonBar>
   <af:commandButton actionListener="#{bindings.ExecuteWithParams.execute}" text="Search"  disabled="#{!bindings.ExecuteWithParams.enabled}"/>
   <af:commandButton text="Clear" onclick="return clearAllFormFields();"/>
</af:panelButtonBar>


  • Now add the scriptlet function in the jspx page as shown below.
<script type="text/javascript">
   function clearAllFormFields(){
      //check if the object is not null. The object will be null when it is not rendered on the page  or is disabled. 
      if(document.forms["searchForm"].elements["firstName"] != undefined)


     document.forms["searchForm"].elements["firstName"].value="";
     if(document.forms["searchForm"].elements["salary"] != undefined)
     document.forms["searchForm"].elements["salary"].value="";
     return false;
   }
</script>

And it is done. Now just test run the page.