1 / 44

ADF Development Live from the trenches

ADF Development Live from the trenches. Aino Andriessen AMIS. Aim. Share our experience with ADF development Better ADF development Prevent problems Better maintainance Better applications. JDeveloper 10.1.3.3 ADF 10.1.3.41.57 JHS 10.1.23.2.51. Software studio Project Organization

jered
Download Presentation

ADF Development Live from the trenches

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. ADF Development Live from the trenches Aino Andriessen AMIS

  2. Aim Share our experience with ADF development • Better ADF development • Prevent problems • Better maintainance • Better applications

  3. JDeveloper 10.1.3.3 ADF 10.1.3.41.57 JHS 10.1.23.2.51

  4. Software studio • Project Organization • Development

  5. Software studio • SCM • Continuous integration • Incident management • OTAP • Quality measurement • Testing • Reporting • Artifact repository

  6. SCM • e.g. Subversion • JDev 10.1.3.3 : 1.4.x; before it's 1.3 • JDeveloper extension(s) • Only 1 scm per JDev installation • Limited functionality, but mostly enough • Necessary for correct refactoring of BC's • ! beware of delete and (re)create in 1 'update-commit cycle' • When updating outside JDev, close JDev or make sure that all changes have been saved • Built-in JDev history • very helpful for re-applying post-generation • 'activate' manually the scm connection to include scm history

  7. Continuous Integration • build • test • deploy • Scripted • maven / ant • Automated • Continuum • Dedicated environment

  8. Unit-testing ↑ code control ↑ code quality ↓development time • TDD improves the testibility of your code • Unit-testing increases your ADF skills • Easy debugging of BC's • Automated execution at continuous integration

  9. BC testing • BC tester • JDeveloper JUnit extensions • URL based application module configuration • 'unit-test framework' • application module configuration • authentication • generic functions import oracle.jbo.client.Configuration; ... public void setUp() { _am = Configuration.createRootApplicationModule ("nl.amis.demo.odtug.model.services.HRService" ,"HRServiceLocalURL"); } public void tearDown () { Configuration.releaseRootApplicationModule(_am, true); }

  10. What to test • Synchronicity of BC with database • Basic test for all VO's • get<AM>().get<VO>().executeQuery() • VO instance in AM • Data • Custom interface methods • Entity validators • Custom methods on ADF objects • Non-ADF java classes • ...

  11. demo

  12. Software studio • Project Organization • Development

  13. Application organization

  14. Test projects

  15. Project naming • Use comprehensive names for your project. • The name will normally also be used for the deliverables: • model.jar or viewcontroller.jar is not very informative • but it is good practice to include them in the name

  16. Project merge • It's quite easy to merge BC projects • Copy / paste BC's • Add configurations to bc4j.xcfg • Modify bc4j.xcfg - jbo.project option • recompile

  17. Project organization • Organize your BC's in directories • Separate the usage of ViewObjects (VO) in separate Application Modules (AM) • Bundle read-only reference VO's in a nested AM • Use Custom baseclasses • Extend AM baseclass from Jhs baseclass

  18. Naming conventions • Good names make the project much more comprehensible and maintainable • Stick to your conventions • Apply them asap • or you must perform refactoring later on • Do not use the default sequencenumber suffix that JDeveloper often generates. • e.g. EmployeesVw1 • This will make your life miserable in no time.

  19. Examples • Entities • singular • e.g. Employee • Viewobjects • plural • suffix • e.g. EmployeesVw • read-only reference (dropdown, lov) • e.g. EmployeesListVw • indicate the usage • EmployeesByNameVw • Accessors of associations and viewlinks • use plural for list and singular for 1 object • Attributes • Start with capital • Lkp prefix for reference entity and Lkp<entity> for referenced attributes • Trnsnt prefix or suffix for non-database bound attributes • VO instance names • NO number suffix • comprehensible names, especially within hierarchies • e.g. EmployeesByDepartmentVw or JobsListVw

  20. Refactoring • Don't be afraid of refactoring • try to be strongly typed • use unittests for verification • spend some time getting familiar • Refactor with scm enabled • JDeveloper does a rather good job... but misses a few spots • rename VO does not update the <am>.get<VO>() method • compile error, manual correction of method in Impl • rename an entity may not correctly update the association • manual correction in entity XML file • Rename VO • The 'api' (AM instance) is not refactored. • Iterator bindings remain valid • Attribute bindings in adf faces pages are not updated

  21. JHeadstart refactoring • BC refactoring (AM instance, attribute) only requires a 'refresh' (and regenerate). • Custom code (EL expressions, binding) must be done manually • Rename a group : • Obsolete files : • <oldGroupName>.jspx • <oldGroupName>Table.jspx (in case your group has layout style ‘table-form’.) • <oldGroupName>.pageDef.xml • <oldGroupName>-beans.xml • Obsolete entries : • DataBindings.cpx • web.xml (param-name javax.faces.CONFIG_FILES) • db resourcebundles • Generate and wait with saving to identify the old, not modified, files. • Note that custom templates may contain hard-coded references to the old entries

  22. Software studio • Project Organization • Development

  23. Development skills • Diverse set of skills • Standard Java and Enterprise Java • Database • ADF • JSF pagelifecycle • HTML / Javascript / css • JHeadstart • Application Server Administration • SOA • Architecture / design • Security • Object Orientation • ... • Know your tool / framework! • When using JHeadstart, make sure you know how to make an ADF application

  24. General • Use a 'reference Emp project' for research and trials • JHeadstart solutions • Download SRDemo project • RTFM • Oracle forums • http://radio.weblogs.com/0118231/stories/2004/09/23/notYetDocumentedAdfSampleApplications.html • Do scm project branching to test changes with major impact • http://www.oracle.com/technology/products/jdev/htdocs/partners/addins/exchange/jsf/doc/tagdoc/core/imageIndex.html

  25. Logging • Log4J • and Apache Commons Logging • log4j is included with jhs runtime • Do NOT include in deliverable • log4j.properties file on classpath • source path private static Log sLog = LogFactory.getLog(HRServiceImpl.class);

  26. Debugging • Project properties -> custom run configuration • -Djbo.debugoutput=console (file) • -Djbo.logging.show.function=true • http://www.oracle.com/technology/products/jdev/tips/muench/debugger/index.html • http://www.oracle.com/webapps/online-help/jdeveloper/10.1.3/state/content/navId.4/navSetId._/vtAnchor.editing/vtTopicFile.adfdevguide%7Cweb_testdebug~htm/

  27. Debugging

  28. Application Module / Service • Create impl class • direct access to VO's • Custom interface methods • parameters must be serializable • return type must be serializable • throw JboException • Exceptions are caught in the binding framework and cannot be catched in managed bean. try { sendEmailBinding.execute(); } catch (JboException e) { // never ever catched } if (ADFJSFUtils.hasErrors(bindings) { // ... }

  29. AM Configuration • Datasource for production • URL for testing • Use exactly the same DB connection • Configure the datasource manually • Do not use the generated ones • Normally do not include them with deployment public static void main(String[] args) { launchTester("nl.amis.demo.odtug.model.services","HRServiceLocalURL"); }

  30. Entity Validation • ! No value change : no attribute validation • but entity validation is performed

  31. Entity validation • Testing can be quite easy with unit-tests /** * Test that the salary must be lower than 10000 */ public void testSalaryRule () { HRServiceImpl service = getHRService(); EmployeeImpl emp = (EmployeeImpl) createEntity ("nl.amis.demo.odtug.model.entities.Employee"); try { emp.setSalary(new oracle.jbo.domain.Number (11111)); fail(); } catch (Exception e) { assertTrue(true); } emp.setSalary(new oracle.jbo.domain.Number (9999)); emp.setSalary(new oracle.jbo.domain.Number (-1)); emp.setSalary(null); }

  32. Views with Instead-of triggers • Refresh after insert / update • DB does not allow returning clause OracleSQLBuilderImpl.doEntityDML(401) BEGIN UPDATE EMPLOYEES Employee SET SALARY=? WHERE EMPLOYEE_ID=? RETURNING PHONE_NUMBER INTO ?; END; public boolean isUseReturningClause() { return false; } OracleSQLBuilderImpl.doEntityDML(401) BEGIN UPDATE EMPLOYEES Employee SET SALARY=? WHERE EMPLOYEE_ID=?; SELECT PHONE_NUMBER INTO ? FROM EMPLOYEES WHERE EMPLOYEE_ID=?; END; Note, that you cannot use this to refresh the DB generated primary key.

  33. Sequence based PK • Sequence based • Override entity create(AttributeList) method : • DbSequence • negative temp id that is NOT submitted to the database • Initially easier to use, but the consequences might be more complex • negative temp id, that is not always updated on details : • override entity postChanges() • refactoring to sequence based requires absence of <VO>Impl • scm issues may arise when delete and create in one updatecycle protected void create(AttributeList attributeList) { super.create(attributeList); SequenceImpl seq = new SequenceImpl("EMP_SEQ", getDBTransaction()); setEmployeeId(seq.getSequenceNumber()); }

  34. Constants and literals • Minimize the use of literals in EL-expressions • Use contants • as managed bean property with 'getter' • IsXXX transient attribute on VO

  35. SetActionListener • The setActionListener tag is a declarative way to allow an action source to set a value before navigation • From and to must be both EL-expressions • even constants, e.g. : from="#{'HelloWorld'}" • oracle.jbo.domain.Number cannot be set as constant • Note execution sequence : • actionListener attribute • setActionListener • action • Can also used to set methodbindings <af:setActionListener from="#{bindings.EmployeesVwEmail.inputValue}" to="#{emailBean.emailTo}"/>

  36. Manipulating the model using binding FacesContext ctx = FacesContext.getCurrentInstance(); Application app = ctx.getApplication(); ValueBinding bind = app.createValueBinding("#{bindings}"); BindingContainer bindingContainer = (BindingContainer) bind.getValue(ctx); OperationBinding sendEmailBinding = bindingContainer.getOperationBinding("sendEmail"); sendEmailBinding.execute(); OperationBinding commitBinding = ADFUtils.getBindingContainer().getOperationBinding("Commit"); commitBinding.execute(); <managed-property> <property-name>bindings</property-name> <value>#{bindings}</value> </managed-property> OperationBinding sendEmailBinding = bindings.getOperationBinding("sendEmail"); sendEmailBinding.execute();

  37. JHeadstart • ADF Faces generation • Different types of pages • I18N • Authorization • Search • Lov • FlexItems • ... • velocity based templating to customize generation

  38. General • Organize pagedefs, resourcebundles, beans, regions • Utils : oracle.jheadstart.controller.jsf.util.JsfUtils • Jhs PhaseListeners in JhsCommon-beans.xml • When using multiple faces-config • !! An extra ADFPhaseListener appears in faces-config.xml after adding custom bindings. Multiple PhaseListeners may lead to unpredictable behaviour.

  39. Postgeneration • Velocity templates • Pagedef generation is not templated • but uses JDev mechanism • Documention of pagedef postgen in a <pafegdef>.postgen.txt file • Disable 'clear pagedef before generation' • Note, disable 'Override' does not add new bindings

  40. Templates • Use scm tag / copy to create a copy template to keep the link with the original template in case of updates • Include custom templates : #parse("cxs/misc/include/cxsNlsEntries.vm") • If necessary, use your own .jtp # Custom template QUICK_SEARCH_TEXT_INPUT=odtug/item/find/googleSearchTextInput.vm # no dropdown needed QUICK_SEARCH_DROP_DOWN_REGION=default/common/empty.vm # removed other entries

  41. Templates and nls • create nls entries : (http://technology.amis.nl/blog/?p=1405 ) • Include custom nls-entries in comment ${JHS.nls("<some text (only used in combination with standard jhs text)>" , "<nls_key>" , "<nls_text>" )} <!-- NLS Entries ${JHS.nls("Global Help button label", "GLOBAL_HELP_LABEL", "Help")} -->

  42. The key to success • Organization • Knowledge • Communication • Fun

  43. aino.andriessen@amis.nl http://www.amis.nl http://technology.amis.nl/blog

More Related