Skip navigation.

Andrejus Baranovski

Syndicate content
Blog about Oracle technology
Updated: 12 hours 58 min ago

MAF 2.1 Alta Mobile UI - Running On iPad Device

Tue, 2015-02-24 14:03
I have installed MAF application (described and available for download here: MAF 2.1 Alta Mobile UI and Oracle Mobile Suite) on iPad device, iOS 8 and would like to share couple of tips and tricks about it. I was installing on iPhone/iPad previous MAF versions (it was called ADF Mobile) - ADF Mobile - Live on iPhone Device. It is always forth to read Oracle Developer guide for MAF - 27.4.2 How to Deploy an Application to an iOS-Powered Device.

You would need to get Apple Development Provisioning Profile (this costs around $100), in order to be able to install MAF application on iPad device for testing. Provisioning Profile creation process is streamlined in iOS 8 and is simple to follow. Here is the example of our Apple Development Provisioning Profile entry, this can be download and installed on Mac OS with one click:


Sample MAF application I'm going to deploy is connecting to the REST service. Make sure to set proper IP address for the REST connection entry in MAF. IP must point to the Service Bus service with published REST connection:


JDeveloper 12c is fetching Provisioning Profile information automatically. You only need to copy paste Common Name from iOS development certificate into Signing Identity field (created and registered during Provisioning Profile creation process):


Make sure to specify the same Application Bundle Id prefix as the one registered in Provisioning Profile. Documentation states you can test MAF application on iPhone/iPad device only in Debug mode, however this is not true - it works fine in Release mode as well:


Thats it with configuration. Choose to deploy MAF application into IPA distribution package:


IPA distribution package file must be generated in deploy folder. Double click on it and it will get installed into iTunes:


Open iPhone/iPad section in iTunes and go to the App category. You should see your new MAF application listed there. Click on Install button and then press Synch - this will install application into the device:


Application is successfully loaded and dashboard screen is displayed. Service Bus provides REST data to the MAF application running on the iPad, data is rendered in Tree Map graph (MAF component):


User could switch to Employees screen:


Alta UI look and feel - we could search for employees and browse through a list with shortcuts:


Switch to cards view, instead of default list view:


Select employee who is a manager:


Pie graph with compensation of managed employees is displayed:


List of managed employees is also present:


I have tested AirPlay and connected iPad with Mac. This is useful to display iPad screen on projector, when you want to demonstrate your app to the audience. AirPlay synchronisation works pretty well, without configuration headache (you may require additional utility application for this). You must enable mirroring on your iPad device:


We are getting iPad screen view on the Mac. This is pretty useful for the presentations and demos:

Red Samurai ADF Performance Audit Tool v 3.4 - ADF Task Flow Statistics with Oracle DMS Servlet Integration

Mon, 2015-02-23 12:38
We have integrated Red Samurai ADF Performance Audit Tool with Oracle DMS Spy Servlet. Integration is dynamic and doesn't require any extra configuration. It brings out of the box information about ADF Task Flow usage and performance. This means we are analysing from now on not only ADF BC performance data, but ADF Controller data also.

DMS Spy Servlet context is accessed in certain intervals and we are not only displaying DMS data, but storing it inside our audit tables. This allows to keep historical data and preserve it between WLS restarts - this is not possible with DMS Spy Servlet alone.

New tree map graph displays ADF Task Flow usage in the application - larger box, more frequently Task Flow is accessed:


Graph is clickable, user could select a box and detail data for the Task Flow will be displayed. We are displaying a number of Active/Maximum Active Task Flows over time. Average load time is logged and displayed - this allows to identify Task Flows with slow performance:


Here you can check information about previous v 3.3 version - Red Samurai ADF Performance Audit Tool v 3.3 - Audit Improvements.

ADF BC Range Paging and REST Pagination

Thu, 2015-02-19 13:14
In this post I would like to explore and integrate two thing - ADF BC Range Paging and REST service pagination. It would inefficient to retrieve entire set of data in the REST service, ideally should be available option to specify number of rows and range number to fetch. ADF BC allows to query VO in Range Paging mode - SQL query will be constructed with row numbers, to query data in certain range of rows (this allows to fetch less data from DB). We could combine this with REST service and provide light interface to access data.

Here you can download sample application - RestADFBCApp.zip (compiled with ADF 12c). I'm translating ADF BC VO structure into HashMap, this allows to publish unified structure through REST, without creating a separate POJO object. There is a special generic method called toHashMap, it iterates over VO attributes and constructs a HashMap with attribute names and values:


Generic AM method accepts parameters for page number and range size. Here we enforce Range Paging mode for VO and using ADF BC API methods to scroll to the certain page and set the range size (number of rows to fetch). It is important to get results from default rowset, otherwise ADF BC will generate a separate default SQL query:


