Friday, July 19, 2013

ADF 12c: Model-Driven LOV with Bean Data Control


Introduction

Prior to ADF 12c Model-driven input List-Of-Values (LOV) was a feature exclusively reserved to the ADF BC DataControl. With ADF 12c the Bean DataControl has been enhanced a lot. Now it is possible to create input LOVs the declarative way.

Prerequisites
You have a plain Java Object Model, for which you want to build the UI, including an LOV. In this sample we use Person, Address and a PersonService, which we want to expose as a DataControl
The adressId of Person should be filled through a LOV from available Address-Entities.

How to do it

First, create the DataControl from the PersonService: Right Click the PersonService.java class and Choose: Create DataControl


For this purpose, just keep the defaults in the wizard and complete with "Finish"

Open the generated DataControls.dcx, Select the Collection Type person and choose 'Edit'

The metadata file for the Person entity will be created. Next open the generated metadata file and configure the LOV on addressId as follows

Now the LOV is already configured and could be used for the UI Creation. If needed the LOV can be refined with UI Hints (as known from the ADF BC LOVs)

Now you can go on an build the UI. Drop the persons collection from the Data Control Palette onto the Page and
choose "ADF Form":

As indicated an ADF LOV Input will be crated for the addressId attribute. It can be further adjusted if needed in the next wizard screen

The LOV has been created

and can be tested at runtime.

The LOV Popup contains a query panel to limit the given values. As a wildcard only % is working. no Asterisk (*) what I personally would prefer. Anyway the LOV works as expected. In the sample the adressId is filled correctly.

Validation also works by default. If you try to enter an invalid value an error message pops up.

Download


Further Reading

Wednesday, June 19, 2013

Production Redeployment with ADF Shared WebLogic Libraries


Based on my previous post I wanted to know if we can achieve to redeploy parts of an ADF application by using shared WebLogic Libraries. In conjuction with the production redeployment WLS feature the overall goal is to prove that we can update modular ADF applications without downtime.

Introduction

The sample application consists of an employees taskflow that is bundled as ADF Library and deployed as shared library on WebLogic server. The sample is based on ADF 11.1.1.7 / WLS 10.3.5 / HR Schema.

First step: Create ADF Library as Shared WAR deployment

Goto JDev application with the containing Taskflow:

Create a MANIFEST.MF file under ViewController/src/META-INF/ with the following contents
The important parts are

Extension-Name: enpit.sample.empFlow
Specification-Version: 1.0
Implementation-Version: 1.0

Create ADF Library Deployment Profile for the empFlow on ViewController project with dependency on your Model project.
Make sure only connection name is Included in the Library

Having an ADF Library Deployment Profile in the employee taskflow application we create an additional Deployment profile (of type WAR) in the ViewController project. 

Under  WAR Options include the MANIFEST.MF file

Make sure to remove everything from Web Files contributors since we only want to wrap the ADF Library inside this WAR file.

Same to WEB-INF/classes. Exclude everything.

Under Profile Dependencies add the dependency to the ADF Library Profile

Goto WEB-INF/lib Filters and uncheck everything except the desired ADF Library JAR file.

With that WAR deployment configuration we are able to deploy -  the ADF Taskflow -  as shared library to the WebLogic server. (Select ViewController, right click, Choose Deploy > SharedADFLib ...to Application Server)

As a result the library shows up under Deployments in the WebLogic Admin Console

Deploy master application

In the master application that consumes the taskflow from the ADF Library we need to make sure
  • versioning is configured for application deployment
  • ADF Library is not bundled with the EAR
  • Library reference is added to the ADF Shared Library in weblogic.xml (not weblogic-application.xml)
To enable the versioning for the app deployment we add /src/META-INF/MANIFEST.MF file with the contents
Manifest-Version: 1.0
Weblogic-Application-Version: 1.0

Now goto the EAR deployment profile and add the MANIFEST.MF file under the EAR Options

Goto application descriptors Filters and exclude MANIFEST.MF. (Otherwise the EAR won't be created as JDeveloper will try to include 2 MANIFEST.MF files in the EAR. You will see this exception in the deployment log window).

Now exclude the ADF Library from the application deployment. Goto ViewController project properties of the master application and make sure the library is not deployed by default.

In the WAR deployment profile check that the ADF Library JAR is not included


Next create WEB-INF/weblogic.xml and add library reference to the ADF Shared Library.

Important note: In my first try I added that library reference in the weblogic-application.xml. That won't work. At deployment time there will be the following exception
[08:23:54 AM] [Deployer:149034]An exception occurred for task [Deployer:149026]deploy application enpit_application1 [Version=1.0] on DefaultServer.: javax.faces.context.ExternalContext.
[08:23:54 AM] Weblogic Server Exception: weblogic.application.WrappedDeploymentException: javax.faces.context.ExternalContext
[08:23:54 AM]   See server logs or server console for more details.
[08:23:54 AM] weblogic.application.WrappedDeploymentException: javax.faces.context.ExternalContext
[08:23:54 AM] ####  Deployment incomplete.  ####
[08:23:54 AM] Remote deployment failed (oracle.jdevimpl.deploy.common.Jsr88RemoteDeployer)

So don't try this.

Doing it right you should see the following in Admin Console:

Test the application. It loads the taskflow and displays version 1

Next Step: Test production redeployment based on new version of ADF Shared Library
We are going to 
  • Make changes in employees taskflow
  • Change Library Implementation-Version to 1.1
  • Deploy ADF Library as Shared WLS Library
  • Increase application version to 1.1
  • Redeploy master application
So first we increase the library version
and make some simple changes to the JSFF

Next: Deploy ADF Library to JAR
Next: Deploy sharedADFLib Deployment to IntegratedWebLogic

Check deployment in the Admin Console

Goto the master application and change Weblogic-Application-Version to 1.1

and deploy the master application to Verify deployment in the Admin Console once again. You should notice that previous application (1.0) is in stop running state. Actually it is meant to be RETIRED Mode. Existing web sessions will be served by that version 1.0.

Open a NEW BROWSER WINDOW (a different browser window to be dead sure) and point to the master application URL. You should see new version of the integrated Taskflow.

Conclusion

This mechanism is really powerful. It lets you redeploy application parts - maybe of a huge application - without downtime.

Download Sample Application


Related Posts

Thursday, June 6, 2013

WebLogic Application redeployment using shared libraries - without downtime


Environment
Oracle WebLogic 10.3.6

Use Case
An application that depends on custom shared libraries needs to be redeployed without downtime. That means without interrupting the availability of the application to existing and new clients. Since production redeployment is not available for libraries we need to think about a different approach.

Precondition

A shared library (as war) is deployed (state: active) and targeted to - for simplicity say - AdminServer with the following version settings:

Extension-Name: enpit-common-war-lib
Specification-Version: 1.0
Implementation-Version: 1.0.4

An application references that library in its weblogic.xml in the following way:
<?xml version='1.0' encoding='UTF-8'?>
  <library-ref>
       <library-name>enpit-common-war-lib</library-name>
  </library-ref>
</weblogic-web-app>

The library is referenced without any version information. That means it will reference the highest available deployed library version. That application is successfully deployed and also targeted to AdminServer. Its state is active. It is working correctly, accesses Java classes in the shared library.

Problem

Trying to deploy the existing library (not changing the version information) once again 

java weblogic.Deployer -adminurl t3://eden.local:7001 -username weblogic -password welcome1 -upload -library -targets AdminServer -deploy -source enpit-shared-lib-war.war
results in the following error:

Cannot undeploy library Extension-Name: enpit-common-war-lib, Specification-Version: 1, Implementation-Version: 1.0.4 from server AdminServer, because the following deployed applications reference it: enpittestcommons-reflib.war

=> Makes sense!

Solution Trial 1
We change the MANIFEST.MF of the Shared Library that has to be redeployed to
Implementation-Version: 1.0.5   (the deployed one has 1.0.4)

Lets see what happens

Task 17 completed: [Deployer:149117]deploy library enpit-common-war-lib [LibSpecVersion=1.0,LibImplVersion=1.0.5] on AdminServer.
Target state: deploy completed on Server AdminServer

=> We succeeded. Have a new version deployed!

Question 1
Which version is our running application now using?

Well, the application still uses version 1.0,1.0.4 although it is specified that the highest version should be used. To conclude: The application does not dynamically adopt to the new library version. I think that is good. Otherwise it would be much magic happening in the background.

Question 2
We stop the running application. Now the application shows up in the admin console in state "prepared".
Lets start it again. ... It moves again to state "active".

Which version is our running application now using?

Well, In my simple use case I changed the returned string in the library class to "1.0,1.0.5" according to the new library version. And indeed, my sample app shows the right information.
Library-Version: 1.0,1.0.5

Conclusion: That's a powerful way to update dependencies for an application. All you have to do is just restarting the application. At the time of restart the new version of the library is picked up! Further: we are able to undeploy the unreferenced "old" library (in my case 1.0,1.0.4). Everything works as expected except the use feedback at the admin console looks inconsistent. Selecting the Library no referenced applications are shown in the corresponding section


Question 1
How about production redeployment for the application in that scenario? It would mean that the application would have NO DOWNTIME. So lets give it a try. I have undeployed the sample app and deployed it as follows:

java weblogic.Deployer -adminurl t3://eden.local:7001 -username weblogic -password welcome1 -upload -targets AdminServer -deploy -source enpittestcommons-reflib.war -appversion 1.0
Note: That the web application shows up with a version information.

Next: We are going to update the library to impl. version 1.0.6

Task 24 completed: [Deployer:149117]deploy library enpit-common-war-lib [LibSpecVersion=1.0,LibImplVersion=1.0.6] on AdminServer.
Deployment succeeded!

Next: Instead of restarting the web application we Redeployit with "-appversion 1.1"

Log: weblogic.Deployer invoked with options:  -adminurl t3://eden.local:7001 -username weblogic -upload -targets AdminServer -deploy -source enpittestcommons-reflib.war -appversion 1.1
<05.06.2013 19:14 Uhr MESZ> <Info> <J2EE Deployment SPI> <BEA-260121> <Initiating deploy operation for application, enpittestcommons-reflib.war#1.1 [archive: /Users/ak/Dropbox/community/doag/doag-2013-imc/use-shared-lib-app/enpittestcommons-reflib.war], to AdminServer .>
Task 25 initiated: [Deployer:149026]deploy application enpittestcommons-reflib.war [Version=1.1] on AdminServer.
Task 25 completed: [Deployer:149026]deploy application enpittestcommons-reflib.war [Version=1.1] on AdminServer.
Target state: deploy completed on Server AdminServer

Now we test the existing connection. It still shows
Library-Version: 1.0,1.0.5

Further open a new Browser and target to the same web app URL gives me :

Library-Version: 1.0,1.0.6

After sessions timed out, we get the following picture

Conclusion

Shared Libraries on WebLogic Server in conjunction with "production redeployment" is a really powerful feature. Applications can upgrade to a library version without downtime!

Next I would like to check if same is possible with shared ADF Libraries. That way it would be possible to update separate application parts (deployed as ADF Libraries) without downtime. Would be really cool!

Sunday, May 26, 2013

ADF: Static Values View Object does not show any values (solved)


Environment
ADF/JDEV 11.1.2.4

Problem description
After creating a ViewObject of Type "static values" and running an instance inside the Business Components tester I noticed that no values are displayed at runtime! From the navigation action it looks like there are exactly as many rows that has been created, but whatever row is displayed, all values are empty!


Analysis
Looking in depth I noticed that the reference to the resource bundle where the static values are coming from, is invalid. The path does not match the actual source for the properties file although the static values ViewObject has been created by the JDeveloper Wizard

Solution
Short term solution is to manually adjust the value of the attribute PropertiesFile of the corresponding ResourceBundle.

So if the Property file is under src/enpit/sample/adf/transientvoascriteria/modelBundle.properties set the value to PropertiesFile="enpit.sample.adf.transientvoascriteria.modelBundle"

Rebuild and restart the BC Tester to verify that everything is working as expected:


Remark
The reason for the mismatch I guess is because JDeveloper does not handle everything correctly if having dots in project names. So take care if you use JDeveloper project names like 'MyApp.Model'. Double check references to the property bundle!



Saturday, April 6, 2013

ADF 11.1.1.7 New Feature: HTML5 Placeholder


Many of us have waited for it some time now. With the arrival of ADF 11.1.1.7 the Input components have got a new attribute: placeholder.

Use Case
Provide a prompt text inside an input component.

Usage

In order to use this feature just fill in the newly added attribute from the property inspector or directly in the source code.


On runtime it is properly rendered as placeholder-HTML5 Attribute.

Works on all modern browsers ;)

Wednesday, February 20, 2013

JDeveloper Code-Template for ADFLogger


 Environment: JDeveloper 11.1.1.6

To make the Logger-Declaration a not so tedious work you can make use of JDeveloper Code Template features which is available in the preferences.
In JDeveloper:

1. Open from the menu: Tools > Preferences
2. Open: Code Editor > Code Templates
3. Click "+" to add a new code template


4. Goto the Code-Tab and add the following:

private static final ADFLogger LOGGER = ADFLogger.createADFLogger($clazz$.class);

5. Goto Imports-Tab and add needed classes:

oracle.adf.share.logging.ADFLogger

6. Confirm Changes by clicking 'OK'.

=>> The Code-Template 'logger' is now available inside the Java-Editor.


Using the Code-Template in JDevelopers Editor

1. Open a Java class
2. Place cursor right inside class definition, type 'logger' and press 'Ctrl+Enter'.


Afterwards the ADFLogger is available inside the Java class.


On the following Blog posts you can find more information around ADFLogger + a CodeTemplates XML which you can import in your JDeveloper.

More information