place your title here - 42 Technology for Enterprise Java, Oracle and ...

translatoryazooInternet και Εφαρμογές Web

12 Νοε 2013 (πριν από 4 χρόνια και 1 μέρα)

134 εμφανίσεις

ww
w.odtug.com

1

ODTUG Kaleidoscope 2008

ADF

D
EVELOPMENT
:

L
IVE FROM THE TRENCHE
S

Aino Andriessen, AMIS Services


Introduction

With release 10,

the Oracle

ADF
(Application Development Framework)
has really taken off. It is the foundation of Oracle
Fusion

and
is
largely
based on
Enterprise Java

in
dustry standard
s
. It can provide a
great productivity boost to
enterprise
Java

application development
.

We have successfully used ADF for large enterprise applications. With this paper, and presentation,
we'd like to share some of our experiences.

Basicall
y
, ADF consists of three parts :
ADF Business Components
(BC)
, that can be considered to be an object
-
relational
framework to provide access to the database,
ADF Faces
, Oracle's JSF implementation and
ADF Model

(also known as
binding)

that kind of
'
glues
'

ADF Faces to ADF Business components
. Development is done with JDeveloper.

General development principles

Basically, ADF development is just software engineering

and the same rules about project management, programming,
maintenance

etc. still
apply. A few
aspects may have so
me extra attention.
Because

ADF is an Oracle framework and offers a
declarative way of development, it seems the logical next step for 'traditional' (Forms, Designer, PL/SQL) Oracle developers.

With some training and coaching, this is in
deed a very conceivable option. But this is not enough because web applications
are quite different from Forms application and Java programming is not a skill you learn in a few days. It is therefore
absolutely vital to have experienced Java and web develo
pers on the project.

In addition, Java developers will often bring in experience with unit
-
testing and continuous integration, something that is
often lacking with Oracle development.

All our viewobjects are subject to a basic unit
-
test that just performs
the
executeQuery
()

method. This allows us to
easily detect some mismatches between the database and the ADF components.

To have the latest development version build, tested and deployed is vital.
Successful

running the application locally in the
embedded
OC4J is not enough, it must run on
an

application server. It is essential to script the build process in such a way
that it can be run automatically, that it doesn't require human actions (that can and will go wrong
, at the wrong moment
) and
that the build

process doesn't depend on only one developer.

Our

continuous inte
gration process is based on
Maven
, although ant could be a viable option too. It may take some time
to set this up, especially
the
library
management

(JDeveloper's library management is not
very
comprehensible), but it
pays off. Every morning the latest version

of our application is available
on the development application server.

Don't be afraid of refactoring. It is important to keep the application comprehensible. One should really take ca
re to apply the
naming conventions when creating business components. But sometimes, it is
inevitable

to rename or move them.
Although
this may seem complicated, because
an ADF component
typically

involves java classes, xml files and project files,
JDevelo
per does a pretty good job and will apply the refactoring on all these places and apply them to the source control
system too. Only in few cases you need to d
o some additional manual steps. For example, when a viewobject is renamed, the
getXXX

method in th
e application module is not updated
, which
is easily detected after recompilation.

Use a simple reference projects, e.g. based on the HR schema, to
try things out
. This is normally much
faster,
easier and
more
comprehensive then using the real project and
doesn't interfere

with

the normal development process
.

Install the SRDemo project and see how they solve problems.

Use
existing, well tested (and often free) libraries like
Apache Commons for general Java utilities, StringUtils is
for example
very handy

fo
r all kind of String manipulation.


ADF Development : Live from the trenches

Andriessen

www.odtug.com

2

ODTUG Kaleidoscope 2008

Development environment

When using the whole ADF stack, the preferred (if not
inevitable
) IDE is JDeve
loper, because it is fully 'ADF
aware'. It
provides wizards, runtime libraries etc. to fully exploit the power of ADF.

Other IDE's do not have this ADF awareness and
you have to manually create and maintain the BC's, which is virtually impossible.

JDeveloper