ViewController project contains a list of references to the REST and Jersey related libraries, these extra libraries are required to transform HashMap to the REST response:


Here is the REST method. I'm accessing ADF BC Application Module and invoking custom method, with range size and page number coming from the REST request. Result is a list of HashMaps - a set of VO rows:


Make sure there is Jersey servlet defined in web.xml, REST request will not work without it:


Here is the example, where I perform a request through REST for rangePage = 1 and rangeSize = 10. This means 10 rows from the first page of rows are fetched:


You should check SQL query in the log. REST request from above generates a special SQL with ROWNUM. This means we are retrieving less data from DB, only data we need to display in the current page:


MAF 2.1 Alta Mobile UI and Oracle Mobile Suite

Mon, 2015-02-09 12:19
This post is about Alta Mobile UI and MAF 2.1. I was using Oracle Work Better mobile application as a reference, along with Alta Mobile UI Design Guidelines. This is based on my previous posts about Oracle Mobile Suite and MAF 2.1 integration, read more here - Oracle Mobile Suite - Web Service Performance Optimisation with Result Caching. You could also use Alta UI 12c with regular ADF Web applications, check more here - Custom ADF Application with New ADF 12c Alta UI.

Sample application - MobileServiceBusApp_v5.zip (contains ADF BC SOAP Web Service, Oracle Mobile Suite SOAP to REST transformation and MAF 2.1 application with Alta Mobile UI) implements a dashboard. Component to visualise amounts and values comes out of the box with MAF (iPad view):


User could open a springboard and select Employees option in the sample application:


Here we can search for employees by first name/last name and bring results as a list:


Optionally user could switch to cards view, to display the same results in different way:


You could click on employee icon - this will load details screen and bring additional info:


Steven King is a manager, he manages Executive department and there are two team members reporting to him. Compensation graph can be displayed for team members:


A list of team members is displayed in the third tab:


There is MAF 2.1 Deck component in Employees search page, it allows to switch between a list and cards view:


Employee details page is rendered with a help of MAF 2.1 Deck component as well, along with Select Button component to display tab UI and navigate between Detail, Compensation and Team sections:


You could check how these pages are implemented in the sample app provided above.

Oracle Mobile Suite - Web Service Performance Optimisation with Result Caching

Tue, 2015-02-03 13:18
One of the main advantages of Oracle Mobile Suite - Service Bus and SOAP/REST web service transformation (more here - Oracle Mobile Suite Service Bus REST and ADF BC SOAP). In addition you will get very nice performance improvement, there is out of the box caching for Web Service resultset with Coherence. I'm going to demonstrate how it works, all out of the box - really simple.

You could define caching for external service (ADF BC SOAP web service in my case), just edit service definition. This is our business service running on WebLogic backend, where actual processing happens. Naturally we would like to eliminate duplicate calls and retrieve previous resultsets from cache stored in Service Bus layer:


Wizard allows to enable result caching by cache token expression. In my case, nameVar is a variable from ADF BC SOAP web service, findEmployees method. You could use a wizard to construct expression. On runtime it will cache resultsets for all the requests according to specified expression. Basically it will cache all invocations of findEmployees method and will track cached data by nameVar parameter value. You could specify cache expiration time, if data is updated more often, expiration time should be shorter. Expiration time even can be dynamic, taken from the request variable:


That't is - this was really simple. All Coherence complexity is hidden and you don't need to worry about it.

I will be running MAF application to perform a test. Here I'm searching by value - th:


If we would check WebLogic log, where ADF BC SOAP web service is deployed, we could see the SQL query was executed with nameVar=th (as per search request in MAF application screen):


Let's run a different query now, search for nameVar=ew:


Again repeat previous search with nameVar=th, there should be query executed on WebLogic server with ADF BC SOAP web service, result should be taken from cache stored in Service Bus (as directed per performance optimization tuning above):


Indeed there was no SQL query executed for nameVar=th this time, data was taken from cache - this is great performance optimisation:


Download sample application (it contains ADF BC SOAP web service, Service Bus and MAF implementations) - MobileServiceBusApp_v4.zip.

MAF 2.1 - Debugger Improvements and Mobile REST Client

Sat, 2015-01-31 11:43
I was blogging previously about Oracle Mobile Suite and REST service transformation from ADF BC SOAP service. Today I'm going to blog the next step in the same series - MAF client consuming REST service exposed from Oracle Mobile Suite ESB. I'm going to highlight improvements in debugging process for MAF, provided with the latest 2.1 release. I had couple of challenges implementing and mapping programmatic MAF client for REST service, all these were solved and I would like to share the solution with you.

Previous posts on the same topic:

- Oracle Mobile Suite Service Bus REST and ADF BC SOAP

- How To Add New Operation in Oracle Mobile Suite Service Bus REST Service

