Monday, October 8, 2012

ADF: Resolving random JBO-27122 and closed statement errors


Problem: 
  • Resolving random JBO-27122 and closed statement errors 
  • <java.sql.SQLException: Statement cancelled, probably by transaction timing out.

Resolution:

Fusion web applications are not compatible with data sources defined with the JDBC XA driver. When creating a data source on Oracle WebLogic Server, be sure to change the Fusion web application data source's JDBC driver from “Oracle's Driver (Thin XA)” to “Oracle's Driver (Thin)”. Because XA data sources close all cursors upon commit, random JBO-27122 and closed statement errors may result when running the Fusion web application with an XA data source. 

Reference: http://docs.oracle.com/cd/E24382_01/web.1112/e16182/deployment_topics.htm#ADFFD23083

Thursday, July 5, 2012

ADF: Rendering HTML code on page


Below are the ways to render HTML code on JSF page:
  • Using <af:outputText>
  • <af:outputText value="#{pageFlowScope.testbean.value}" id="ot1"
                   escape="false"/>
    
  • Using <af:richTextEditor>
  • <af:richTextEditor label="Label 1" id="rte1" readOnly="true"
                       value="#{pageFlowScope.testbean.value}"/>
where bean code is using "org.apache.commons.lang.StringEscapeUtils.unescapeHtml" API to render html code properly.
import org.apache.commons.lang.StringEscapeUtils;

public class testbean {
    public testbean() {
    }
    
    private String value = "&lt;object width="100" height="100" data="http://www.google.co.in/images/srpr/logo3w.png"&gt;&lt;/object&gt;";

    public void setValue(String value) {
        this.value = value;
    }

    public String getValue() {
        value = StringEscapeUtils.unescapeHtml(value);
        return value;
    }
}

Tuesday, May 8, 2012

ADF: Programmatic View Criteria


To define view criteria programmatically:
  • VO must contain the attributes which are to be added in where clause.
  • The following method is added in AMImpl java class & method is exposed via client interface.
import oracle.jbo.ViewCriteria;
import oracle.jbo.ViewCriteriaItem;
import oracle.jbo.ViewCriteriaRow;
import oracle.jbo.domain.Number;
...
...

public void filterEmployees(){
   ViewObjectImpl empVOImpl = getEmployeesView1();            
   ViewCriteria vc = empVOImpl.createViewCriteria();
   ViewCriteriaRow vcr = vc.createViewCriteriaRow();            
    
   //criteria for employee id
   ViewCriteriaItem vci1 = vcr.ensureCriteriaItem("JobId");
   vci1.setValue("SH_CLERK");

   //criteria for showing employees whose salary are more than 10000
   ViewCriteriaItem vci2 = vcr.ensureCriteriaItem("Salary");
   vci2.setOperator(">");
   vci2.setValue(new Number(2500));

   //criteria for department
   int[] deptIds = {50,100};
   ViewCriteriaItem vci3 = vcr.ensureCriteriaItem("DepartmentId");
   vci3.setOperator("IN");
   int i = 0;
   for(int deptId: deptIds){
     vci3.setValue(i++, new Number(deptId));
   }

   vc.addElement(vcr);
   empVOImpl.applyViewCriteria(vc);
   System.out.println("Query: " + empVOImpl.getQuery());
   empVOImpl.executeQuery();
}

Above implementation is showing three conditions:
  • Equal (JobId = "SH_CLERK")
  • Greater than (Salary > 2500)
  • IN (DepartmentId in (50,100))

ADF: Programmatically adding partial trigger/target


To refresh component programmatically:
  • Bind the component in bean. e.g.
<af:outputtext binding="#{pageFlowScope.BackingBean.outputText}" id="ot1" 
               value="outputText1">
</af:outputtext>

  • Wherever required use following API inside bean:
AdfFacesContext.getCurrentInstance().addPartialTarget(getOutputText());

Monday, May 7, 2012

ADF: Access attribute binding

import oracle.adf.model.BindingContext;
import oracle.adf.model.binding.DCBindingContainer;

import oracle.binding.AttributeBinding;
...
...
    DCBindingContainer bindings = 
        ((DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry());
    AttributeBinding attrBinding = 
        (AttributeBinding) bindings.getControlBinding("AttributeNameFromBindings");

    //get input value
    attrBinding.getInputValue();
    //get label
    attrBinding.getLabel();
Similiarly, we can cast bindings.getControlBinding("AttributeNameFromBindings") to:
  • JUCtrlListBinding: for getting value from list binding.

ADF: Access/Execute method binding


Below is the way to access/execute method binding from managed bean:
import oracle.adf.model.BindingContext;
import oracle.adf.model.binding.DCBindingContainer;

import oracle.binding.OperationBinding;
...
...
    DCBindingContainer bindings = 
        ((DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry());
    OperationBinding operationBinding = 
        bindings.getOperationBinding("MethodNameFromBindings");
    
    //passing value into method arguments
    operationBinding.getParamsMap().put("ArgumentName",value);
    operationBinding.execute();
    
    //getting return value from method
    operationBinding.getResult();

Friday, May 4, 2012

ADF: Programmatic Redirection


Below is the way to programmatic navigate to other view:
    public void redirectToSelf(String viewId) {
        FacesContext fctx = FacesContext.getCurrentInstance();
        ExternalContext ectx = fctx.getExternalContext();
        ControllerContext controllerCtx = null;
        controllerCtx = ControllerContext.getInstance();
        String activityURL = controllerCtx.getGlobalViewActivityURL(viewId);
        try {
            ectx.redirect(activityURL);
        } catch (IOException e) {
            //Can't redirect
            e.printStackTrace();
        }
    }
Note: For executing "controllerCtx.getGlobalViewActivityURL", the view must be present in adfc-config.xml .

ADF: Programmatic Logging out


Below are the ways to programmatically logging out the user:
  • First Approach
FacesContext fc = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession)fc.getExternalContext().getSession(false);
session.invalidate();

try {
   fc.getExternalContext().redirect("faces/welcome");
} catch (IOException e) {
   e.printStackTrace();
}
  • Second Approach
ExternalContext ectx = FacesContext.getCurrentInstance().getExternalContext();
StringBuilder logoutURL = new StringBuilder(ectx.getRequestContextPath());

logoutURL.append("/adfAuthentication?logout=true&end_url=");
logoutURL.append("/faces/welcome");

try {
   ectx.redirect(logoutURL.toString());
} catch (IOException e) {
   adfLogger.warning("Error logging off");
   e.printStackTrace();
}

ADF: Programmatic Navigation


Below is the API that can be used to programmatically navigate to next/new activity of taskflow:
FacesContext facesContext = FacesContext.getCurrentInstance();
NavigationHandler navHandler = facesContext.getApplication().getNavigationHandler();
navHandler.handleNavigation(facesContext, null, "controlFlowCaseName");
API javadoc:
Package: javax.faces.application.NavigationHandler

public abstract void handleNavigation(FacesContext context, String fromAction, String outcome)

Perform navigation processing based on the state information in the specified FacesContext,
plus the outcome string returned by an executed application action.

Parameters:
context - The FacesContext for the current request
fromAction - The action binding expression that was evaluated to retrieve the specified outcome,
or null if the outcome was acquired by some other means
outcome - The logical outcome returned by a previous invoked application action (which may be null)
Throws: NullPointerException - if context is null

Thursday, May 3, 2012

ADF: Tree using managed bean


For creating ADF tree component using managed bean:
  • Create a object representing tree item & this will have references to its children.
public class TreeNode {
    public TreeNode() {
        super();
    }    
    public TreeNode(int id, String name){
        this.id = id;
        this.name = name;
    }
    
    private int id;
    private String name;
    private List<TreeNode> childNodes;

    ...with getters & setters...
}
  • Create and Populate objects representing tree item with data, i did that in constructor of managed bean. Managed bean can be registered in either adfc-config.xml or faces-config.xml.
    public TreeBackingBean() {
        rootNode = new TreeNode(1, "World");
        TreeNode node2 = new TreeNode(2, "USA");
        TreeNode node3 = new TreeNode(3, "India");
        TreeNode node4 = new TreeNode(4, "Los Angeles");
        TreeNode node5 = new TreeNode(5, "Delhi");
        TreeNode node6 = new TreeNode(6, "Mumbai");
        
        List<TreeNode> l1 = new ArrayList<TreeNode>();
        l1.add(node2);
        l1.add(node3);
        rootNode.setChildNodes(l1);
        
        List<TreeNode> l2 = new ArrayList<TreeNode>();
        l2.add(node4);
        node2.setChildNodes(l2);
        
        List<TreeNode> l3 = new ArrayList<TreeNode>();
        l3.add(node5);
        l3.add(node6);
        node3.setChildNodes(l3);
    }
  • Use following API to create TreeModel:
org.apache.myfaces.trinidad.model.TreeModel treeModel = 
new org.apache.myfaces.trinidad.model.ChildPropertyTreeModel(objectOfNodeTreeItem, "childNodes");
Note: The second argument is String matching the property of objectOfTreeItem representing references to its children. If the name is mismatched, you will end up with "javax.el.PropertyNotFoundException" error.

  • Bind the value of <af:tree> from page to above "treeModel" instance. Final result be like:
The sample application can be downloaded from https://rapidshare.com/files/4090558697/TreeFromBeanExample.zip

Tuesday, May 1, 2012

ADF: Ghost Labels

To have Ghost Labels on ADF pages:
    <af:document id="d1">
      <af:messages id="m1"/>
      <f:facet name="metaContainer">
        <af:resource type="javascript" source="/jquery-1.7.min.js"/>
        <af:resource type="javascript" source="/label-in-field.js"/>
        <af:resource type="css">
            .text-label {
                color: #cdcdcd;
                font-weight: bold; 
            }
        </af:resource>
      </f:facet>
      <af:form id="f1">
        <af:panelStretchLayout id="psl1">
          <f:facet name="center">
            <af:panelGroupLayout layout="scroll" id="pgl1" halign="center">
              <af:inputText label="Username" id="it1" simple="true"
                            required="true"/>
              <af:inputText label="Password" id="it2" secret="true"
                            simple="true" autoTab="true"/>
              <af:selectOneChoice value="#{bindings.DepartmentId.inputValue}"
                                  id="soc1">
                <f:selectItems value="#{bindings.DepartmentId.items}" id="si1"/>
              </af:selectOneChoice>
            </af:panelGroupLayout>
            <!-- id="af_one_column_stretched"   -->
          </f:facet>
        </af:panelStretchLayout>
      </af:form>
      <af:clientListener type="load" method="onPageLoad"/>
    </af:document>
Final Result will be like:
Note: http://lspatil25.blogspot.in/2012/05/adf-make-findcomponentbyabsoluteid-js.html

ADF: Make findComponentByAbsoluteId JS work


JS: AdfPage.PAGE.findComponentByAbsoluteId(componentId); 
To make it work:
  • There must be some validation/behaviour property or client attribute present in that component (as in figure, maximum length is present).
  • Or the component itself should be client component.
<af:inputText label="Label 1" id="it1">
   <af:clientAttribute name="defaultFocusField" value="Y"/>
</af:inputText>

Monday, April 30, 2012

ADF: Default cursor/focus to input field using javascript


Sometimes when default properties won't work, we can use JS to set initial focus.
  • jquery is required & can be downloaded from (http://jquery.com/).
  • A dummy <af:clientAttribute> is added for field on which initial focus is required.
  • A <af:clientListener> method is added on "load" type.
<f:view>
    <af:document id="d1">
      <f:facet name="metaContainer">
        <af:resource type="javascript" source="/jquery-1.7.min.js"/>
        <af:resource type="javascript">
          function onLoadFocus() {
              $('input[type="text"]').each(function () {
                  if (isDefaultFocusField(this.name) == 'Y') {
                      this.focus();
                  }
              });
          }

          function isDefaultFocusField(compId) {
              try {
                  var adfComp = AdfPage.PAGE.findComponentByAbsoluteId(compId);
                  return adfComp.getProperty("defaultFocusField");
              }
              catch (err) {
              }
          }
        </af:resource>
      </f:facet>
      <af:form id="f1">
        <af:panelStretchLayout id="psl1">
          <f:facet name="center">
            <af:panelGroupLayout layout="scroll" id="pgl1">
              <af:inputText label="Label 1" id="it1">
                <af:clientAttribute name="defaultFocusField" value="Y"/>
              </af:inputText>
              <af:inputText label="Label 2" id="it2"/>
            </af:panelGroupLayout>
            <!-- id="af_one_column_stretched"   -->
          </f:facet>
        </af:panelStretchLayout>
      </af:form>
      <af:clientListener type="load" method="onLoadFocus"/>
    </af:document>
  </f:view>
Note: http://lspatil25.blogspot.in/2012/05/adf-make-findcomponentbyabsoluteid-js.html

ADF: Default cursor/focus to input field & default button of JSF page


For setting initial cursor/focus to input field:
  • The property named "initialFocusId" should be set of <af:document>.
  • The property named " clientComponent" should be set to "true" for that input field.

For setting default button for the form:
  • The property named "defaultCommand" of "<af:form>" should be set. By setting this property, we can press "Enter" & the button's action will be invoked.
    <af:document id="d1" initialFocusId="it1">
      <af:form id="f1" defaultCommand="cb1">
        <af:panelStretchLayout id="psl1">
          <f:facet name="center">
            <af:panelGroupLayout layout="scroll" id="pgl1">
              <af:inputText label="Label 1" id="it1" clientComponent="true"/>
              <af:inputText label="Label 2" id="it2"/>
              <af:commandButton text="commandButton 1" id="cb1"/>
            </af:panelGroupLayout>
            <!-- id="af_one_column_stretched"   -->
          </f:facet>
        </af:panelStretchLayout>
      </af:form>
    </af:document>
Note: For jsff pages, we can use <af:subform>.
<af:subform defaultcommand="cb1" id="s1" />

ADF: Including javascript/JS or CSS on JSF pages


How to include javascript or CSS on JSF page:
Drag and drop "resource" from operation pallet to page & select JS/CSS accordingly. "source" is optional, so you can either specify location or include js/css directly on page.
Note: you can include resource anywhere on page, but the more appropriate location will be inside "metaContainer" facet of <af:document >.
<f:facet name="metaContainer">
  <af:resource type="javascript" source="/js/custom.css" />
  <af:resource type="javascript">
    function lsp(){
      alert('hi');
    }
  </af:resource>
  <af:resource type="css">
    .text-label{
      color: #cdcdcd;
      font-weight: bold;
    }
  </af:resource>
</f:facet>
On page, wherever you want to call method from JS; just use <af:clientListener >.
 <af:commandbutton id="cb1" text="commandButton 1">
     <af:clientlistener method="lsp" type="action" />
  </af:commandbutton>

Saturday, April 28, 2012

ADF: IE9 Browser Issues


Sometimes when we use nested components i.e. Links, CommandMenu dropdown buttons etc. under Tree/Table component, then we encountered issues on IE9 like links are not clickable, dropdown is not opening etc.

Solution:
For Tree/Table component, we should assign "contentDelivery" property to "immediate"; so as to enable working of nested components in IE9.

Properties file outside EAR


If properties file is placed outside EAR, then there won't be any need to build ear everytime.

Steps:
1. Place the properties file/files at any location on server.
2. Include the location of properties file in classpath.
e.g. If weblogic server is used, you can make entry in server startup script.
set CLASSPATH=(PATH of .properties file without braces);%CLASSPATH%
We can then change properties file & even without building ear, new properties file will be used.

Note: If the logic is to load properties file only once, in that case server restart is needed.

Finally, simple java method to load properties file can be used:
    public static void loadPropertiesBundle(){
        Properties propertiesBundle = new Properties();
        InputStream stream = Thread.currentThread().getContextClassLoader()
                                   .getResourceAsStream("PropertiesFileName.properties");
        try {
            propertiesBundle.load(stream);
        } catch (IOException e) {
            adfLogger.log(ADFLogger.ERROR, "Error getting Property file :" + e.getStackTrace());
        }
    }

Friday, April 27, 2012

Identifying "Type" of ADF "Set Property Listener"



Sometimes we often wonder, which type to select from "Set Property Listener" after inserting it into common components.
The best way to find is, look into the property inspector of component for all available listeners.

e.g. If on <af:commandButton> component, we are adding "Set Property Listener".
Then from property inspector we can know - action, launch & return are supported types.

Similarly, for <af:inputText> component the type available is only "valueChange".

Note: Improper use can result into: javax.faces.FacesException: javax.servlet.ServletException: java.lang.NoSuchMethodException

Friday, April 13, 2012

Unix: Adding a new disk to VM Image


1.Execute the following command to see all the disks that are present on the machine
fdisk -l
Disk /dev/sda: 8589 MB, 8589934592 bytes
255 heads, 63 sectors/track, 1044 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x000ac560   

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1         993     7976241   83  Linux
/dev/sda2             994        1044      409657+   5  Extended
/dev/sda5             994        1044      409626   82  Linux swap / Solaris

Disk /dev/sdb: 3221 MB, 3221225472 bytes
255 heads, 63 sectors/track, 391 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0xe8768ce7
 
   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1         391     3140676   83  Linux Disk

/dev/sdc: 10.7 GB, 10737418240 bytes
255 heads, 63 sectors/track, 1305 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x00000000

Disk /dev/sdc doesn't contain a valid partition table


2.Execute the following commands to create the partitions
fdisk /dev/sdc
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel with disk identifier 0x261e87e6.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.

The number of cylinders for this disk is set to 1305.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
(e.g., DOS FDISK, OS/2 FDISK)

Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)
Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
   p
   Partition number (1-4): 1
   First cylinder (1-1305, default 1):
   Using default value 1
   Last cylinder, +cylinders or +size{K,M,G} (1-1305, default 1305):
   Using default value 1305

   Command (m for help): w
   The partition table has been altered!

   Calling ioctl() to re-read partition table.
   Syncing disks.


3.Create the file system
mkfs.ext3 /dev/sdc1

4.mount the file system
mount /dev/sdc /filepath
  

Unix: Increase system's file descriptor size


This is a common problem with DB servers with heavy transactions.
The server usually throws “too many open files” errors and no new processes could be started.

check the fd size via:
$ulimit -a   # see all the kernel parameters
$ulimit -n   #see the number of open files
$ulimit -n 9000  #  set the number open files to 9000

First, in order to set this options automatically  you have to edit the etc/security/limits.conf file.
root soft  nofile 9000
root hard  nofile 65000

Second you have to add a line in the /etc/pam.d/common-session file:
$ sudo gedit /etc/pam.d/common-session #open the file in gedit
 
Then add the line:
session required pam_limits.so

Unix: Swap Size Increase




To check memory:
free -m
Sample output:
             total       used       free     shared    buffers     cached
Mem:          8105       1292       6812          0         38        483

-/+ buffers/cache:        770       7334
Swap:         1906          0       1906

Swap size increment helps to improve system performance. Suppose we are increasing swap size by 2GB.
dd if=/dev/zero of=/swap_file bs=1M count=2048

This will create file (swapfile) of size 2GB
mkswap /swap_file

add this file to your swap pool
swapon /swap_file

free -m
Sample output:
             total       used       free     shared    buffers     cached
Mem:          8105       1292       6812          0         38        483

-/+ buffers/cache:        770       7334
Swap:         XXXX          0       1906

To make it turn on at every bootup, open up /etc/fstab:
vi /etc/fstab
/swap_file none swap sw 0 0

 

Ubuntu 3GB Ram Limitation and Solution


Ubuntu 32-Bit machine is bound to use maximum of 3 GB RAM, Below are the steps to use > 3GB RAM.
$ free -m
Sample output:
             total       used       free     shared    buffers     cached
Mem:          3291        801       2489          0         95        342

-/+ buffers/cache:        363       2927
Swap:         1906          0       1906

Open terminal and type the following command if you are using Ubuntu version Ubuntu v9.04 and earlier:
$ sudo apt-get update
$ sudo sudo apt-get install linux-headers-server linux-image-server linux-server

If you are using Ubuntu v9.10 (Karmic Koala) and above, enter:
$ sudo apt-get install linux-generic-pae linux-headers-generic-pae

Once kernel images installed, just reboot your workstation, type:
$ sudo reboot

After reboot, login into your system and type the following command to verify memory usage:
$ free -m
Sample output:
             total       used       free     shared    buffers     cached
Mem:          8105       1292       6812          0         38        483

-/+ buffers/cache:        770       7334
Swap:         1906          0       1906