Andrejus Baranovski

Subscribe to Andrejus Baranovski feed
Blog about Oracle technology
Updated: 7 hours 37 min ago

Oracle JET Modular Architecture Example

Tue, 2017-06-27 13:01
One of my favourite parts in Oracle JET - modular code structuring support. This allows to split application functionality into modules and reusable functions. In this post I will show how you could leverage Oracle JET modular architecture not only by implementing common code functions, but also by managing data maintained in common modules.

Let's jump to the example (download or browse through sample code on GitHub repository - JETModularArchitecture). Sample application is based on JET template. I have created two common modules - dashboardChartHelper and dashboardTableHelper. These modules define data structure to be displayed in the dashboard and provide API to manage this data from consuming module:


Both helper modules are imported into consuming module - dashboard:


Dashboard module defines variables (chart and table data), which are initialized from variables assigned with data structures in helper modules:


There are two wrapper functions, calling API functions from helper modules. API provides data manipulation logic, which changes chart data structure. Wrapper functions are invoked from dashboard UI:


Here is the implementation of API functions - data array changes:


What is great about such structuring - data and data changes logic can be encapsulated in common helper module. As soon as we have observable variable defined in consuming module (dashboard), which points to the method helper method (where data is changed) - changes are automatically visible on UI.

Here is the data coming from helper modules rendered in dashboard module:


Press on Add Group E button, this will call helper module API function to update data array cached in that module. In turn observable variable in dashboard module will be updated and data displayed on UI will be refreshed:


Press on Remove Group E button - chart data will be changed again:

ADF BC Attribute - Collection Storage Mode Property

Sun, 2017-06-25 14:45
I would like to describe one interesting property for ADF BC attribute. This property is called Storage. There are two possible values: row (default) and collection. By default attribute value is saved in row storage, but alternatively it can be saved in collection storage. ADF BC implements collection storage using map which comes from session scope. This allows to keep value even between ADF BC requests, this is ideal for transient attributes.

Sample application (ADFBCCheckboxApp.zip) implements VO transient attribute to keep checkbox value:


VO is configured for Range Paging support. While user will navigate through UI table pages - VO range paging will re-execute and this will force VO replace rows (which will result in loosing transient attribute values):


This is how it will look like. User will select checkbox and then navigate to another table page:


After navigating back - checkbox value will be lost (range paging mode will re-execute VO rowset to bring rows belonging to current page):


To force transient attribute value to stay, go to Properties window for the attribute and scroll down to the last section. Select attribute called Storage:


Change value to collection. This will force ADF BC to store value for this attribute in session map:


Transient attribute value will stay, even when VO is re-executed in range paging mode and VO rowset is refetched:

Fixes for ADF Cloud User Experience Rapid Development Kit (RDK) UI Layout Issues

Mon, 2017-06-19 13:45
If you was evaluating Oracle RDK UI template, probably you noticed information popup coming up, when RDK home page is loaded. Popup is loaded through showPopupBehavior listener, which is executed on Welcome page load event. Such popup is not required in practice, and usually is disabled. But as soon as you disable it, there will be layout issues with Welcome page. User information widget will not align the name and menu navigation items will not be ordered correctly:


This is not nice. And you will get such behaviour only when popup is not loaded:


I looked into it in more detail and I saw there is a second HTTP PPR request executed, when popup is loaded. It seems this second HTTP request was triggering partial response and this was forcing UI to load correctly:


Fortunately I found a simple fix for that. Need to set layout="horizontal" for springboard panelGroupLayout component located in Welcome page:


This change makes job done and now Welcome page layout is rendered correctly from the start, even without loading popup and forcing second HTTP PPR request:


There is another issue - related to panelGridLayout usage in ADF Task Flows loaded through Film Strip page. You can check my previous example about customising/extending RDK template - Extending ADF Cloud User Experience Rapid Development Kit (RDK). Let's assume use case with ADF Task Flow implementing two fragments (search and edit functionality):