Here you can download sample application implemented for today post (contains ADF BC SOAP, Mobile Suite Service Bus and MAF client apps) - MobileServiceBusApp_v3.zip.

High level view of the implemented use case - there are three parts. Service Bus is acting as a proxy to transform ADF BC SOAP service to light REST consumed by mobile REST client (implemented in MAF):


I would not recommend to use auto generated Data Control for REST service - I didn't had positive experience using it. You should invoke REST service from Java, using MAF helper classes (read - here). There must be REST connection defined and tested, later it can be accessed and used directly from Java. REST connection endpoint must include REST service URL (in my case, it by default points to getEmployeesListAll operation):


It is enough to define REST connection, now we can start using it.

Sample application implements REST helper class. Here actual REST call is made through MAF RestServiceAdapter class - see invokeRestService method. Public method invokeFind(requestURI) is supposed to be used to initiate search request. Content type is set to be JSON. Search parameter is always passed as a part of requestURI, therefore we are passing empty post data value:


MAF application contains Java class - ServiceHelper, this class is used to implement Data Control. Each time when search parameter is set, applyFilter method is invoked and it makes REST request. Response is received and with the help of MAF utility (highlighted) is transformed from String to the array of objects:


ServiceHelper class includes a set of variables required to perform successful REST request. Data collection object - employees of type EmployeeBO[] is defined here and later exposed through Data Control:


As you can see from above example of applyFilter method - response String is transformed to the array of objects. I'm using EmployeesList class for conversion. This class contains array of objects to parse from REST response. It is very important to have exactly the same name for array variable as your REST response result set name. In my example, this name is employees:


Finally there is class to represent response object - EmployeeBO. This class is a POJO with attribute definitions:


ServiceHelper class is exposed to Data Control - defined methods will be accessible from MAF bindings layer:


This is all about REST client in MAF implementation - I would say quite straightforward, when you are on the right path.

Let's have a few words about debugger in MAF 2.1. I would say I was positively impressed with debugger improvements. There is no need to do any extra configuration steps anymore, simply right click anywhere in Java class you are currently working on and choose Debug option - Debugger will start automatically and MAF application will be loaded in iOS simulator.

It works with all defaults, you could go and double check the settings in Run/Debug section of MAF project - Mobile Run Configuration window:


Right click and choose debug, don't forget to set a breakpoint:


Type any value to search in the sample MAF application - Employees form. You should see breakpoint is activated in JDEV (as it calls applyFilter method):


Debugger displays value we are searching for:


After conversion from response String to array of objects happens, we could inspect the collection and check if conversion happened correctly:


Response from REST is successfully displayed in MAF UI:

How To Add New Operation in Oracle Mobile Suite Service Bus REST Service

Mon, 2015-01-26 14:00
I will use sample app from my previous blog post as the basis - Oracle Mobile Suite Service Bus REST and ADF BC SOAP. I was describing there the main steps in defining transformation from SOAP WS based on ADF BC to the REST WS interface. I will dive a little bit deeper into the same topic and will explain how to add new operation to the REST WS interface.

Here you can download updated sample application - MobileServiceBusApp_v2.zip. In order to add new operation to the REST interface, you should choose Edit REST option for REST Proxy Service in JDEV Service Bus project:


REST Binding editor will appear. Here you should define new resource - I will add /employees to return the list of all employees. New operation should be defined for resource path - /employees, operation getEmployeesListAll in my case:


You can give any meaningful name for the operation. Make sure to select correct resource path and use GET (if you want to fetch data, not update or delete). I'm getting the list of all employees, this means there will be no parameters in this case:


In the response specification tab for the getEmployeesListAll operation, make sure select JSON as the payload. You could use the option to generate sample payload - this shows what kind of result set will be constructed (based on the response XSD - HRRestProxy.xsd, I have created it in the previous post mentioned above):


Once new operation is defined in the REST wizard, we can add it to the mapping. Simply you could copy existing operation mapping to the newly created operation branch. Select new branch and provide required operation name - getEmployeesListAll in this case:


We need to edit request action first and specify empty payload - we want to fetch the list of all employees. For this we could reuse existing transformation file (REST to SOAP):


Important to remember - transformation file is created as a XQuery Map module, where you need to specify source and target types (this will allow to transform REST to SOAP and vice versa):


Request action contains empty value binding - REST variable will be initialised as empty, this will allow to use getEmployeesListAll operation with /employees path:


For response action I'm reusing the same transformation as in getEmployeeList operation - response will be parsed in the same way, using the same binding:


This is how it works - the list of all employees is fetched with /employees path (testing using Postman extension available in Google Chrome):


Previously implemented operation works as well, user could search by First Name/Last Name:

Reading MAF iOS Simulator Logging Output

