Tuesday, April 25, 2017

ADF: Popup gets closed automatically

Problem description: I found at times people complaint that ADF popup gets closed automatically.
In this blog I am trying to figure out possible cause of popup getting closed.

Possible cause: There are following four scenarios when a popup gets closed.
          1. User selects default buttons or close icon of dialog
          2. User programmatically closes popup using hide function
          3. User hit enter/escape key
          4. Popup or its parent component gets refreshed.

In first two points popup getting closed is desired behavior.

In third case when you use default buttons of popup, it gets closed with enter/escape keys. If you don't want you can use custom buttons as suggested in blog https://blogs.oracle.com/jheadstart/entry/adf_faces_how_to_prevent_closi

Point 4 is most problamatic, when user is not doing anything to close popup but it gets closed automatically. This happens when as a ppr we refresh popup or any of its parent component.
Lets take a scenario:
You have an inputText on popup the moment you enter its value and tab out your popup is getting closed. This may be because you are refreshing popup or any of its parent component. When you do so popup gets closed automatically. Your popup or any parent component of it might have partialtrigger property pointing to inputText. Or you may have valuechangeListener on inputText and you programmatically using addPartialTarget trying to refresh a component, which is having popup as child component in hierarchy.

Most of the time this happens accidentally. You decide to refresh UI component on base page and forget that same UI component is having popup also as child component. As a good practice I can suggest that we should move all our popups in single panelGroupLayout and keep them somewhere close to root components. For example

PanelGroupLayout -container
    PanelGroupLayout - main  [Keep your main page content here]
    PanelGroupLayout - popus  [Keep all your popups together here]
        af:popup1
        af:popup2

Keeping popups out of main page ensure that you can freely refresh main page components while working on popups.
One exception to this rule I see is when you have inline popups. For example you have a table and every row is showing some information in popup (may be on hover) and you have added popup inside a column with contentDelivery=immediate to make sure that popup launches quick with making a server trip. In such cases you have to add popup inside and refer #{row.myAttribute} kind of expression's EL in those.


Thats all.
  

Wednesday, April 19, 2017

Change webservice endpoint at runtime

Problem Description: In ADF we can create a webservice proxy and if we see the main class which extends Service has references of wsdl like
Now if we have dev/uat/production environment and for each environment we need to change endpoint, it could be very bad to change url manually and then generate ear. We need a way to dynamically change url at runtime.


Solutions
What we can do is keep service class as it is. We can use Client class, which we use to create instance of Servce and while creating instance we can provide url

Let say my client class is HCMUserDetailService. I change its constructor to accept url from outside.

    public HCMUserDetailService(String wsdlLocation, String username, String password) {
        super();
        userDetailsService_Service =  new UserDetailsService_Service(wsdlLocation, new QName("http://xmlns.oracle.com/apps/hcm/people/roles/userDetailsServiceV2/",
                    "UserDetailsService"));
        SecurityPoliciesFeature securityFeatures =     new SecurityPoliciesFeature(new String[] { "oracle/wss_username_token_over_ssl_client_policy" });
        userDetailService =      userDetailsService_Service.getUserDetailsServiceSoapHttpPort(securityFeatures);
        Map<String, Object> reqContext =  ((BindingProvider)userDetailService).getRequestContext();
        reqContext.put(BindingProvider.USERNAME_PROPERTY, username);
        reqContext.put(BindingProvider.PASSWORD_PROPERTY, password);
        objectFactory = new ObjectFactory();
             
       
    }