Search screen renders ADF list implemented using panelGridLayout:


Navigate to edit screen:


Try to navigate back to search screen, you will get empty list displayed:


Fix is simple. RDK is using property stretchChildren="first" in FilmStrip page and this seems to break UI layout for regions with panelGridLayout component:


Remove stretchChildren="first" property from FilmStrip page, showDetailItem component assigned with id="sdi1":


With this fix applied, try to navigate from edit to search:


This time search page layout with panelGridLayout component is displayed as it should:


Download extended RDK application code with applied fixes - AppsCloudUIKit_v3.zip.

Nice Trick to Get ADF LOV Description Text

Wed, 2017-06-14 12:29
I will tell you about nice trick to display LOV description. Usually you would create separate attribute in VO for LOV description and base LOV on this attribute (read about it in my previous post - Defining the LOV on a Reference Attribute in Oracle ADF 11g). But there is one more way - it makes it much faster to define LOV on description, but you should be aware about additional SQL statement executed to fetch description text.

You could set converter for ADF UI LOV, and then LOV component would use description by itself, without any additional configuration.

It is important to set correct order for LOV display attributes. Make sure to set description attribute to be first in the list for converter approach to work:


Go to ADF UI LOV component and set converter property. This must point to binding object, converter expression:


What you get - LOV field displays description, converter is able to mask ID value behind it:


It offers nice usability option - you could start typing description, press tab and value will be auto completed (if autoSubmit is set to true):


Behind the scenes it executes LOV SQL to get description text (this SQL is executed on page load too, which is not ideal when you have many LOV fields - in such situation is better to use separate attribute for description in the same VO):


When LOV value is changed and changes are saved, ADF BC updates ID value only (as expected):


Download sample application - ADFLovDescriptionApp.zip.

Running ADF BC REST Service Together with ADF Faces Application

Sat, 2017-06-03 05:44
ADF 12c provides out of the box support for ADF BC REST API. It is straightforward to create ADF BC REST service and run it. But what if you would like to expose ADF BC REST for existing ADF application with ADF Faces UI. This could be useful if there is a requirement to handle ADF Bindings access to ADF BC along with light ADF BC REST service API implementation for Oracle JET or other JavaScript clients. The same ADF application could handle two types of client access - ADF Faces and REST.

When you create ADF BC REST application, JDeveloper creates REST Model and WebService projects. Technically speaking, if you have existing ADF application with Model and ViewController, you could add third project for REST Web Service by yourself. Two configuration files are required - web.xml and weblogic.xml (if ADF Security is enabled):


ADF BC REST is exposed to the client through ADF servlet. It doesnt work to enable ADF BC REST servlet in ADF Faces project web.xml. This requires to have separate WAR deployment for ADF BC REST and different context root.

ADF Faces and ADF BC REST are sharing the same ADF Security context and this means we are using the same set of Application Roles for both.

In my example, ADF Bindings are mapped with Employees VO instance - this brings data to be displayed in ADF Faces:


The same VO instance is exposed through ADF BC REST:


ADF BC REST servlet is defined in REST project web.xml. It doesnt work to define it in the same web.xml where ADF Faces are configured - context conflict error comes on runtime. Thats the reason why I have separate WAR for ADF BC REST:


There is one WAR for ADF Faces app and one for ADF BC REST. Both WARs are packaged into single EAR. This means there is one deployment, but two context roots, one for each WAR:


If you download my sample app and want to run it, make sure to build REST project first:


Then click Run for ADF Faces app - ADF BC REST WAR will be packaged automatically (if you deploy it on standalone, simply build EAR - it will include both WARs):


We can see it in the deployment log - both WARs are packaged into single EAR:


This is the result - ADF Faces UI is accessed through adfapp context root:


ADF BC REST from the same application is accessed through restapp context root, authenticated with the same ADF Security context as ADF Faces app:


Download sample application - ADFFacesRESTApp.zip.