Fri, 2015-01-16 03:34
It could be very handy to know how and where to read MAF logging output from iOS simulator. This is not that obvious to find logging output on Mac OS system. All log is written into application.log file, this file is located inside temporary application directory. I will explain how to locate this directory and how to open application.log file. You can read more about MAF testing and logging here - 18.5 Using and Configuring Logging.

Sample mobile application - ADFMobileLogginApp.zip, is pretty basic and contains System.out.println to write a message into application.log file:


Message is written to the log from Action Listener method, invoked from Save button. Log file application.log is accessible from the following location (you can access it from the console) -

Users/youruser/Library/Application Support/iPhone/ 7.1/Applications/com.company.ADFMobileLoggingApp/Document/logs.

As you can see, application.log file is stored under logs directory in documents folder. You must navigate to the iOS simulator, application temporary folder to access it:


There will be application.log file available:


Log file can be opened directly from console, execute command open -a TextEdit application.log:


Message from saveAction() is printed in the log:


Enjoy MAF coding in Mac OS !

How To Start a Case in Oracle Adaptive Case Management 12c

Sat, 2015-01-10 03:43
Blog reader was asking to describe how to start a new case in Oracle ACM 12c. You can read my previous blog post on ACM 12c topic - Adaptive Case Management 12c and ADF Human Tasks. There are multiple ways to start a case, depends if you want just to test the case or really use it. I would recommend to use SoapUI to test the case. In the real scenario, case most likely will be started from third party web service or through ACM 12c Java API. Here I would like to describe, how you could use SoapUI to test ACM process during development.

Once ACM 12c application is deployed, you could open it in EM. There is the option to test deployed composite and invoke it through EM Web Service tester. In the example below you can see startCase operation selected and payload structure displayed. Unfortunately it doesn't work well to test ACM process through EM, payload structure is very confusing and it usually fails with mandatory attributes missing errors:


Instead I would recommend to use SoapUI to test the ACM 12c composite. You could download and use it free of charge. Start the tool and choose to create New SOAP Project:


We need WSDL URL to define a SOAP project in SoapUI. You can copy WSDL URL from EM test screen:


Paste it into SoapUI dialog (Initial WSDL field) and Project Name will be filled in automatically (keep Create sample requests for all operations? option selected):


SoapUI will fetch all operations from the service and new SoapUI project will be generated:


In order to start a new case, expand startCase operation and open Request 1. Request will be pre-filled with default payload structure (similar as we saw in EM):


Save SoapUI project, before doing any changes to the request structure. I would suggest to save it under ACM JDEV application structure - project is saved into single XML file:


Change the request to include custom data payload (you can find this XML code inside sample application available for download) and invoke the service. If request will be successful, you should see case number returned in the response:


Case with the same number should be available in BPM Workspace:


Here you can download sample application with SoapUI project (XML file) included - HotelBookingProcessing_v1.zip.

Oracle Mobile Suite Service Bus REST and ADF BC SOAP

Sun, 2015-01-04 10:06
One of the key parts of Oracle Mobile Suite 12c offering is Service Bus product. This is logical choice - Service Bus allows to transform complex SOAP Web Service data into simplified REST format, preferred by mobile client. I think it is essential to use Service Bus, when implementing enterprise mobile applications. It makes sense to learn how Oracle Service Bus works. I would recommend to start from Steven Davelaar excellent tutorial article, available here - Creating a Mobile-Optimized REST API Using Oracle Service Bus – Part 2.

I have created my own ADF BC application with SOAP WS - findEmployees method (filters by first and last name). Here you can download both applications - MobileServiceBusApp_v1.zip. Keep in mind, for some reason Service Bus server doesn't start with JDEV 12c BPM Default Domain, it works only with JDEV 12c SOA Default Domain. Make sure to check, which JDEV you are using, you can check the list features installed:


ADF BC SOAP service is implemented to support Master-Detail (Employee - Department Managed by Employee) structure:


Detail VO is visible in WS response, only when ADF BC SDO classes are generated for the VO:


Here is Service Bus application main diagram. External Services contains a reference to the ADF BC SOAP WS (invoked through HTTP service). Proxy Services contains a reference to the REST proxy (this will be accessed from mobile device). Pipeline contains a mapping resource, this is where transformation between SOAP and REST happens:


REST proxy service is defined to support getEmployeesList operation with parameter - nameVar:


REST proxy service response is configured with EmployeeListResponse element, stored in HRRestProxy.xsd file:


Here is the structure returned by REST proxy service - list of employees and list of departments managed by employee:


Pipeline mapps SOAP and REST services. Here we can define how request and response actions are handled. Request action is processed with mapping stored in EmployeeDetailsPS2BS file:


Request action mapping is simple, it needs to pass search parameter and assign it to nameVar parameter from SOAP WS:


This is how search parameter is initialised in REST -  through special expression, value is taken from REST request and sent to SOAP call through mapping:


Response is handled with EmployeeDetailsBS2PS mapping:


This mapping is more complex and it represents the data, returned by REST proxy service. Here we need to map all attributes from SOAP WS to REST proxy service response. This is the place, where actual transformation happens - here we can decide, how we map attributes and even convert between types:


To test Service Bus application, you can simply right click on REST proxy service and choose run:


Service Bus application should be accessible in Enterprise Manager, list of all operations should be present. In the picture below, we can see both SOAP and REST proxy services present. You can open HRRestService:


Test button is present, this allows to test REST proxy service directly from Enterprise Manager:


Provide search parameter  - it will look for 'w' in both first and last name:


Response is constructed with list of employees:


This is request URL: http://127.0.0.1:7101/MobileSBProject/HRRestService/employees/w, it can be used from mobile client, to retrieve similar data (department managed by employee 200 is present):


Custom ADF Application with New ADF 12c Alta UI

Tue, 2014-12-30 08:35
I was inspired by recently published WorkBetter application with ADF 12c Alta UI demo (you can read more about Alta UI and download WorkBetter application from here - Oracle Alta UI). I have decided to create my own application, using the same guidelines as described by Alta UI. While WorkBetter application is based on EJB, my application is using regular ADF BC model. Right now it displays a list of employees from HR schema and allows to edit selected employee data. In the future, I plan to add CRUD support and more advanced UI features. I would recommend to watch a video from Shay Shmeltzer, he describes how to build your first Alta UI application in ADF.

Here you can download my sample application, implemented with Alta UI - ADFAltaUI.zip. This application implements ADF task flow with employees data. By default, employees data is displayed as a list (you should see how it differs comparing to pre-Alta ADF UI, now UI is much cleaner and only essential data is displayed):


According to Alta UI guidelines, user should be given an option to switch to a grid view. This is useful and gives different perspective for the data view:


In the grid view there is an option to flip an item to see more details about particular entry - address, manager name in this case:


I'm using ADF quick search component to filter employees data. Quick search offers an option to select search field from the list - this is quite handy and comes out of the box:


User can click on any entry and this will navigate to the edit form. According to Alta UI guidelines, edit form should not be overloaded and must contain only necessary data. Sections must be clear enough to separate different data blocks:


You can switch to the list view, the same filtered data will be displayed in the list:


Let's dive into application code now. I'm using helper bean from WorkBetter application, this bean contains a method to trigger navigation by a hidden button located in the fragment (this is how navigation between fragments is implemented in WorkBetter app):


Quick query component is implemented as a standard ADF query block:


List and grid layout views are implemented as separate items, there is no single special component for this. Dedicated buttons are resetting variables and changing the view, based on the setting - one or another view is rendered:


Both components are implemented inside ADF Faces List, while actual list view layout is implemented inside ADF Faces panelGridLayout and grid view layout inside new ADF Faces Deck component:


Data item selection is handled automatically by ADF Faces List selection listener - row key is set and preserved in Data Control, this allows to reuse the same selected row in different fragments (for example - edit fragment):


I'm using helper Java Script method from WorkBetter application, this allows to trigger navigation from Java Script level. Server listener invokes custom method from the bean, where it is using hidden button to initiate navigation in the ADF task flow from one fragment to another:


Here is this hidden button, used to initiate navigation between fragments:


Navigation is defined in the ADF task flow - between view and edit fragments:


Managed bean is using helper method from WorkBetter class to initiate navigation through hidden button:


According to Alta UI guidelines, toolbar with Save/Cancel buttons must be placed into top right corner (it should not be in the bottom of the page anymore):


Sample application implements a special logic, to keep the current row, after Rollback functionality was invoked. Couple of methods are overriden in the ADF BC VO implementation class (you must set ClearCacheAfterRollback=false option in the AM):

Red Samurai ADF Performance Audit Tool v 3.3 - Audit Improvements

Thu, 2014-12-25 11:13
Christmas present from Red Samurai - ADF Performance Audit Tool v 3.3. This is a next version after 3.2 (Red Samurai ADF Performance Audit Tool v 3.2 - Large Fetch and Full Scan Audit Optimizations) with a set of features improving audit process.

Implemented features in v 3.3:

1. Logging audit data from multiple WebLogic servers

Audit is improved to log data from several WebLogic servers into the same DB schema, Audit UI dashboard allows to select data from specific server or display combined data from all of them. This helps when ADF application is installed in the cluster environment or different application instances are running on different servers.

Changing current audit server address in UI dashboard, to display audit data logged from that server. Here is the example of showing data from all servers, this is by default:


If user selects DefaultServer:7101, data is filtered from selected server only (there are 30 issues displayed):


Select another server - TestServer:7101 and only one logged issue will be displayed:


2. Data Source switch