To know your development environment, may really improve development time and quality. JDeveloper offers a lot of
settings and options that can enhance the development experience.

Make sure to clean the output directory once in a while :
Run => Clean
. Sometimes old classes or other files still remain and
may interfere in the application resulting in weird
behavior
.

Op
ening a
.
jspx file may take some time. Default it opens
in
the design editor. When you open it in the source editor, the file
is opened much more quickly :
Tools => Preferences => FileTypes => Default Editors tab =>

JSP Source

.

The debug messages from the

ADF framework can be essential in tracing problems. This can be enabled by adding
-
Djbo.debugoutput=console
-
Djbo.logging.show.function=true

to the runtime Java Options :
project properties =>
Run/Debu
g
), Launch Settings, Java Options
. It is good practice

to
define

a separate Run / Debug configuration to easily
switch.

Make sure that the database connections that are used in the application are defined
exactly

the same on every workstation.
This prevents continuous changes on the application module config
uration, the
bc4j.xcfg

file.

Use a datasource in the application module configuration to connect to the database. This allows connecting to different
databases (for Test, Acceptance and Production) without changing the configuration at delivery.

Add a sec
ond application module configuration that
uses
a
JDBC URL to the development database. This can be used for
running and debugging the application module tester and for unit
-
testing.

To debug the application module tester, replace the configuration in the

main

method in the
<ApplicationModule>Impl

with
the
name of the JDBC URL configuration
.

Source => Override Methods

opens a window with all the methods in the superclass.

Shortcuts :


Ctrl
-

opens a window to quickly open a class or the JavaDoc.


Ctrl<space>

lists all the available methods.


Ctrl<shift><space>

lists all the parameters of the method.

Enable external tools, especially 'Explore Directory' and another editor are very handy to easily open a file outside
JDeveloper.

Use TODO or @todo in your commen
t to indicate work to be done. All todo's are listed in the
tasks

window

and reporting
tools, like the maven taglist plugin can generate nice reports
.

Use a local standalone OC4J container as a first test if your application runs successfully on a more or
less real application
server.

We never use the
JDeveloper user libraries for external libraries,
which

are not a part JDeveloper because that requires
configuration

of each workstation which reduces flexibility,
transparency

and maintainability,

especiall
y for library
version
.
All these libraries are added to the <application>/lib directory and added as jar via the project properties.


Application /
Project
organization

and Naming Conventions

Much of the complexity of ADF Business Components is hidden fro
m the developer. The components are generated by
wizards and much of the
development

can be done in a declarative way without actually seeing or touching any Java code,
configuration files or xml files. But the actual implementation of Business Components

is quite complex
and the number of
Business Components tend to increase rapidly. It is therefore essential to organize ADF projects
thoroughly

and to apply
comprehensive naming conventions.

ADF Development : Live from the trenches

Andriessen

www.odtug.com

3

ODTUG Kaleidoscope 2008


A typical ADF project consists of multiple projects

(in differen
t directories)
, that are combined into one application.
Normally
you'll

find at least one busi
ness components (Model) project,
only one web

(
ViewController
)

project

and some
additional projects
.
Use comprehensible names for the projects because the name of

the deliverable is often equal to the
project name. Imagine all your applications producing deliverables with the same name like e.g.
ViewController.war
.

Stick with
one

viewControlle
r project. Each web application

is deployed with a different context and

they
(normally)
cannot
share
the

session.


Use a limited number of (ADF BC) Model projects.

It is perfectly possible to use different model projects to organize your
application
, but it is less comprehensive to reuse your business components in other proj
ects
, because they are only available

programmatically and not declaratively
.
On the other hand, it is
actually quite easy to merge two projects; JDeveloper will
take care of most issues but you need to manually update the
jbo.project

entry in the applicat
ion module configuration
file
.


We typically have one or two model projects
.

In addition to the Model and the ViewController projects, an application can contain as many projects as necessary. This
allows for separation of functions and better
maintenance
.

Typically you'll find a

common

project for generic, re
-
usable code

