Andrejus Baranovski

Subscribe to Andrejus Baranovski feed
Blog about Oracle technology
Updated: 10 hours 17 min ago

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.

Improved Display for Empty Field Values in ADF Form

Sun, 2017-03-12 04:39
I had a task in the project, to improve display for empty field in ADF form. By default, if there is no row data in the result - all input text entries in ADF form will be hidden, user will see only labels. This is not ideal, most of time users would prefer to see disabled input text boxes instead.

In this example below, on purpose I search for non existing value and this causing form below to become empty. First Name field shows example with disabled text box, the way we want it to be displayed. All other fields display only label - default way:


Let's see how First Name field is changed to be rendered as disabled, when there is no data. I have changed EL for value property. Instead of pointing directly to the binding inputValue (when expression points to standard inputValue and when there is no data - field is rendered as read-only), I point to proxy method in my custom bean. Method is generic and it accepts field name as variable:


Disabled property is changed to return true, when primary key value is empty - this would happen when there are no rows in the result:


No need to change any other properties.

Proxy method is implemented in the bean. This implementation allows to pass parameter to the getter. Parameter - attribute name. Using parameter we are reading value from the bindings. If value is empty - NULL is returned, this makes field empty, but not read-only. When user is changing value - we need to update binding - this is done in put method. Here we get two values from EL - attribute name and actual new value. Think about it as about HashMap element:


With this generic method, there is no need to define separate getters/setters for each UI field. You only need to provide attribute name in EL expression:


Now form is displayed with empty disabled boxes, when there is no result:


When results are available - from displays and allows to edit data:


Download sample application - ADFDataEntryUIApp.zip.

Oracle Java Cloud - How to Create Access Rule for Managed Server

Tue, 2017-03-07 11:40
When you get fresh instance of Oracle Java Cloud, you are assigned with one admin and one managed server. If there is requirement to host multiple environments - demo, production, etc. - one managed server is not enough. Is better to run different environments on dedicated managed servers, this would simplify maintenance. WebLogic 12.2.1.2 partitions are not supported yet for Fusion Middleware, so only choice we have right now - different managed servers per environment.

In this short post, I will describe how to enable access to newly created managed server in Oracle Java Cloud. I have created RedSamuraiProd managed server with port 9075 in our Oracle Java Cloud service instance:


To allow access to port 9075, I need to define new access rule. This can be done through Cloud instance control, select Access Rules from the menu:


In Access Rules section, create new rule. Import here is to specify PUBLIc-INTERNET for source, WLS_MANAGED_SERVER for destination and port for managed server:


Once rule is created, managed server starts to be accessible from the internet. So simple and it works!

Oracle Java Cloud Upgrade to 12.2.1.2

Wed, 2017-03-01 11:51
We finished upgrade of our production Oracle Java Cloud instance to 12.2.1.2. This allows us to use new ADF BC REST features (16.5.2 What You May Need to Know About Versioning the ADF REST Framework).

Upgrade to newer version in Oracle Cloud is similar to on-premise upgrade. We need to create new service instance for software release 12.2.1.2 and later re-deploy our app, re-configure data source and setup security mappings:


12.2.1.2 instance is created in same way as it was before:


Instance is created in three simple steps, last step is just to review configuration:


Give it some 10 minutes to initialize:


And 12.2.1.2 environment is initialized - very simple and much more easier than to configure it by yourself on premise:


We can verify in Cloud EM - JRF 12.2.1.2 is installed, this means it includes full ADF 12.2.1.2 support:

Simple Way to Export Your Data from Oracle Cloud

Mon, 2017-02-27 02:05
You should not get stuck in the Cloud. There are various options to create Oracle Cloud backup, but is very important to keep a local copy of your data. One of the simplest options to create a local copy of data from the Oracle Cloud - use Oracle SQL Developer.

Define Oracle Cloud DB connection in SQL Developer (the same as regular DB connection):


Use Database Export utility from Oracle SQL Developer:


Allows to export schema DDL, together with data (various formats, SQL INSERT statements one of them):


