Saturday, June 25, 2016

ADF : populating the bind variable from ViewObjectImpl Class

In ADF while working with view objects(Entity based or Readonly) user might be in need to populate the bind variable value from Security context or session scope. for this reason it can be populated easily in java class

Consider a scenario where the query to be executed is "Select * from <tablename> where userid is <logged in user>". Such scenario can be handled via regexs (since i am not very good with regex so i decided to populate such value in java class which gives me flexibility to get such values from security context or session scope and also i can modfiy  the values is needed using java APIs.


Steps.
1. create the bind variable and assign the value as expression as :
adf.object.viewObject.managerRoleIdFromSession





here the managerRoleIdFromSession is private string defined in the Impl class as:


    private String managerRoleIdFromSession;


    public void setManagerRoleIdFromSession(String managerRoleIdFromSession) {
        this.managerRoleIdFromSession = managerRoleIdFromSession;
    }

    public String getManagerRoleIdFromSession() {
        String managerRoleId="";
        Map sessionScope = ADFContext.getCurrent().getSessionScope();
        managerRoleId=sessionScope.get("Manager_roleId")!=null?sessionScope.get("Manager_roleId").toString():"";
        return managerRoleId;
    }

as demonstrated in the setter method user can use the necessary APIs to play around the variable and get desired output

Thursday, March 3, 2016

Developing custom build Kaptcha (captcha) in adf

Web applications might often need captcha in order to prevent application from robotic attacks. Following example demonstrates how to build custom captcha in ADF Technology

Display Captcha :

Add following in jspx:

 <af:panelGroupLayout id="pgld11" layout="horizontal">
                  <af:outputLabel value="#{pageFlowScope.backingBean.secretQ}" id="otd14"
                                  inlineStyle="font-weight:normal; font-size:small; color:Black; font-family:Arial;"/>
                  <af:spacer width="18" height="5" id="sd13"/>
                  <af:inputText simple="true" label="secretQ" id="it7capta" contentStyle="width:100px; height:22px; font-family:Arial; font-size:small; color:Black; border-color:#878787;"
                                value="#{pageFlowScope.backingBean.secretUA}"
                                autoSubmit="true"
                                binding="#{pageFlowScope.backingBean.secreatAnswer_binding}">
                     </af:inputText>
            </af:panelGroupLayout>

in backing bean define the variables as:

 private String secretQ, secretA, secretUA;

 public void setSecretQ(String secretQ) {
        this.secretQ = secretQ;
    }

    public String getSecretQ() {
        List<String> secretQandA = CAPTCHAUtil.getQuestionAndAnswer();
        this.setSecretQ(secretQandA.get(0));
        this.setSecretA(secretQandA.get(1));
        this.setSecretUA("");
        return secretQ;
    }

    public void setSecretA(String secretA) {
        this.secretA = secretA;
    }

    public String getSecretA() {
        return secretA;
    }

    public void setSecretUA(String secretUA) {
        this.secretUA = secretUA;
    }

    public String getSecretUA() {
        return secretUA;
    }


please find the captcha util class attached. it can be modified as per user needs.


Validate Captcha:

Call this method to validate captcha:

    private Boolean validateCapta() {
        if(getSecretUA()== null){
            retValue=false;
        }else{
            if(getSecretUA().equals("")){
                retValue=false;
            }else if(!getSecretA().equalsIgnoreCase(getSecretUA())){
                retValue=false;
            }
             
        }
     
        return retValue;
    }

Data Source Not Found

While developing a web application i often come across following exceptions:

javax.naming.NameNotFoundException: Unable to resolve '<Data_Source_Name>'. Resolved ''; remaining name '<Data_Source_Name>'

at weblogic.jndi.internal.BasicNamingNode.newNameNotFoundException(BasicNamingNode.java:1139)
at weblogic.jndi.internal.BasicNamingNode.lookupHere(BasicNamingNode.java:252)
at weblogic.jndi.internal.ServerNamingNode.lookupHere(ServerNamingNode.java:182)
at weblogic.jndi.internal.BasicNamingNode.lookup(BasicNamingNode.java:206)
at weblogic.jndi.internal.WLEventContextImpl.lookup(WLEventContextImpl.java:254)
at weblogic.jndi.internal.WLContextImpl.lookup(WLContextImpl.java:411)
at javax.naming.InitialContext.lookup(InitialContext.java:411)



oracle.jbo.DMLException: JBO-27200: JNDI failure. Unable to lookup Data Source at context HppConnNonXA
at oracle.jbo.server.DBTransactionImpl.lookupDataSource(DBTransactionImpl.java:1491)
at oracle.jbo.server.DBTransactionImpl2.connectToDataSource(DBTransactionImpl2.java:335)
at oracle.jbo.common.ampool.DefaultConnectionStrategy.connect(DefaultConnectionStrategy.java:203)
at oracle.jbo.server.ApplicationPoolMessageHandler.doPoolConnect(ApplicationPoolMessageHandler.java:620)
at oracle.jbo.server.ApplicationPoolMessageHandler.doPoolMessage(ApplicationPoolMessageHandler.java:425)
at oracle.jbo.server.ApplicationModuleImpl.doPoolMessage(ApplicationModuleImpl.java:9316)
at oracle.jbo.common.ampool.ApplicationPoolImpl.sendPoolMessage(ApplicationPoolImpl.java:4530)
at oracle.jbo.common.ampool.ApplicationPoolImpl.prepareApplicationModule(ApplicationPoolImpl.java:2460)





Reason:
Application Module is configured (App Mod -- > Configurations -- > App Module -->Connection Type)to connect to DB using data source defined in Weblogic(WL Console --> Service -->Data Source). The Data source is unavailable for the application


Where to Look for solution:

If you get the above mentioned error look for following :

1. Make sure the data source is targeted for the default server(in local) or the designated server you are running the application.

Go to WL Console --> Service -->Data Sources --- > Select Data source ---> Targets:




2. This might happen more often then you think. In most of the cases (atleast with me) you might have been disconnected to vpn or the data base might not be reachable due to some circumstance.

Make sure the database connection is up. quickest way to check the same is :

Go to WL Console --> Service -->Data Sources --- > Select Data source -- > Configuration --> Connection Pool and click on save.

If the data base is reachable, you would get all green in case of issue you will find it





The issue mentioned above may sound silly but believe me its occurs more often then you think.

Hope its is useful



Wednesday, January 27, 2016

Solution to ADFC-0619: Authorization check failed

Problem Statement:
My ADF Application, with security implemented through jazn-data when deployed on Weblogic box, the authorization does not happen and i often i receive
oracle.adf.controller.security.AuthorizationException: ADFC-0619: Authorization check failed: 'oracle.jbo.uicli.binding.JUFormDef@d856cd' 'VIEW'.

This issue has been discussed @:
https://community.oracle.com/message/9646751
http://oracle.developer-works.com/article/4786269/ADFC-0619%3A+Authorization+check+failed%3A+'homePageDef'+'VIEW'+-+Solved

Root Cause:
The root cause for the issue is when an ADF application with security enabled is deployed through weblogic console the <Domain_home>/config/fmwconfig/system-jazn-data.xml do not get updated and hence the server is not aware of the security policies and the page remains unavailable

Solution:

I was stuck with this issue for more than 2 weeks and following solutions were implemented:

1. Instead of going for Authentication and Authorization go for Authentication only


Not sure why this works, but it induces a new issue.
Issue with this approach if if trying to access a page with permission given to anonymous-role, the application would route to the login page in this case and user is forced to login

2. Try to deploy the application on server through Jdeveloper


This solves the issue but in most of the cases the prod servers wont be available for developers to access and makes this approach unpractical

3. Deploy through em console

This approach finally worked in my case. Deploy the application on Admin Server through em console. Make sure in Deployment Settings: Click on Configure Application Security to modify the default settings and in Configure Application Security provide following:

Select Application Policy Migration as “Append”.
Uncheck the “Remove Policies during Application undeployment
Provide Application setting id as "<Application_name>"
Click Apply



NOTE: THIS STEP WOULD UPDATE THE system-jazn-data.xml FILE

Now undeploy the application from Admin Server and deploy it on the managed server with same settings keeping the system-jazn-data.xml intact(i guess deployment to managed server can be done even from WL Console but never tried it)

probably Dimitar Dimitrov speaks of the same stuff manually in the thread



Please share your thoughts on this issue if you face it




Wednesday, January 6, 2016

Solution to JBO-25014: Another user has changed the row with primary key oracle.jbo.Key[xxx].

I have posted this issue here

Simultaneous Commit operation in ADF throws "oracle.jbo.RowInconsistentException: JBO-25014"

Chris has discussed this issue in detail here

I have how tackled the solution and such implementation can be applied as turn around solution.

The real culprit is:

We know the record in the mid-tier has been changed by the user, however ADF doesn't use the changed record in the mid-tier to compare to the database record, but rather a copy of the original record before it was changed.  This leaves us to conclude the database record has changed, but how and by who?

So,  simple call execute operation for that viewObject after commit would solve the problem .
as:            
   OperationBinding op = getBindings().getOperationBinding("searchApplication");  //searchApplication is the method which populates the VO
    op.execute();

But would reset the iterator and even though the selected row in table is (says 5th from the top), the form would be always displaying 1st row.

So i deal with problem with variable defined as:
private String currentRowKeyStr="";
i would set this variable to
currentRowKeyStr=row.getAttribute("PrimaryKeyValue")!=null?row.getAttribute("PrimaryKeyValue").toString():"";

Similarly,
on the table selection listener
selectionListener="#{pageFlowScope.Bean.selectTable_SelectionListener}"

i would set this variable every time a row is selected as:
currentRowKeyStr=rowSelected.getAttribute("PrimaryKeyValue")!=null?rowSelected.getAttribute("PrimaryKeyValue").toString():"";

Please post comment in case you need help with such issue

Wednesday, December 23, 2015

Fixing the Issue where getBindings() returns Null

Problem Statement:

Suppose we have a jspx page having a bounded task flow as region.


The taskflow starts with method activity as shown in the figure


If the method tries to access the some method binding using the getBinding() method, where get binding is defined as:

    public BindingContainer getBindings() {
        return BindingContext.getCurrent().getCurrentBindingsEntry();
    }

some binding method accessed as:
        OperationBinding op =
            (OperationBinding)getBindings().get("someMethodInAppModImpl");
        Object result = op.execute();

in this case, the BindingContext.getCurrent() would return the BindingContext but when trying to access getCurrentBindingsEntry(), this method would return null and as result the
 OperationBinding op =
            (OperationBinding)getBindings().get("someMethodInAppModImpl");

would throw null pointer exception

Solution:

Since the page starts with method having no pagedef difination the CurrentBindingsEntry always return null.

Make Sure you create binding for the default method as:


also the binding defined for the method shall have the method binding for the someMethodInAppModImpl you wish to access during execution.

Once page defination is defined, you can see the small little sign at the right bottom of the methodas


Please reach out in case of any further issues


Tuesday, July 14, 2015

Externalized Resource Bundle for ADF Application

Often we have to use resource bundle for our project which is a part of the project war.
Issue with this approach is when the war is specific to environment, for eg, if you need to provide different url for dev,prod,st and qa in your application, you need to create environment specific artifact and the same artifact can not be implemented across all the environment.

Solution to this approach is to externalize the resource bundle. The resource bundle would be the part of environment and the application would point to the location of the resource bundle instead of resource bundle being a part of the Application.

steps to implement the same:

1. create the property file with content(content is specific to this demo):

button_value=this text comes from property file
butoon_message=this message will be displayed on button click which comes from property file

and save it as TestMessage.properties in the local folder for eg:

C:\test\TestMessage.properties

while deploying the application in weblogic the path can be:
/web/TestMessage.properties

2. Mention the path's name in weblogic's start parameter.
I would define a system variable as TESTPROP_PATH and assign it the location as C:\test\TestMessage.properties for the example

To achieve this i have made an entry in
setDomainEnv file present in <UserFolder>\AppData\Roaming\JDeveloper\system11.1.1.7.40.64.93\DefaultDomain\bin

as:
set EXTRA_JAVA_PROPERTIES=-Djps.app.credential.overwrite.allowed=true -DTESTPROP_PATH=/test/TestMessage.properties %EXTRA_JAVA_PROPERTIES%

once set, this variable can be accessed from application as:

System.getProperty("AIMSPROP_PATH")

***please check with Environment team how to perform the step 2 for the environment


3. Now in your application you need to create a java class which would extend ListResourceBundle and fetch all the entries from the file as:

4. Make an entry for this class as <resource-bundle> in faces-config.xml

5. To access the resource bundle in jspx or jsff and entry has to be made in for f:loadBundle and can be used as:
6. Similarly, to use the resource bundle in java class can be used as:

the link to the demo application can be found here

steps 1 & 2 has to be performed individually to run the downloaded application


Please put in your comments in case of any doubts or suggestion to improvise this entry