UI dashboard is capable to switch between different data sources. This is useful, if there are different DB schemas, where audit data is logged. From the single UI dashboard, on runtime, user could decide which audit data he wants to display


3. Option to turn on/off audit globally with -Dredsamurai.audit=on JVM parameter

It is much easier now to turn on/off audit when it is installed in ADF application. This can be controlled with JVM parameter -Dredsamurai.audit=on/off:

Configuring MDS Customisation Layer and Layer Value Combination in ADF

Wed, 2014-12-24 04:07
With this post I would like to dive a bit deeper into MDS customisation and layer combination handling. By default, there is defined customisation layer - site. Typically we set our own customisation values for this layer, as a result - all customisations usually are stored under site layer. There could be situations, when more advanced setup would be required - to be able to control layer and layer value combination in a custom way. In other words - to be able to define your own custom layer and then provide customisation values for this layer (MDS customisations will be stored under custom_layer/custom_layer_value, instead of default site/custom_layer_value). Oracle docs would not describe how to handle on runtime layer name to be dynamic and retrieve it from some sort of configuration file. I'm going to describe a technique for this, allowing to combine and group MDS customisations under custom layer and layer values folders.

Sample application - MDSCustomizationsApp_v3.zip is implemented with a separate JDEV project for MDS customisation files. There is no site layer, it starts with profile1/profile2 and then goes with MDS layer values group1/group2. Layer profile1/profile2 switch is dynamic and handled by custom MDS customisation class implemented in the project. This is how it looks like in JDEV (Customisation Context is set with profile2 name) - MDS layer name is retrieved from a custom JAR file stored under JDEV structure (I will describe it below):


In Oracle docs you would find an example of custom class with MDS layer, where layer name will be set as static. In my sample app, I have implemented it as dynamic - layer name is retrieved from configuration file. Layer name is retrieved and assigned during first application load, it is not reset until the next restart. Here is the example of layer name variable initialisation:


Method getValue is overriden as well, to return different MDS layer customisation values, based on ADF Security.

Method getName is overriden to return MDS layer name on application initialisation. Custom method retrieveDynamicLayerName is implemented to retrieve MDS layer name from configuration file. This method works on design and runtime, this means it can be used for MDS design time seeded customisations:


In order to use custom SiteProfileCC class on runtime, we need to package it into separate JAR file and include this JAR into EAR. In my example, configuration file is packaged together with the class (this would allow to use it for design time MDS seeded customizations):


You must copy JAR file with MDS seeded customisation class SiteProfileCC into JDEV directory - jdeveloper/jdev/lib/patches, this would make it visible for design time MDS seeded customisations:


I have defined multiple MDS layers with layer values. Two layers are used for the test - profile1 and profile2. Each of these layers is assigned with group1 and group2 MDS layer values:


Application must be configured to use custom class SiteProfileCC, this is done in add-config.xml file:


Customisations are implemented in the separate JDEV application, all customisations are deployed to MAR file (we can export them directly and apply to the running instance of ADF application):


MAR file is included into main application deployment profile, under EAR level. You should notice - MDS customisation class JAR file is included to be packaged under lib folder on EAR level (this is important, otherwise application will not be started, because it will fail to load custom SiteProfileCC class):


Let's see how it works. I have provided profile1 for MDS layer in configuration file and redeployed application:


Login with user redsam1, the one granted with Group One role:


Application screen is loaded with customisations based on MDS layer and layer value - read-only table is rendered on the right side:


Login with user redsam2, the one granted with Group Two role:


Customisations for profile1 and group two are applied. Instead of Submit button, Save button is implemented:


Let's change MDS layer to be profile2 and test again with the same users:


User redsam1 gets customisation applied with Jobs block rendered below Employees:


User redsam2 gets customisations with Save and Cancel buttons included:

How To Set EAR Upload Size for Oracle Enterprise Manager

Sat, 2014-12-13 06:29
By default, there is a limit for EAR upload size (~40 MB) in Enterprise Manager. If your ADF application is fairly big, you may face this limitation and will not be able to deploy through Enterprise Manager. Deployment for large EAR would work through WebLogic console, WLST script or directly from JDEV, however sometimes you may need to deploy through Enterprise Manager. I will describe in this post, how you could increase the limit - we are going to extract Enterprise Manager application EAR and change maximum file upload size specified in web.xml.

In my case, the requirement was to be able to deploy ~47 MB EAR file:


When trying to deploy this EAR through Enterprise Manager, I would get the error about maximum file upload size exceeded:


You must navigate to the folder, where applications are deployed for your domain (alternatively, double check in WLS for EM application, where EAR file is stored). There must be one called em.ear, this is the deployment for Enterprise Manager application:


Extract this EAR (make sure to create backup), you will find em.war file inside - we need this file:


Extract em.war file now. Navigate to WEB-INF folder, you will find web.xml file there. Open web.xml file for editing:


Search for org.apache.myfaces.trinidad.UPLOAD_MAX_DISK_SPACE parameter in web.xml and change its value to be large enough to accept the size of EAR file you want to deploy. I have set it to 50 MB = 52428800 bytes:


Make sure to pack everything back, and keep original em.war and em.ear files structure:


After all the are changes applied, large EAR file is accepted in Enterprise Manager and we can proceed with the deployment:

ADF Mythbusters UKOUG'14

Mon, 2014-12-08 09:11
I would like to post the slides from our recent session on UKOUG'14 conference - ADF Mythbusters. This session was presented by my colleague from Red Samurai Consulting - Florin Marcus. The goal was to break popular ADF myths. We have logged Oracle Support SR's, each myth in the slide is assigned with SR number.

Slides are available on SlideShare:

ADF Mythbusters UKOUG'14 from andrejusb
The following topics are covered in the presentation:
  • ADF BC Batches Of Functionality
  • AM Pools and DB Connection Pools
  • Activation-Safe Application Modules
  • Maximum Number of Regions Per Page
  • JSP vs Facelets
More detailed description and analysis data are available in the slides.

Adaptive Case Management 12c and ADF Human Tasks

Thu, 2014-12-04 14:08
I'm diving into the new topic - Adaptive Case Management 12c and ADF integration. Today will be the first post in the category and there are more posts planned for the future. I strongly believe that ACM (Adaptive Case Management) makes a great extension for standard BPM. Mainly because it allows to define a loose process, without strict order steps. Process steps can be executed in different order, depending on the situation requirements, at given time. I will be explaining how to implement ADF Human Task for ACM activity and will share several tips, how to make it run in BPM Workspace application.

This is how sample application (HotelBookingProcessing_v1.zip) is constructed, there are two Human Tasks (AddHotelBooking and ValidateHoteBooking) and HotelBookingProcessing Case control:


HotelBookinfProcessing case is defined with Hotel Booking Details data type (this type is based on XSD schema and is defined as Business Component variable - don't mix up with ADF Business Components) - you can think about it as about main data structure type for the case, this can be transferred into every case activity:


There are two stakeholders defined, this could help to control who could have access to human task and case activity. Customer Service Representative is supposed to add new hotel booking, while Financial Accountant can approve or reject it:


I have created Human Task activity directly through composite, it is not necessary to have BPM process to define human tasks. Important to set Application Context property for Human Task to be OracleBPMProcessRolesApp, this will help later with security roles configuration in BPM workspace:


In order to register human task with Case management, we are given option to promote human task as a case activity. This will allow to initiate human task from the case management:


We can define input and output for the case activity, based on the same data type defined in the case. This will allow to transfer data from the case to the activity, and to the underlying human task in our situation:


You could generate ADF form case data, this form will be rendered in BPM workspace case UI. I'm going to look into customisation options of this kind of form in my future posts (checkbox is set to generate editable form):


This is how case data form is rendered, out of the box is given option to save and reset data for the case - Hotel Booking Details:


Human task form is generated in the same way as it was in 11g - no change here for 12c. You could auto generate this form, it generates a lot of code and I would prefer to build custom light form instead:


Important hint - auto generated human task form will not render in BPM workspace window. You need to change FRAME_BUSTING parameter generated in web.xml from differentOrigin to never. With differentOrigin option it doesn't render human task form, in 11g it was generating with option set to never, for some reason this was changed in 12c - not for good:


With FRAME_BUSTING set to never, human task form renders well:


Human task is started directly from the case activity - Add Hotel Booking from the available list of activities:


We can track in the case activity log - when activity was started, completed or modified. This is quite helpful info to track activity history:


One of the main advantages - user could decide the order of activities, on contrary to strict BPM process. Start Validate Hotel Booking activity, this will create new task for Financial Accountant:


Activity was started, we can see this from the audit log:


This is readonly human task, rendered in BPM workspace - Financial Accountant could approve or reject it:


Case can be closed and hotel booking approved:

Adaptive Form with Dynamic ADF LOV Value Binding

Sat, 2014-11-29 05:25
Previously I had a post about dynamic ADF attribute binding creation and dynamic ADF form generation - Adaptive Form with Dynamic ADF Attribute Value Binding. Blog reader was asking how to generate dynamic ADF LOV binding using similar approach. This is possible and actually documented in Eugene Fedorenko post here - Dynamic LOV binding. I will use the same piece of code to extend my sample application with dynamic ADF LOV binding support.

Here you can download updated sample application - DynamicAttributeBindingApp_v2.zip. This application is updated with LOV definition for JobId attribute in ADF BC:


Once you are generating dynamic components on the UI and getting VO attributes to render, you should not be surprised there will be more attribute entries returned than you can see defined in VO. Additional attributes are for View Accessors, and we don't need them while generating dynamic ADF UI. This can be controlled by checking attribute kind property for attribute definition. If attribute kind is not of rowset kind, we can display it:


There is another method in the sample app, it checks for attribute type. This helps to decide what kind of UI component to render - input text, input date, LOV, etc.:


Dynamic ADF LOV binding is constructed from helper method below, this method is invoked from ADF UI LOV component:


Here is the essential part of the updated sample app - LOV binding creation method. LOV binding is constructed, similar as ADF attribute binding, by pointing to the iterator, LOV server binding name, attribute name and ID:


Dynamic ADF UI components are stamped through ADF UI iterator:


There is a special Facet to support ADF LOV UI component creation. UI component is created by pointing to the helper method, where ADF LOV binding is constructed:


LOV generated dynamically works well on runtime, user can open a list and select a value:


LOV validation also works, try to enter invalid value (not available in the list), user will be prompted to enter existing value instead:

Suppressing ADF LOV Like Operator Filtering V2

Wed, 2014-11-26 01:53
I had a post about the solution to suppress ADF LOV Like operator and prevent LOV popup loading when user is typing existing value - Suppressing ADF LOV Like Operator Filtering. Thanks to a blog reader, there was one use case found, when Like operator was not suppressed properly. This is fixed now and I would like to post updated sample application here.

Additional method is overridden in LOV VO implementation class - applyViewCriteria(ViewCriteria, boolean). Besides previously overridden method buildViewCriteriaClauses(ViewCriteria), this method provides additional handling for LOV Like operator suppression. Download sample application - ADFTableApp_v2.zip.

Blog reader reported an issue, when LOV value was changed to 10, again changed to 100 and again 10, then LOV popup was opened on the last change. This should not happen, as value 10 exists in the LOV. It seems like when LOV value is changed to the same as it was set before, ADF BC executes extra call for LOV filter through applyViewCriteria method. This is why this method is overridden as well as buildViewCriteriaClauses.

Both methods are overridden and check for STARTSWITH (Like) operator is implemented:


It works well now. Try to enter value 10, LOV will accept this value without opening LOV popup:


Enter value 100, this value will be accepted as it exists in the LOV list:


Again enter value 10, it will be accepted as it was previously (it will not be, without overriding applyViewCriteria method):


If I type any value, not available in the LOV list:


As expected LOV popup will be opened and user could select a valid value:

BPM Authentication On Behalf Business User from ADF

Wed, 2014-11-19 01:20
This is the next post in the series of ADF/BPM integration, check previous post available here - Dynamic ADF Buttons Solution for Oracle BPM Outcomes. Here I'm going to describe how you could authenticate with BPM from ADF through a proxy user, on top you could apply only business user name, password will not be required.

There is API method available - authenticateOnBehalf(context, userName), you must have a valid connection context created and with authenticateOnBehalf method you could set to use any valid user name, instead of proxy user. Here is the example for Workflow Context:


Similar example for BPM Context, same authenticateOnBehalf method:


As a proxy user I'm using weblogic. You could set to use any different user and consider it as a proxy user.

Tasks assigned for redsam1, connected through proxy user weblogic, are retrieved and displayed in the table:


This is how you could avoid using password for each business user and simply create initial connection through a proxy user. Download sample application - adfbpm11gr4.zip.

Dynamic ADF Buttons Solution for Oracle BPM Outcomes

Thu, 2014-11-13 13:07
BPM Human Task activity is configured with outcomes. Based on these outcomes, buttons in ADF UI are constructed allowing user to perform different actions with the task. Auto generated ADF Human Task form contains a set of predefined buttons and this set is controller with rendered flag. My sample application is using different approach, it implements custom tasks table and dynamic ADF UI for the human task input form - Dynamic ADF Form Solution for Oracle BPM Process. Once user selects a task, action buttons are generated dynamically - using a set of outcomes configured for the particular task.

Here you can download complete sample application - adfbpm11gr4.zip. This application implements a method based on BPM API, where a list of outcomes by the currently selected Task ID is fetched from BPM engine:


Each outcome is represented by ActionType. I'm constructing a list of outcomes to be used on ADF UI. There is ADF UI iterator components on the fragment, this component is generating dynamic buttons, based on the constructed set of outcomes. Outcome name is used to set button name and outcome itself is used as attribute value for the generic action listener method:


Generic action listener method is responsible to parse outcome name, initialise a payload if needed, and execute BPM API to submit the outcome for further task processing:


We can check how this works. There is a human task AssignEmployee with SUBMIT outcome, in the sample application:


Task action button is generated accordingly - there is only one Submit action button for the selected task:


The next human task ApproveEmployee is set with two outcomes - APPROVE and REJECT:


Based on the set of the outcomes, two buttons are present now - Approve and Reject: