Monday, July 31, 2017

JCS-SX: Deploy your first application

Problem description: If you create a minimum ADF application and try deploy it directly on JCS-SX instance your deployment may fail with below error

2017-07-31 19:02:13 CDT: weblogic.application.ModuleException: weblogic.application.ModuleException:
at weblogic.servlet.internal.WebAppModule.startContexts(WebAppModule.java:1531)
at weblogic.servlet.internal.WebAppModule.start(WebAppModule.java:488)
at weblogic.application.internal.flow.ModuleStateDriver$3.next(ModuleStateDriver.java:425)
at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:52)
at weblogic.application.internal.flow.ModuleStateDriver.start(ModuleStateDriver.java:119)
at weblogic.application.internal.flow.ScopedModuleDriver.start(ScopedModuleDriver.java:200)
at weblogic.application.internal.flow.ModuleListenerInvoker.start(ModuleListenerInvoker.java:247)
at weblogic.application.internal.flow.ModuleStateDriver$3.next(ModuleStateDriver.java:425)
at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:52)
at weblogic.application.internal.flow.ModuleStateDriver.start(ModuleStateDriver.java:119)
at weblogic.application.internal.flow.StartModulesFlow.activate(StartModulesFlow.java:27)
at weblogic.application.internal.BaseDeployment$2.next(BaseDeployment.java:671)
at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:52)
at weblogic.application.internal.BaseDeployment.activate(BaseDeployment.java:212)
at weblogic.application.internal.EarDeployment.activate(EarDeployment.java:59)
at


Solution:
You need to create weblogic.xml file inside WEB-INF and make following entry in it

<?xml version = '1.0' encoding = 'windows-1252'?>
<weblogic-web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.bea.com/ns/weblogic/weblogic-web-app http://www.bea.com/ns/weblogic/weblogic-web-app/1.0/weblogic-web-app.xsd"
      xmlns="http://www.bea.com/ns/weblogic/weblogic-web-app">
   

    <library-ref>
        <library-name>adf.oracle.domain.webapp</library-name>
    </library-ref>
    <library-ref>
        <library-name>jstl</library-name>
        <specification-version>1.2</specification-version>
    </library-ref>
    <library-ref>
        <library-name>jsf</library-name>
        <specification-version>1.2</specification-version>
        <exact-match>true</exact-match>
    </library-ref>


</weblogic-web-app>


Once done you can deploy your application.


Thats all.

Making ADF page Readonly

Problem description: Sometime we found that we want to make ADF page readonly based on certain condition. One option is apply EL expression on all input fields of ADF page. For example you can write EL as readonly="#{pageFlowScope.pPageMode=='View'}. By this expression we are saying make input field read only if page mode is view. If there are multiple input fields, we need to apply it on all those fields. I would say if number of fields are less, its manageable but at times fields are more and it becomes very difficult to maintain this condition. In future also some developer may add new field but then forget to add this condition. So at times it becomes error pron and we need a centralized solution to make a page readonly. In this blog I am showing a generic method, which makes page input/action items disabled/readonly.

Solution

1. Have a bean for page and write below method

private void makeComponentHierarchyReadOnly(UIComponent component) {

        try {
            Method method1 =
                component.getClass().getMethod("setDisabled", boolean.class);
            if (method1 != null) {
                method1.invoke(component, true);
            }
         

        } catch (NoSuchMethodException e) {
            try {
                Method method =
                    component.getClass().getMethod("setReadOnly", boolean.class);
                if (method != null) {
                    method.invoke(component, true);
                }
            } catch (Exception e1) {
                // e.printStackTrace();//silently eat this exception.
            }


        } catch (Exception e) {
            // e.printStackTrace();//silently eat this exception.
        }
        List<UIComponent> childComponents = component.getChildren();
        for (UIComponent comp : childComponents) {
            makeComponentHierarchyReadOnly(comp);
        }

    }

Above method is taking UI component as input. It iterates over each child upto n level and try to disable them or if disable property is not there then it tries to make it readonly.

NOTE: Disable will also disable links/button and all action items as well.

2. You can call above code at appropriate time: Mostly we want to call above code at page load but at times you may have View/Edit button and on click of that you want to call it. If you want to call it at page load you can take approach 3 as described in blog http://sanjeev-technology.blogspot.in/2017/02/adf-execute-code-before-page-load.html

If you want to call on button click then you can simply have actionListener and call above method from there. For example
public void makePageReadOnly(ActionEvent actionEvent) {
        // Add event code here...
        makeComponentHierarchyReadOnly(this.getMyPageRootComponent());

    }

getMyPageRootComponent is a getter for a UI component under which you want everything to be readonly. To get this component, you just need to bind it with bean.

Thats all. Thank you for your time.