and a
n '
ear'

project that is dedicated to build and del
iver. The latter is more or less standard
in other Java IDE's.
This is also
required when using build tools like ant or maven. Integ
ration tests will typically have their own project. Webservices are
also often defined in their own project.

Make sure not to define circular dependencies.

U
nit
-
tests

are special cases
. They are
often
maintained in a different
sub
directory


but with the sa
me package structure,
within the same project

directory
.
T
his will normally clutter the interface of JDeveloper.
Fortunately, we can
easily
define separate
JDeveloper project
s

(.jpr)
, one that includes only the subdirectory with the normal sources
(src/ma
in/java) and one

that

only includes the subdirectory with the test sources (src/test/java).

An ADF project will typically end up
with the following project and

directory structure:


Figure
1

JDeveloper project structure. Figure
2

File system project structure

Within the Model project it is good practice to organize all business components in a comprehensive package (directory)
structure (
Figure
3
).

ADF Development : Live from the trenches

Andriessen

www.odtug.com

4

ODTUG Kaleidoscope 2008


Figure
3

Business Components organization


It is better to create the business components one
-
by
-
one instead of using the 'New Business Components from table' and
create them all in one try, because the wizard offers less control and uses some default conventions

(for relations and
instance name in application module) that often does not fit the project standards and must be corrected by hand.

In
addition

to good organization, it is extremely important to define and
apply

consistent naming conventions to have a cl
ear
picture of the components and what they are used for.

The names of entities are singular
, while the name
s

of viewobjects are plural and have Vw as an extension; e.g.
Employee and EmployeesVw.

A
simple naming convention
is to
add '
byXXX
'

extension to t
he name, like EmployeesByJob
Vw

that indicates a
ViewObject for which the
query
on employees is limited
by the job

(as bind parameter)
.

The viewobjects without this
extension
are not limited with a bind
-
parameter.
.

When no clear convention is used, develope
rs tend to have a lower understanding of the application, are more afraid to touch
it, are more reluctant to apply changes and will create more objects than needed, making the application less maintainable.

In our projects, we often create separate read
-
only viewobjects with the extension Lov or List that

are only to be used for
dropdown or LOV's, in addition to the 'normal' updatable viewobjects.

In addition to the name of the viewobject, the instance name in the application module is probably even more
important,
because this is the actual interface to the front
-
end like ADF binding. Especially with different usages, e.g. in a hierarchy, the
default name is not very comprehensible (<viewobject><sequencenumber>). Note that when a viewobject is renamed, th
e
instance name remains the same.

Attributes of business component, especially viewobjects, can be quite confusing, especially when a viewobject includes
multiple (reference) entities. It is good practice to be able to be able to identify the origin of the

attributes.

Reference entities (and their attributes) are prefixed with 'Lkp
<entityname>
'. Transient attributes are prefixed with
'Trnsnt'. .

When writing custom Java code, the name of association or viewlink
a
ccessors

can be a source of much frustration,

because
the default names are not very comprehensible and should be changed immediately

after creation
.


ADF Business Components

It is good practice to use custom Business Components Base Classes and to define them already at the start of the project.
Thi
s makes it much easier to add generic functionality later on.
The easiest way is to
configure them

via the project properties
(
Figure
4
)

to make your BC's automagically extend them at when they are created

(
image
)

(else you have to pr
ovide the
superclass with every BC that you create)
. Put the base classes in a separate, common, project

for reusability reasons.

ADF Development : Live from the trenches

Andriessen

www.odtug.com

5

ODTUG Kaleidoscope 2008


Figure
4

Definition of the base classes as project

properties.


Use multiple application modules

an
d organize them by functionality. Using
only one, will greatly decrease the
comprehensibility

of the project
.

We g
roup all general read
-
only viewobjects that are used for LOV's

and dropdowns

into one application module and
nest that into your other AM's.

N
ever use
select * from table
,

becaus
e

occasionally the columns in
other

database environments may be ordered
differently which result in the wrong mapping between the attribute and column.

The diagrams offer an excellent overview of the business components
, very suitable for technical documentation. They are
automatically synchron
ized with the actual components. For this purpose, meta information is added to the business
components xml files
. Don't worry about that.

Sequence based primary keys on an entity
object can be handled in two ways :
1
.

by defining the
datatype DBSequence
and
let the database trigger handle it
2
.
or by
manual
ly retrieval of

the nextval

from the sequence
. The first can be done
completely declarative

while the second one requires a lit
tle bit of custom java code (override the create method in the
<entity>Impl class) :

protected void create(AttributeList attributeList) {


super.create(attributeList);


SequenceImpl seq = new SequenceImpl("employee_seq", getDBTransaction());


setEmploye
eId(seq.getSequenceNumber());

}

With the DBSequence, the framework automatically generates a temporary, negative, id which is not posted / committed to
the database, and refreshed after insert. This may seem attractive, but it may cause issues with foreign

keys
which

are not
always updated properly to the new, refreshed, value resulting

in even more custom java code.

Refactoring a DBSequence
attribute to a Number may cause a dependency issue. This is due to the viewobjectRowImpl class; that must be removed
before you can change the datatype and than added again. Be aware how your source control system handles this.

In our projects, we
hardly

use the DBSequence anymore, but always retrieve the value from the database.

The refresh after update or insert uses
the returning clause to refresh the data. When the entity object is based on a database
view

with instead
-
of triggers, the returning clause

is not supported and a re
-
query must be performed instead. Create a
DefImpl class and override the
isUseReturningCla
use()

method to return false.


ADF Development : Live from the trenches

Andriessen

www.odtug.com

6

ODTUG Kaleidoscope 2008

ADF Faces

and JHeadstart

ADF Faces is the Oracle implementation of JSF. It has a rich set of components that greatly extends the reference set. It als
o
has extended the standard JSF lifecycle.

Needless to say, but it is essen
tial to understand ADF Faces to fully enjoy its potential, also when using JHeadstart.

See
http://www.oracle.com/technology/
products/jdev/htdocs/partners/addins/exchange/jsf/doc/tagdoc/core/imageIndex.html

for a complete list and description of the available components.


JHeadstart

provides a declarative approach for creating ADF Faces applications
using simple property editor
s

and
the
JHeadstart Application Generator
.
Amongst others it generates features like multi
-
row editing, trees, (multi
-
select) list of
values, quick and advanced search wizards,
internationalization and security.
It does not generate Java! It generates UI
pages,
configures the page flow and wires together the pages, the page flow, and the business components.

Application
configuration is done with the so called application definition file(s).

JHeadstart hides ADF Faces / JSF technology from the developers,
allowing inexperienced developers to join
productively the project. It is still essential to have experienced ADF developers on the project
.


Use multiple application definition files to s
e
parate

your application in logical chunks and to let your developer
s work on
different files, thus preventing source control problems.

By the way, e
ach application definition file can only be based on one
application module.

It's quite easy to split or merge application definition files, just copy and paste the group;
mak
e

sure to
copy the dependent lov's and domains etc. too.

We generate each application definition to different directories and packages
, t
hus clearly separating the generated
artifacts. However, some files still are shared, notably the JhsCommon
-
beans.xml.

Make sure
that common settings, like the data format, are set equally for all the application definition files.

The templates are based on velocity and are highly customizable.
With custom templates it is possible to have 100%
application generation
.

Paged
efinitions are the only artifacts that are not generated by templates, but via JDeveloper. Make sure to document the
postgeneration steps thoroughly. The 'clean pagedefinition before generation' is very useful in keeping them. Note however,
that also the o
ld binding is kept when an attribute changes name.

We create a <pagedef>.postgen.txt file next to each pagedef that describes the postgeneration steps.

JHeadstart creates a pagedefinition, a jspx file, bean files based on the group name and references to t
hem in the
databindings.cpx and the web.xml. When you rename a group, the old files and references remain intact. They do not harm,
but it is wise to clean them once in a while.

Obsolete files are easily identified after generation, because in the JDevelo
per Applications navigator only the name
s

of
modified files are displayed in italics (before saving all files)
, while the non
-
modified (i.e. non generated) files remain
the same
.

JHeadstart can generate fully i18n applications.
The resourcebundle entries a
re added during genera
tion. You can add your
own entri
es,
in

custom templates, using the same mechanism (see
http://technology.amis.nl/blog/?p=1405
), for example :
${JHS.nls("
<some text (only used in
combination with standard jhs text)>
", "<nls_key>", "<nls_text>" )}"

JHeadstart
implements

many design patters, e.g. for search, lov's, breadcrumbs etc.
It is
worthwhile to check their
implementation

(even when not using JHeadstart). Their implementation c
an easily

be
extended to fit your own needs
.


Although JHeadstart is enabled on the viewcontroller project,

the model project may also be extended. Make sure the
required
libra
r
ies are added to the model project (especially when using a separate build proc
ess like Maven).

When using the database resourcebundles or flexitems, the JhsModelService is added as a nested applicationmodule to your
own applicationmodule. The reference to this JhsModelService and its Business Components is added to the
model.jpx

fi
le

and
references the JHeadstart library in the JDeveloper installation directory,
which
is workstation dependent.

Add the
JHeadstart runtime library to
the project
(e.g. in the lib directory mentioned before)
and update the .jpx file

manually
.

ADF Development : Live from the trenches

Andriessen

www.odtug.com

7

ODTUG Kaleidoscope 2008

Disable 'S
et Application Module

Supercl
ass to
JhsApplicationModuleImpl

when you use a custom base class for the
application module (which off course you have), and extend your base class
from it yourself.

With JHeadstart it is quite easy to add generic functionality

like security or internationalization, later in the project.

For
example, role based security is easily configured at group level (
Figure
5
).


Figure
5

Overview of the JHeadstart security group properties.


Consider to develop complicated pages,

which
require a lot of JHeadstart customization, by hand

or use JHeadstart as the
beginning
. It may take much more effort to add the changes to the templates than to create the page.


ADF Model

(binding)

ADF Model, be
fore (and often still) called binding, provides access to the business services (application module) and its
objects (business components).

Bindings are defined in the pagedefinition file.

The DataBindings.cpx file defines the mapping between pagedefiniti
on and
page and defines the datacontrols (application modules).

Binding can also be used in managed or backing beans. Normally, you can only use the bindings of the current page.

The use of bindings is
loosely coupled
. In managed beans the name of the bin
ding is provided as String. These values are not
updated when the binding name changes and will result in a runtime error. Minimize the number of

bindings in managed
beans. Consider

retrieving

the underlying object via binding and then manage the attribute
s instead of handle all the attributes
via their own bindings.

The SRDemo project provides the ADFUtils and JSFUtils with lots of utility methods to handle bindings.

Note that JSF also has the concept 'binding'. This references the backing bean and not the

ADF binding.


References


OTN white paper on best practices

http://www.oracle.com/technology/products/jdev/collateral/4gl/papers/Introduct
ion_
Best_Practices.pdf

The Steve Muench undocumented sample
application addressing advanced ADF issues.

http://radio.weblogs.com/0118231/storie
s/2004/09/23/notYetDocumentedAdfSampl
eApplications.html

The AMIS technology blog, on (
amongst

others)
Oracle and Java development.

http://technology.amis.nl/blog/

Overview of the ADF faces components

http://www.oracle.com/technology/products/jdev/htdocs/partners/addins/exchange/js
f/doc/tagdoc/core/imageIndex.html

JDeveloper d
ocumentation

http://www.oracle.com/webapps/online
-
help/jdeveloper/10.1.3/state/content/destinat
ion./expanded.10~/navId.0/navSetId._/o
ldNavId.0/oldNavSetId._/

ADF Development : Live from the trenches

Andriessen

www.odtug.com

8

ODTUG Kaleidoscope 2008