ADF PopUp Event Context Launcher

Tue, 2017-05-30 02:30
I will describe how you could use ADF popup event context to pass parameters into popup. This could be useful if you want to develop reusable popup, which should accept different type of parameters from various launcher components.

In this example - popup is loaded from context info. Launcher component - output text is assigned with attribute, reading its value from binding. Our goal is to pass attribute value into popup:


In order to be able to read attribute value from launcher parent component, make sure to set eventContext="launcher" for ADF popup:


You can reference parent UI component from launcher property, this can be done in popup fetch listener - where value will be copied to managed bean property:


We could process launcher parent component in managed bean, extract values, etc.:


Value retrieved from popup launcher is displayed in the popup:


Download sample application - PopUpEventContextApp.zip

Oracle JET Hybrid - NavDrawer Template Menu/Header Structure

Thu, 2017-05-18 13:31
Oracle JET provides NavDrawer template for Web and for Hybrid. Read how to create JET Hybrid application based on template - Create a Hybrid Mobile Application. There is significant difference in NavDrawer template implementation when we compare Web and Hybrid application.

Hybrid template draws menu structure on top of the form. Web template is pushing form to the right, when menu is opened. Such approach works fine on the Web, but you would see significant UI lag each time when menu item is selected. Probably thats the reason why hybrid NavDrawer template draws menu on top of the form - visually this provides better performance when switching between menu items. Menu is rendered on the top of the form in JET Hybrid Nav Drawer template:


Form is loaded instantly, when menu item is selected. Header in JET Hybrid NavDrawer template stays fixed, it doesnt scroll. This gives good opportunity to put there common actions:


NavDrawer template in JET Web application moves form to the right, when menu is opened - thats the main visual difference when comparing to NavDrawer Hybrid:


Index page of NavDrawer hybrid template is almost identical to Web NavDrawer, except that it doesn't contain header part. Header is implemented separate module:


I have customized default header implementation with additional items - logo and user preferences:


Header module is constructed in appController, this is how it is generated by default. If we want to have access to variables/functions from appController in the header, we need to create a mapping:


Every module must include div with fixed top JET CSS class (thats why it doesnt scroll and stays on top), where you would copy header code:


Header is bind with module, which is defined by headerConfig variable (must be located in each module) - which is initialized in appController:


Thats all about menu/header implementation.

Let's learn how to push update to Google Play. Make sure to increase application version in Cordova config.xml file:


Go to Google Play and upload new APK, it will be parsed and Google Play automatically will deactivate previous version:


You can initiate roll-out to production:


This will push new release to Google Play. Users will be automatically notified about new version:


Version 2 of our JET Hybrid app is available on Google Play:

Oracle JET Hybrid Mobile Application on Google Play

Wed, 2017-05-10 12:57
Oracle JET Hybrid mobile application can be published to Google Play and installed on Android device. We have tested this process from beginning to the end. Of course JET Hybrid mobile app can be published on Apple Store too, but we are using Google Plain and Android for now.

Where to get started if you want to publish your own Oracle JET Hybrid (open source and free to use) mobile app? First of all you need to build APK (if building for Android) file in release mode. Read about it in my previous post - How To Package JET Hybrid Mobile Application for Release (Android Platform).

Search for JellyHouse in Google Play to install and test our JET app:


You can use demo data account redsam/welcome1 to login and check how JET runs on your Android mobile:


Let's walk through the main steps about how to upload and publish JET APK file in Google Play. First of all you need to login into Google Play Developer console and pay license fee 25 USD (if you are publishing first time). Second, prepare APK file compiled in release mode (read above how to do it). APK file typically is located in hybrid folder, build/outputs directory:


In Google Play Developer console create new application - press Create Application button:


Before you could publish APK to Google Play, you will be asked to complete various forms with information about the app, content rating and upload application graphics:


APK file is uploaded under Release Management -> Artifact library:


To verify upload, click on show details icon and you should see additional information for uploaded APK:


There are options to manage test releases. But you could opt out directly for production - this is what I did. Press publish button and wait about 30 - 60 minutes. Status should be changed to published:


Once published, search for your app in Google Play. Google Play for JellyHouse app:

How To Package JET Hybrid Mobile Application for Release (Android Platform)

Sun, 2017-05-07 11:01
If you want to build/package JET Hybrid application you must issue build:release or serve:release command. Read more about it in JET developer guide: Packaging Hybrid Mobile Applications. In order to run build:release or serve:release commands successfully, you need create buildConfig.json file, which includes information about self signed certificate. This allows to sign application and package it for release.

Steps below are tested for Android platform.

You can generate certificate with Java keytool utility. Navigate to Java home bin folder and run keytool. Specify correct path and preferred alias:

keytool -genkey -v -keystore /Users/andrejusbaranovskis/jdeveloper/mywork/jellyhouse-release-key.keystore -alias RedSamuraiConsulting -keyalg RSA -keysize 2048 -validity 10000

You will be asked to enter additional information, such as name, organization, location, etc.:


Once certificate is generated, you can create empty buildConfig.json file. I have created it in the root directory of JET Hybrid application. Certificate file is copied into the same location:


Provide release information in buildConfig.json. Since certificate file is located in the same folder, it is enough to specify its name without path. Include alias name, certificate password and keystore password:


If buildConfig.json contains correct entries, build:release should run successfully:

sudo grunt build:release --platform=android --buildConfig=buildConfig.json

Successful result output:


JET Hybrid release app built for Android platform size is 7.5 MB (major part takes Cordova libraries):


So, if you create self signed certificate and populate buildConfig.json correctly - it is very easy to run release build for Oracle JET Hybrid application.

Batch Requests Support in ADF BC REST

Wed, 2017-05-03 09:48
ADF BC REST provides a set of enterprise features for REST, one of them support for batch requests. In single REST batch call we can execute multiple update, insert, delete and get operations. This is important functionality, it allows to minimize number of REST calls from the client and improves client performance. Take a read about it in developer guide - 22.13.7 Making Batch Requests.

Batch request in ADF BC REST is executed through POST. You need to specify root URL for REST request, complete path will be set in the payload. Make sure to include batch request Conent-Type:


Request is constructed with different parts, each part describes separate request operation - update, create, delete or get. Path to REST resource is specified too, along with payload if any:


Complete example of ADF BC REST batch request (one for update, create, delete and another for multiple get):

It is important to keep in mind - if one of the batch operations fails, other operations are reverted. In this example, validation fails for create operation - message is returned to the client:


Successful batch request returns back response data for each operation. This is useful, if you want to leverage response on the client - there is no need to do separate REST call to retrieve latest data:


I have logged execution output on the server side. Batch request is executing two update operations, create and delete. At the end single commit is called:


Very useful could be execute multiple get operations in single batch request. We can fetch data for different REST resources in one call to improve performance. In this example fetching data for Employees and Departments:


In response we get data for Employees under part1:


Data for Departments under part2:


Response structure is simple and this makes it easy to parse it on the client.

Access sample application code on GitHub repository - jetcrud.

ADF BC Groovy Expression Security Policy Configuration

Mon, 2017-04-24 13:23
Today I'm going to explain how to configure Groovy expression security policy. This could be helpful, if you dont want to change trustMode property to trusted everywhere across the app, but looking for single configuration point.

My sample app - GroovyPermissionApp.zip, contains bind variable with expression reference pointing towards custom method located in AM implementation class:


JDEV 12.2.1.2 returns compilation error for Groovy expression, can't resolve applicationModule property:


Such kind of checks can be disabled in Model project configuration. Uncheck option for Groovy Expression Type Validation:


JDEV 12.2.1.2 by default creates Groovy expressions in untrusted mode. If you change it to trusted, expression would work OK. However, if your app contains many expressions like this, you may want to ignore trustMode property:


If you run ADF BC tester in JDEV 12.2.1.2, it will show error text in the log for untrusted expression. ADF BC tester will fail to start, if there is any error - we logged this issue with Oracle Support. Property applicationModule can't be resolved, when trustMode is set to untrusted:


To disable this check, we can create new class extending ExprSecurityPolicy class. Override checkProperty method to allow calls to applicationModule property:


This class should be registered in adf-config.xml:


Try to run ADF BC tester again. Error about applicationModule will be gone. This time it will complain about permission error to call getCurrentRegion method:


Method access can be granted by annotation in AM implementation class:


ADF BC tester runs, and returns VO row data:

Production Mobile App with Oracle JET Hybrid in 2 Hours

Wed, 2017-04-12 22:58
Do you want to know a secret, how to build mobile application just in 2 hours? Use Oracle JET Hybrid. Beauty of Oracle JET Hybrid - you can reuse the same source code (HTML and JS) from regular JET application. JET UI is responsive out of the box and this allows to render JET screens from the Web on mobile device without changes.

We were using our JET 3.0.0 production app - Red Samurai and Oracle PaaS JCS Success - JET/ADF BC REST Cloud Production Application and created mobile app version. This process took around 2 hours.

Below I will list steps required to create JET Hybrid mobile app out of existing JET app.

1. Execute sudo npm -g install cordova to add Cordova to JET tooling

2. Execute sudo yo oraclejet:hybrid --platforms=android to create new JET Hybrid application. Windows and iOS are supported as well

3. Copy HTML and JS files from src folder of JET app into src folder of JET Hybrid app. Structure of JET Hybrid app with HTML and JS files:


4. Execute sudo grunt build --platform=android to compile JET Hybrid app

5. Execute sudo grunt serve --platform=android --destination=device to deploy JET Hybrid app to mobile device. If you are deploying to Android, you need to have Android tools installed on your machine

Dashboard screen on mobile device, built with JET data visualization components:


Customer setup screen contains JET search list and various input components with validation:


JET dialog looks good in mobile too, with input number fields:


JET input date component on mobile screen:


JET table with pagination is rendered very well and is easily usable on the small screen:


I should say - we are very happy with JET Hybrid functionality. It allows to reuse JET application code and build mobile app very fast.

Oracle JET 2.2.0 Application Migration to JET 3.0.0 Experience

Wed, 2017-04-12 00:28
I was migrating our production JET app from 2.2.0 to 3.0.0. End-to-end migration process took probably around 1-2 hours - with testing. I think this is quick. JET migration is not hard if you follow developer guide instructions - B Oracle JET v2.x.x to v3.0.0 Tooling Migration.

Migration from 2.2.0 must be done in two steps:

1. Migration to 2.3.0 from 2.2.0

2. Migration to 3.0.0 from 2.3.0

Step 1: Migration to 2.3.0 from 2.2.0

- Execute sudo npm install generator-oraclejet@2.3.0 -g to update Oracle JET to 2.3.0

- Execute sudo yo oraclejet ChBJellyHouseInvoicingJET230 to generate brand new JET 2.3.0 application

- Copy html/js files from existing application src folder into new one

- Update JET version number in index.html:


- Update JET version number and add additional library references (as per JET Developer Guide) in main.js:


- Update same set of libraries and versions in main-release-paths.json:


- Execute sudo grunt build:release to verify in migrated app build process succeeds:


- Execute sudo grunt serve:release to run application:


Step 2: Migration to 3.0.0 from 2.3.0

- Execute sudo npm install generator-oraclejet@3.0.0 -g to update Oracle JET to 3.3.0


- Execute sudo npm uninstall grunt-oraclejet oraclejet-tooling

- Execute sudo npm uninstall grunt-bowercopy --save-dev

- Execute sudo npm install grunt-oraclejet@3.0.0 oraclejet-tooling@3.0.0 --save-dev