In above code constructor accepts a wsdl url as input and use that to create service instance using UserDetailsService_Service(wsdlLocation,new QName....


Now anybody needs to invoke service using this proxy we can pass wsdl location as input.

User of this client can read wsdl from
1. web.xml context parameter and then use deployment plan to change value of web.xml
2. from database table.

That way wsdl url is not hardcoded and it will get changed dyanamically.

Thats all.

Sunday, April 16, 2017

JCS/JCS-SX: Creating application server connection

Problem Description: I see most of the time people face issues while creating connection with JCS server using Jdev. Its pretty straight forward but we provide wrong details most of the time.

Solution

1. Use Resources pane and select New Connection > Application Server

2. If this JCS account then you can enable your weblogic ports 7001/7002 to public and make normal weblogic application server connection in Resource tab.


3. If its JCS-SX then you may want to use Oracle Cloud type of application-server connection. On first tab provide any name to your connection and select connection-type = Oracle Cloud


4. Next tab provide username/password. NOTE: These are cloud service user not weblogic user. In normal weblogic connection we provide weblogic user and its password but here it should be cloud user and password. If you don't have cloud user details ask cloud admin (who owns identity domain of cloud).



5. Next tab is where you need to select cloud service details [Datacenter, Identity-domain, Service Name]. This is the tab where I see mistakes most of the time. We should be knowing how to get these information. For that login to your cloud my services dashboard.

Datacenter, you always know as that is first thing you select when you want to login to your cloud account. Most of the time for me its us2.

Find identity domain on dashboard



   Select your JCS-SX instance and launch Service Detail page. 
   Get Service-Name as shown below from Service Detail page


   You can also get service name from Java console. Select Java Console from service detail page
   Service Name is mentioned at top of page


Now mention these details on your Jdev connection


Navigate to Test tab and perform a test



Thats all.

Sunday, February 5, 2017

ADF: Execute code before page load

Problem description: In ADF there are multiple ways to execute a piece of code before page load. In this blog I would like to point out those options and their usecases.

Solution
1. If you have a Bounded task-flow and a pagefragment. You want to run a piece of code before fragment load and you want to do it only once. It means if you take any action on your page you do not want to run that piece of code again.

In such case you can simply add a method activity before your page in task-flow. Such method activities gets executed only once before page load.

While writing such methods, you will not have any handle for page components and its binding because you have not yet reached to your page.

Generally we use this approach when we want to do something model side for example I want to execute a VO and before showing its data on page. We can write method in AMImpl, expose it and drop it before fragment on task-flow.


2. If you want a piece of code to get executed anytime you take action on your page. You don't want page components but you want bindings to be available. 

In such case you can add such methods and operation binding in pageDef file and also add corresponding executable. Set executable's refresh property as per your need. Also placing of this executable binding is important as it gets executed from top to bottom. If you expect some VO to have data then you may want to keep this executale binding after that.

If its a bean method that you want to execute in this approach, I would suggest you to write a separate class and keep only that method in that java class and expose it as datacontrol. In any way you are not going to get page components. Getter/Setter of bean will return null so no point in mixing bean with this method. Keep bean and this Java method separately. Actually its not a bean method you are invoking but a datacontrol pojo kind of method.

If you keep your method in different java file but you want to access your bean. You can invoke ADFUtils method to get beanscope first and then get bean instance.


3. If you want a piece of code to get executed anytime you take action on your page. You also want page components to be available. 

In such case you should add hidden outputtext (visible=false) to your page and bind it with bean. In its getter/setter method you can place your code. Keep outputText at the bottom of your page so that by the time its getter/setter runs all other page components are already bound to bean.



In approach 2 and 3 although your method will get execute everytime you make server request but you can control its behaviour by keeping a variable in pageFlowScope and set its value to Y when method got executed first time and next time ownwards check if pageFlowScope variable value is Y then only execute. Something like below

public void initMyPage(){

     String value = ADFUtils.getPageflowScope().get("isPageAlreadyInitialised");

    if(!"Y".equals(value)){

           //write your initialization code here. This piece will get executed only once.
 
         ADFUtils.getPageFlowScope().put("isPageAlreadyInitialised", "Y");


   }

}

4. Using PagePhaseListener: If you are working with jspx page you can have PhaseListeners as well. Here challenge is carefully picking the phase in which you want to execute your code.

You can use ViewScope variable if you want to make sure code only runs on very first load of page.

@Override
    public void afterPhase(PagePhaseEvent pagePhaseEvent) {

        if (pagePhaseEvent.getPhaseId() == Lifecycle.INIT_CONTEXT_ID) {
                
           String value = ADFUtils.getViewScope().get("isPageAlreadyInitialised");

             if(!"Y".equals(value)){

                        initMyPage();

                      ADFUtils.getViewScope().put("isPageAlreadyInitialised", "Y");


            }


         }
    }



As bindings are already in place so you should be able to use bindingContext and bindingContainer to use bindings. Also to get UI component you can get handle of bean and get getter for bean. To get bean handle you can use expressions like
MyBean myBean = ADFUtils.evalueageEL("#{backingBeanScope.myBean}");



Thanks
Sanjeev

Saturday, January 28, 2017

ADF/SOA/Weblogic: Enabling fiddler for all webservice requests made by weblogic server

Problem Description: In ADF/SOA or simple J2EE application we may have requirement to enable third party webservices and we want to see exact request and response messages. Fiddler comes handy to me. In this blog I want to set fiddler to show all request/response messages sent by weblogic.

Solution
1. Install Fiddler: You can download and install fiddler from https://www.telerik.com/download/fiddler

2. Modify setDomainEnv.sh and add below line
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dhttp.proxySet=true -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=8888

Thats all. Now whenever your weblogic server will make a request to third party server, that request will go via fiddler and you can see exact Request/Response messages is fiddler.

Its very useful in SOA framework where you need to invoke services very frequently.


Tuesday, January 3, 2017

Oracle Cloud: Using Cloud Berry to connect with Cloud Storage

Problem Description: In this blog I just want to show how can we use cloud berry to connect with Oracle Cloud Storage.

Solution
1. Get Oracle Cloud storage: To use Oracle Cloud storage you must have cloud storage account. You can get it from https://cloud.oracle.com/en_US/storage


2. Get details from Cloud environment: Once you have Oracle Cloud login you will have username/password and identity domain. Using this you can see you dashboard. From Dashboard you can launch cloud storage home page.



2. Install Cloud Berry: You can download and install Cloud Berry from http://www.cloudberrylab.com/explorer/openstack.aspx

3.Run Cloud Berry and Navigate to File > New Oracle Cloud Account


     Before filling details in above shown form keep your REST endpoint handy. Its shown in Step-2

  • Display Name: It could be anything, which helps you to recognize cloud environment.
  • User Name: This is important. Most of the time mistake we make is we directly provide username. It actually has two parts. First part is last part of REST endpoint url [Storage-<IdentityDomain>]. Second part is your oracle cloud username. Now join both of them using colon (:)
  • Password: Your oracle cloud password.
  • Authentication Service: This is another important part. You can provide two values here. 
    • Take REST endpoint url and remove /v1/Storage-<IdentityDomain> and replace it with /auth/V1.0 as shown in above diagram.
    • Another way is if you have us2 datacenter you can use https://us2.storage.oraclecloud.com/auth/v1.0

4. Thats all, Now you can start managing cloud using Cloud Berry