You can choose from long list of DB objects to export, this includes indexes, triggers, constraints, tables, etc.:


In my use case I select all objects to export (except PS_TXN):


There is option to filter exported data, again I will export all data:


Schema structure along with data is exported successfully:

ADF Editable Table - Recommendation For Data Entry Optimization

Fri, 2017-02-17 11:33
I will explain data entry use case related to ADF table. Specifically I will talk about a bit more complex case, when some columns in the table are set with AutoSubmit=true, to force values to be submitted to the server on change. This can be required when validation rule must be processed on value change or there are dependent re-calculated fields in the same row.

If you are using AutoSubmit=true columns in ADF table, it is easy to start loosing values from columns with AutoSubmit=false. Really? Yes - only, if table iterator is set with ChangeEventPolicy=ppr.

Let's do an experiment. First Name column field is set with AutoSubmit=true:


Iterator is set with ChangeEventPolicy = ppr:


Enter value for Last Name, field with AutoSubmit=false:


Change value for First Name, field with AutoSubmit=true and tab away:


Previously entered value for Last Name will be lost and focus will move to table header. Two bad things happened at once. First Name is set with AutoSubmit=true, this means it send value from this field in PPR request, and since table iterator is set with ChangeEventPolicy=ppr, in response it is refreshing table with data from the server. Obviously Last Name new value wasn't sent to server yet (AutoSubmit=false) and ChangeEventPolicy=ppr is reloading values on the client with whatever values are on the server. Technically this is not a bug, but is a critical bug from user perspective - loosing data.

If you have AutoSubmit=true columns in the table, make sure to set ChangeEventPolicy=none for iterator:


This time after changing value with AutoSubmit=true - other field values stay on the client and focus moves nicely to the next field:


When data is saved - changed from both fields are submitted to the DB:


Download sample application - GroovyADFApp_v3.zip.

Setting Invalid Fields for the UI in ADF BC Groovy

Tue, 2017-02-07 10:23
What if you have entity level validation rule and want to attach validation error message to specific field. By default this is not possible - all entity level validation error messages are displayed in the popup and are not attached to the fields (differently than attribute level validation rule messages).

Apparently there is a way to achieve such requirement with Groovy expression, this can be executed from entity level validation - adf.error.addAttribute('Salary'). In addAttribute you need to provide attribute name which will be assigned with the error. Complete expression for entity validator:


Result displayed on UI - validation error message is assigned to the field, which was changed:


Download sample application - GroovyADFApp_v2.zip.

ADF 12c New Groovy API to Work with View Object Methods

Fri, 2017-02-03 04:01
I have interesting topic to share - new Groovy API in ADF to work with View Object, apply View Criteria, execute it. I have discovered it while experimenting with new features and functionality in ADF 12c. Starting from ADF 12.2.1, we have an option to code Groovy in separate file with extension .bcs - ADF BC Groovy Improvements in ADF 12.2.1. This makes sense especially with this new Groovy API - it is more convenient to code/maintain more complex Groovy logic in separate file. As Oracle docs say - Groovy runs faster when it is coded in separate .bcs file, probably there is no need to parse XML to extract and execute expression.

Sample application - GroovyADFApp.zip, contains Groovy implementation for Employees EO:


There is validation rule for Salary attribute coded in Groovy:


Let's take a look into Groovy method, we can open it in .bcs file - for more convenient to review/edit:


1. Method newView gets instance of Jobs VO, within Employees EO context. To get instance of VO with newView, it needs to be defined for programmatic access. This can be done in Model.jpx file, Groovy section.


2. Method copyNamedViewCriteria returns instance of predefined View Criteria. You need to set property ExtAllowUntrustedScriptAccess=true for View Criteria to be accessible in Groovy:


3. Method setViewVariable allows to set value for bind variable from VO. As a rule, bind variable must be assigned with ExtAllowUntrustedScriptAccess=true to be accessible in Groovy.

Let's see how it works on runtime. First it gets VO instance, applies bind variable value and then executes VO. Based on predefined logic, if row is returned - validation is successful:


When validation fails - message is returned:


This Groovy API can be useful when you need to access VO and execute logic directly from Groovy script, without coding Java method.

Contextual Event API Improvements in ADF 12.2.1.x

Sun, 2017-01-29 08:43
ADF 12.2.1.x brings improved API support for Contextual Event implementation - this should simplify Contextual Event usage. Now Contextual Events can be produced without referencing ActionEvent or SelectionEvent, also there is no need to define Data Control to implement Contextual Event handler. Read more in ADF 12.2.1.x documentation - 46.4 Creating Contextual Events Using Managed Beans. I will provide example and explanation how to use these improvements.

Download sample application - ContextualEventApp.zip. This sample is based on two isolated ADF regions - table and chart. When row is changed in the table, through table selection listener method I generate Contextual Event with Job Id payload and send it over, event is consumed in chart region and it allows to refresh chart by key:


Row is changed in the table - new Contextual Event is produced and consumed - chart is refreshed:


We should check in the log - it prints what happens from event initialization to consumption. This gives useful info to debug Contextual Event flow:


Let's jump into code of event producer - method for table row selection (JSFUtils helper method allows to execute table row selection event programmatically, just before producing Contextual Event, this allows to access information about current row). Event is constructed without any event definition in the bindings, directly using method action and event dispatcher API - we can pass payload information directly - no need to describe it in the definition (this is advantage, as sometimes payload definition expression could execute too late and payload could be empty):


Method action definition doesn't represent any real method, it contains event name and acts as helper for event producer:


Consumer region contains Contextual Event handler mapping - it specifies event name and handler info (this is same as before). There is no need to define handler through data control anymore. Method action points directly to the bean method, through instance name. Payload value is sent through using paramVal name and ${data.payLoad} expression:


Consumer receives payload and re-executes VO:

SQL Bind Variable Support in ADF BC REST

Sun, 2017-01-22 10:14
Is not that obvious from Oracle ADF BC REST developer guide how to provide value for bind variable defined directly in the View Object SQL statement. I did research around this and would like to post few hints to make your life easier, if you have same requirement - pass values from REST request to View Object required bind variables. This topic is especially useful, when you want to reuse existing ADF BC implementation for ADF BC REST access.

We are going to use View Object Row Finder. Oracle ADF BC REST developer guide explains how to use Row Finder with View Criteria. In our case we have different situation -  we would like to use Row Finder for required bind variables, referenced directly in SQL statement.

You can't define Row Finder without View Criteria. First trick is to define empty View Criteria, just to be able to define Row Finder - we are not going to use View Criteria functionality, our bind variables are referenced directly in SQL WHERE clause:


Once Row Finder is defined, you are going to see bind variables listed. Keep in mind - this doesn't means bind variables are referenced by Row Finder, they are just listed for possible use. Now main trick - go and define some dummy expression for each bind variable you want to use in REST request (make sure to uncheck - Save expression to groovy file):


This action would generate Groovy expression for each bind variable and list these bind variables under Row Finder. Go to source of View Object to see the structure:


Now remove Groovy expressions assigned to each bind variable - we don't need them, keep only bind variable names assigned to Row Finder:


Visually in the wizard is going to look like there are no changes made - but we keep bind variables under Row Finder tag now:


Bind variables are included directly into SQL statement WHERE clause:


ADF BC REST service is defined in regular way, no special tips here:


This is how REST call looks like: Departments?finder=RESTFilter;depNameVar=IT.locIdVar=1700. We include Row Finder name and two bind variables with values:


In the background we could check ADF BC log, where it prints SQL statement with both bind variables assigned with values:


Download and browse sample application ADFBCRestApp from my GitHub repository - jetcrud.

Multi Language Support in Oracle JET

Wed, 2017-01-18 09:30
There is great post from Geertjan Wielenga about Translating Oracle JET Applications. If you want to introduce multi language support into JET app - this is great place to start reading from. We are building production Oracle Cloud app with ADF BC REST and JET. This app requires multi language support - English and Lithuanian. I will describe below how we integrated multi language into various areas in the app.