- Execute sudo npm install oraclejet@3.0.0 --save

- Execute sudo npm uninstall bower -g to remove Bower, it is not needed anymore from JET 3.0.0

- Remove the following file from your system: scripts/grunt/config/bowercopy.js

- If you have no third-party dependencies remaining in your bower.json file, remove it

- Update JET version number in index.html:


- Update JET version number and add additional library references (as per JET Developer Guide) in main.js:


- Update same set of libraries and versions in main-release-paths.json:


- Execute sudo grunt build:release, most likely you will face error. Same was documented by someone on OTN Forum - v3.0.0 - Error with Grunt build and serve tasks with initConfig() in Gruntfile.js:


- To fix this error, add oraclejet-build.js and oraclejet-serve.js into scripts/grunt/config (you can copy these files from newly generated JET 3.0.0 app):

ADF Multi Task Flow Binding and Tab Order

Sun, 2017-04-09 19:47
I had a post while ago about ADF multi task flow binding and loading dynamic regions - Building Custom UI Shell with ADF 11g R2. In that sample, new region was opened in the first tab position. Meaning tab order was from right to left. It is more natural to have left to right tab opening order. This can be done too, check updated sample app - we need to control disclosed property and add new region to the end of array.

Sample app - MultiTaskFlowApp_TabOrder.zip. Sample app contains four regions that can be opened dynamically. Let's say user opens region Locations:


With improved tab order, next region will be opened in the tab on the right (before it was on the left, in the first position):


Tab closing works in the way. Let's say user wants to close second tab:


When tab with Departments is closed, next tab on the right is opened - Employees tab:


Key thing in implementation for this requirement - disclosed property in dynamic tab:


It calls bean method, where it evaluates current tab to be disclosed. If given tab is matching the value - it will be disclosed. Disclosed property for all other tabs will be reset:


Each time when new tab is loaded, it is loaded to the end of the array. New tab is set to be disclosed:


When user selects tab - currently disclosed tab property is updated too, to make sure info about new disclosed tab is stored:


One more case - tab closure. When tab is closed - next tab is selected, unless current tab was the last one:


When tab is selected programmatically, we update information about current selected tab too:

Workaround for ADF BC View Object Attribute Order Problem in JDeveloper 12c

Thu, 2017-04-06 21:23
I'm sure probably every ADF developer sooner or later faced this issue. When you create VO based on EO, JDEV gives you alphabetically ordered list of attributes. As a result - order of attributes in EO and VO becomes different. While this doesn't influence runtime functionality, it becomes quite annoying for application maintenance. Hard to match attributes between VO and EO, developer need to search through the list to locate attribute he is looking for. But there is a workaround, I will describe it here.

Let's see what the problem first. Assume we have Employees EO, attributes are generated in the same order as DB table columns:


Now if you are using VO creation wizard, list of attributes will be displayed in alphabetic order. This is frustrating:


Without any other choice, developer would select EO attributes and select them in such order as it is listed:


But wait, there is a workaround. Don't select all attributes, instead select only EO item itself. Then use Add button to add entire list of EO attributes:


This time attributes will be added in original order, as the order is set in EO.


Enjoy this small, but useful hint.

Slides from Oracle PaaS Forum 2017 - Oracle JET and ADF BC REST Production Experience with Oracle Java Cloud

Sun, 2017-04-02 01:56
My colleague Florin Marcus (twitter: @FlorinMarcus) was attending and presenting at Oracle PaaS 2017 forum in Split, Crotia last week. He was explaining our production experience with Oracle Java Cloud Service and running Oracle JET/ADF BC REST system on Cloud instance.

Slides are uploaded on slide share, you can go through and read about real production app built with JET and ADF BC REST running on Oracle Java Cloud. If you are interested in more details - let me know, I could show a demo:



Exciting news from Oracle PaaS Forum 2017 - Red Samurai won award for Outstanding Java Cloud Service Contribution 2017:


This award was received for implementing Oracle JET/ADF BC REST app and running it on Oracle Java Cloud in production. Read more about it - Red Samurai and Oracle PaaS JCS Success - JET/ADF BC REST Cloud Production Application.

Oracle JET Slider in Foreach Loop

Wed, 2017-03-29 13:55
While working in the project last week, I had a question from development team - how to render multiple Oracle JET Slider components in foreach loop. I thought this could be useful tip for other developers too.

You can get JET sample app from GitHub - JETSliderSample.

Take a look into dashboard.js, I have defined array with two elements, containing variables (value property variable must be observable, otherwise it will not receive changed data) required to initialize JET slider. Each array element, defines slider to be rendered in HTML. There is JS function which prints array content, it can be useful to access changed slider values:

HTML implementation contains foreach loop pointing to array from JS module. Each loop element prints JET slider. JET slider properties must be mapped with variables from array elements, otherwise slider would not function (if you are using it inside foreach loop):

This is how UI looks like. Multiple slider components are displayed through foreach loop. User can adjust slider values and print new values in JS function (hitting Submit button):

Oracle JET Tooling Migration from 2.2.0 to 3.0.0

Fri, 2017-03-24 12:35
Oracle JET 3.0.0 was released this week and I decided to migrate my local JET tooling from 2.2.0 to 3.0.0. Oracle JET developer guide provides well documented instructions for migration - B Oracle JET v2.x.x to v3.0.0 Tooling Migration. I was following outlined steps and tooling migration was smooth.

Migration from 2.2.0 to 2.3.0

Clean cache for bower and npm:


Install JET 2.3.0:


Migration from 2.3.0 to 3.0.0

Install JET 3.0.0:


Thats it - in three simple steps tooling was upgraded to 3.0.0.

Now we can create JET 3.0.0 app with Yeoman (follow instructions list in JET Getting Started guide):


I prefer to use NetBeans for JET application development. I already had a post about how to open JET application generated in Yeoman for development in NetBeans - JET Application - Generate with Yeoman - Debug in NetBeans. Let me go through this once again. NetBeans provides handy option to open HTML5/JS with existing sources:


We need to point to source folder, project directory and site root:


Make sure to point start file to index.html, NetBeans will ask this info when you try to run app for the first time:


To be able to run JET 3.0.0 application generated with Yeoman in NetBeans, you would need to copy two folders (create another app directly in NetBeans and copy from there):

1. Copy folder js/libs:


2. Copy folder css/libs:


Later when you build minified version of your app, css/libs folder can be removed:


JET 3.0.0 sample app is running:


In my next post I will explain how migrate existing JET 2.2.0 app to JET 3.0.0.

Red Samurai and Oracle PaaS JCS Success - JET/ADF BC REST Cloud Production Application

Mon, 2017-03-20 00:34
I would like to share our success in Oracle PaaS service - Java Cloud (JCS). We have managed to implement JET/ADF BC REST system in short period of time and deploy it in production running on Oracle JCS. UI is implemented entirely with JET, while back-end REST services are running on top of ADF BC. Secure access is controlled by unique ID managed by server side ADF Security.

Production application implements custom invoice processing logic for startup candy factory/distributor in Lithuania. Oracle Cloud doesn't require administration and provides all mandatory services to run custom application. This is primary reason why decision was made to use Oracle Cloud. In the next phase we are going to implement warehouse management logic, tightly integrated with invoice processing.

JET UI

Home screen displays dashboard with financial data for orders, customers and invoice items:


Menu structure (JET Router) is focused around implemented business logic:

1. Dashboard - statistical data display
2. New Invoice - invoice creation module
3. Template Setup - invoice template setup, to speed up invoice creation
4. Invoice Search - search through all invoices
5. Customer Setup - customer data management
6. Supplier Setup - supplier data management

Invoice Search screen implements form block and results table with pagination. This screen is using a set of JET components, starting from input list to responsive UI:


User have option to select invoice for editing. Various invoice fields can be changed in this screen. UI remains responsive and can be rendered on mobile device or JET Hybrid application - this was one of the key requirements:


Invoice items are edited in JET dialog. This is very convenient approach, JET dialog works really fast and allows to switch from one item to another in a quick way:


Development process - Oracle Developer Cloud Service

Application was developed using Oracle Developer Cloud Service. We think Agile boards/sprints defined in DevCS are really helpful. Offered functionality simplifies task management/monitoring process and you can see the progress in the sprint:


DevCS provides Git source control repository, agile board and issue tracking. It also gives you Build Automation. We were using Build Automation to re-build changes committed in ADF BC REST repository:


After build process completes - there is a an option to redeploy latest EAR package directly to JCS. This helps to save time, no need to repeat redeployment routine steps yourself each time when new build completes:


Application Structure

Application is divided into two parts (two separate deployments): ADF BC REST and JET UI implementation.

ADF BC REST implements back-end REST services and provides authentication/authorisation control. We are using regular ADF BC development, together with REST interface provided out of the box starting from ADF 12.2.1:


JET UI application is following modular architecture approach. Each use case is implemented in separate module. Common logic (REST service definition, etc.) is moved out into controller modules. Client side business logic is implemented in JET module JavaScript functions and rendered with JET UI components:


Oracle Cloud Deployment

We are using Oracle Java Cloud Service instance to run both ADF BC REST app and JET. ADF can't be deployed to Oracle Application Container Cloud service, but you can host JET from Java Cloud. For this reason it was more sense for us to use only Java Cloud and run both server side and host client side from the same instance.

Both demo and prod environments run from the same Cloud instance, targeted to different Managed Servers (to simplify maintenance):


If we take a look into application runtime statistics, ADF BC REST application mainly executes ADF REST servlet (to produce REST request response), our custom PDF servlet and ADF authentication servlet to execute session logout:


JET wrapper application doesn't run any server side logic, it simply return JET application content to the client - only File Servlet is invoked in operation:


Performance

JET runs on client side, there are much less server side calls comparing to ADF Faces application. In this example we change invoice status to Submitted. In result several REST calls are executed, each running below 100 ms. and transferring just a bit of info. Key difference between JET and ADF Faces - REST call doesnt block client functionality. REST call may execute asynchronously and user can continue to work with the application:


In the example below, we navigate to invoice list screen. Invoice MAR-36 status was changed to submitted, invoice line data is re-fetched to display up-to date information in the table for particular row. Invoice row data is re-fetched below 100 ms.:


Let's check navigation in the table. We navigate to the last page. REST request is completed in around 100 ms., and it returns only a set of rows for the last page:


When user log's our from JET application, we execute request for adfAuthentication servlet with parameter logout=true. This allows to close ADF BC REST session on the server side:


Summary

1. JET UI and ADF BC REST server side can be used in production system

2. JET UI and ADF BC REST runs great on Oracle Java Cloud

3. Oracle Developer Cloud Service is useful for JET and ADF development

Significant Improvement for WebLogic Start-Up Time on macOS Sierra

Tue, 2017-03-14 11:59
I have faced really slow WebLogic start-up times after upgrade to recent versions of macOS Sierra. It turns out to be common problem related to JVM start-up on macOS systems, nothing to do with WebLogic itself. Solution is to register mapping between 127.0.0.1 and your computer name in hosts file, read more on Stack Overflow - Jvm takes a long time to resolve ip-address for localhost. This issue seems to appear with newer JVMs.

Originally WebLogic was starting up in 157 seconds:


After config was applied in hosts file, start-up time improved a lot, it is 24 seconds now:


Changes in hosts file - 127.0.0.1 was mapped with my computer name, along with localhost. Same applies for ::1 mapping:


You can get computer name in System Preferences -> Sharing:


Hope this hint will be useful for those developers, who are working on macOS.

Pages