Download or browse through sample application in GitHub repo - JETPlaygroundApp.

In JET we could set default language in index page html root tag. By default it is set to en-US, but it can be set to lt-LT for Lithuanian language or any other language:


Translation texts are located in message bundles. There is one default message bundle for English and translations are located in sub folders. English bundle:


Lithuanian bundle with translations for the same message keys:


Multi language bundle support must be registered in main.js (bundle file name can be anything):


Values for all labels/texts must be defined as observables and initialised from JET translation API by passing message key - this will bring default text:


When language is changed, we need to update observable values and reset language value in HTML tag. I'm changing menu labels as well by re-configuring JET router:


On UI in index.html message key is referenced directly from observable variable:


We can access message key defined in appController from individual JET module UI through $parent. For example, I'm using dueDate message key in incidents module:


Same message key is reused in another module - customers:


This is how language switch looks on UI - language change is available in preferences:


When we switch to Lithuanian language - texts are changed (the ones assigned with translatable messages):


Menu labels are also changes, JET Router is reset:


Labels are change in built-in JET components - such as date. Though is not translated completely for Lithuanian language (Today text remains in English):

Oracle JET Router API Example

Sat, 2017-01-07 13:11
One of the examples of JET Router API usage - sign-in/sign-out implementation. After sign-in we need to change menu structure and allow access to application modules, on sign-out menu structure should be changed again. JET Router API allows to manage application navigation and menu structure from JavaScript. Check complete API methods list here - JSDoc: Class: Router.

Sample application code is available on GitHub - JETPlaygroundApp. This application is generated with JET NavDrawer template and is runnable in NetBeans and from command prompt with Grunt. I was using such Yeoman command to generate it:

yo oraclejet JETPlaygroundApp --template=navdrawer

I have changed index page to stretch to entire width and hamburger button to be always available. This is how sign-in module looks like:


After sign-in, user gets hamburger icon to access menu structure:


Oracle Developer Cloud service UI looks similar, it also gets menu list on the left, user can open it with hamburger icon:


Sign-out is available in the drop-down list:


Router API is used in three places in my sample app:

1. Initial sign-in module setup in appController.js. This is executed when application is initialized. Router is configured here with single module - login. Developer should get root instance, configure it with module list and define array with description how each menu item will look like:


2. On sign-in, when login function is called - we get the same root instance of the router. Configure it with new set of modules, one of them is marked as default, define array with descriptions and reset current navigation. At the end we should sync all changes with Router instance, this is done through sync() method call:


3. On sign-out, when logout functionality is called. We reset router configuration with single login module. Login module is set as default. Here we call Router API method go(). Method doesnt need parameter, it will navigate to default module, if no parameter specified. Depending on URL state, if current module before sign-out is default one, URL will not change - this would require to call sync() method to force sign-in module display. If user is on any other module, not the default one - go() method will navigate to sign-in module automatically:

Oracle ADF - Strategic Oracle Technology

Fri, 2017-01-06 09:48
Happy New Year !

There is update for Oracle ADF Statement of Direction dated to November 2016:


You can read full document on Oracle Support site, search for document ID 1985782.1.

To summarise outlined roadmap for Oracle ADF:

1. Oracle continues its commitment to Oracle ADF as a strategic technology

2. Oracle ADF will bring new technologies minimising the negative effect of change (recent examples - ADF BC REST, HTML5 support)

3. In future versions of ADF there will be more focus on JavaScript solutions

4. There are plans for ADF 12.2.1 and beyond

NetBeans Git Client for JET Versioning and Oracle Developer Cloud Service

Thu, 2016-12-29 13:31
I should say I'm happy with how NetBeans Git client works. It offers good performance and resolves conflicts pretty well.

It shows a list of pending changes and also changes colour for changed file name:


Changes can be committed into local repository through informative wizard:


File changes are displayed in very clear way, easy to understand them:


All local changes can be pushed to Oracle Developer Cloud Service Git (or other repository):


Select a branch where to push your work:


Notification about recent update is displayed in Developer Cloud Service console:


We can track changes, do merge requests and merge into trunk in Developer Cloud Service:

ADF BC REST 12.2.1.2 Custom Method JDeveloper Workaround

Tue, 2016-12-27 04:19
Some of you who would try to implement custom method with ADF BC REST may face JDeveloper 12.2.1.2 wizard issue. JDeveloper 12.2.1.2 wizard is refusing to register ADF BC REST custom method, but it works perfectly on ADF runtime. Seems to be JDeveloper 12.2.1.1 - 12.2.1.2 bug. There is a workaround to modify REST service configuration manually and include custom method binding.

Sample application (available on GitHub - jetcrud). This sample implements custom method in VO implementation class - testCall:


Method is exposed through client interface:


Now if you go to REST service definition and try to enable this method to be included into REST interface - JDeveloper will report error:


Something wrong happens in RSTCustomMethodTab class:


Workaround - add method call into REST service definition manually. I recommend to do it outside of JDeveloper, as it hangs. Change definition in external editor. This is the example for custom method entry:


a

If you take a look into JDeveloper wizard for REST definition, it still shows method unchecked. But you can ignore it:


To execute custom method through REST call, make sure to use POST and specify method name along with parameters in REST request body:


Make sure not to forget to provide action Content-Type:


Check section for more info - 22.13.5 Executing a Custom Action.

ADF REST Framework Version 2 (and later) - 12.2.1.2

Mon, 2016-12-26 06:40
While building our new Oracle Cloud application with ADF BC REST and JET, I have discovered not announced feature in ADF BC REST 12.2.1.2. Starting from 12.2.1.2 ADF BC REST offers runtime versions. This is configurable in adf-config.xml file or could be provided through REST request header. ADF 12.2.1.2 supports version 1, 2 and 3. Version 2 offers better query support, while version 3 provides better response for hierarchical data - 16.5.2 What You May Need to Know About Versioning the ADF REST Framework.

You can specify version in adf-config.xml, as per documentation:


Version 2 offers more advanced support for data query. Besides query by example from version 1, we could use advanced query syntax - 22.5.4 Filtering a Resource Collection with a Query Parameter. For example, like operator wasn't supported in version 1:


It is supported in version 2. I could specify version 2 directly in REST request header as in example below:


Download ADF BC REST sample from GitHub repository - jetcrud.

Oracle JDeveloper (SOA and BPM) 12c (12.2.1.2.0) - Download Temporarily Not Available

Mon, 2016-12-26 04:40
If you try to download JDeveloper (as well as SOA Suite or BPM Suite) from OTN - you will see a message on OTN download section - "This page is temporarily not available we'll be back soon".

You should not worry, as per Shay Shmeltzer answer on OTN Forum - "We discovered an issue with the installer - we are working to fix this. Once we have the updated installer we'll update the forum and the pages." Read more here.

There is solution - if you need urgently to download JDeveloper, go to Oracle Software Delivery Cloud and download from there.

Skip LOV Validation for ADF BC Bulk Insert

Wed, 2016-12-21 05:14
This post is about ADF BC LOV. I will describe how you could optimize bulk insert of new rows into VO, when some of the attributes are assigned with LOVs. By default ADF would validate new row attribute value through LOV (LOV Validation and Programmatic Row Insert Performance) for each new row. This will lead to bad performance, especially if you insert a set of new rows programmatically - there will be multiple SQL queries executed to check if LOV attribute value exists.

My colleague found a way to bypass LOV validation when new rows are created programmatically by calling ADF BC API createAndInitRow instead of createRow.

Sample application - LOVValidationBulkInsertApp.zip is developed with LOV for JobId attribute:


We should see first how it works to insert row with LOV attribute by calling createRow ADF BC API:


With SQL log enabled, you should see SQL query executed for LOV, when custom method from above is called:


Now change createRow method to createAndInitRow, to see the difference:


This time no LOV SQL query (for Job Id attribute) executed during new row creation:

JET Application - Generate with Yeoman - Debug in NetBeans

Sat, 2016-12-17 13:53
Let's take a look today how to debug JET application which is initially generated with Yeoman. We could debug in NetBeans, but by default application generated with Yeoman is not runnable in NetBeans, we need to add manually some config files - I will describe how. Also note - JET application created with NetBeans can't be directly served with grunt from command line, it also would require manual changes in the config. It would be nice if Oracle would make JET applications generated with Yeoman automatically runnable in NetBeans and vice versa.

I will go step by step through the process (first I would recommend to go through JET Getting Started):

1. JET application creation with Yeoman and build with Grunt
2. Manual configuration to be able to open such application in NetBeans
3. JET CSS config to be able to run such application in NetBeans

1. JET application creation with Yeoman and build with Grunt

Run command: yo oraclejet basicjetapp --template=basic. This creates simple JET application with one module:


Scripts and various modules are being generated. JET content can be located under src folder - generated application structure:


This is the most simple JET application possible, based on basic template. I have added chart into main page (I'm using Atom text editor to edit JavaScript):


Supporting variables for the chart are created in Application Controller module:


Application Controller module is included into JET main module, where bindings are applied based on Application Controller module and JET context is initialized:


You can build minified JET structure ready for deployment with Grunt command build:release. Navigate to application root folder and run it from there: grunt build:release:


This will produce web folder (name can be changed) with JET minified content:


We could run JET application with Grunt using server:release command: grunt serve:release:


JET application is running:


2. Manual configuration to be able to open such application in NetBeans

To debug JET application generated with Yeoman we would need to open it in NetBeans. Unfortunately this is not available by default. NetBeans doesn't recognize JET project and shows disabled icon:


We need to copy manually NetBeans nbproject folder from any other JET application created with NetBeans into our application root folder:


Change project.xml file and update project name property:


Update web context root in project.properties file:


Update application paths in private.xml file:


After these changes, NetBeans can recognize JET application and it can be opened:


JET application generated with Yeoman is successfully opened in NetBeans:


But there is issue when trying to run application in NetBeans - it can't find JET Alta UI CSS. JET is running, but with ugly look:


3. JET CSS config to be able to run such application in NetBeans

JET application generated with Yeoman points to CSS location which doesnt exist in folder structure:


After we run Grunt command grunt build:release it automatically updates CSS location. This is why it works with grunt serve:release:


Things are a bit different for JET application created with NetBeans. JET application created with NetBeans indeed contains JET Alta UI CSS in the folder originally referenced by JET application created with Yeoman:


I copied this folder into JET application generated with Yeoman:


This time JET application runs and displays as it should in NetBeans:


Don't forget to remove duplicate (we need it only to run/debug in NetBeans) JET Alta UI CSS files folder from release if you run grunt serve:release:


Download sample JET application from GitHub directory - basicjetapp.

Early ADF Model Update with Process Updates Method

Sat, 2016-12-10 12:29
This use case specifically useful for ADF UI value change listener. If there is business logic to be invoked when field value is changed, we can can call ADF BC custom method from assigned value change listener. However new value is not yet propagated down to ADF BC model - we would need to pass it as parameter to custom method. What if want to have new value to be available in ADF BC model without passing new value from value change listener as parameter? This is possible if we call processUpdates method in value change listener, before calling custom ADF BC method.

In my example - ADFProcessUpdatesApp.zip, I have created sample method testCall in VO Row implementation class. This method is accessing salary attribute value from current row. I'm going to call this method through bindings from value change listener and lets see what it will print out:


Let's use value change listener with custom method call without calling processUpdates initially:


Change salary attribute value to call value change listener:


Custom ADF BC method is invoked from value change listener and it prints value before change:


How to get new value in ADF BC custom method, without passing it as parameter from value change listener? Call processUpdates on UI component, before calling custom method in value change listener:


Change value once again:


This time new value is visible in ADF BC custom method instantly, when value change listener is invoked:

Pages