Tuesday, April 05, 2011

Coding Standards

For any ADF/Webcenter/SOA/J2EE Java code, Model and UI layer, here are few points to make code better from writing from performance and standard point of view,that comes from our coding practice and experience.This was the list we were using while developing the Fusion Apps in Oracle.

Here I have tried to consolidate a set of checkpoints we should check before source controlling any changes.This ensures making code better, robust, standards compatible and performant.

Keep this article opened in your web browser and just before checkin, make a habit to just glance through it once to make sure, you havent forgotten unknowingly anything.

Note:
This list is expandable.It would be great to add as much as points you find I have missed in respective sections.

JSFF/JSPX code- Checkpoints

  • Make sure, you have used Resource Bundle whereever its required.
  • For Bounded taskFlows, make sure to use activation as conditional/deferred(Not Immediate) and use active condition EL expression.
  • Id of the component, length should be <= 7.
  • Make sure, you have removed unwanted PageDef Bindings.
  • If af:popup is used, make sure to set the contentDelivery to "LazyUncached".
  • If using af:contextInfo, make sure the af:dialog has modal="false".
  • If using af:contextInfo, make sure the af:showPopupBehavior has triggerType="contextInfo".
  • If using af:popup from af:commandLink, make the partialSubmit to true for af:commandLink.
  • If using af:popup. make childCreation property to "deferred" so that only when the Popup is launched the WebBean hierarchy would get created in server memory.
  • Run JAudit for the file you make changes, from Menu->Run->JAudit file.
  • Right click->Reformat before checkin.
  • If using JavaScript, can you think to avoid that.
  • jsff/jspx files must reside under /page package.
  • Taskflows must reside under /flow package.
  • Menu model xml files must reside under /menu package.
  • In Case of deriving the Url parameters, preferably use the following syntax to derive declaratively #
    Unknown macro: {facesContext.externalContext.requestParameterMap['Empno']}

    (Empno is url parameter)

Any Java Code - Checkpoints

  • Managed Bean class name should end with "Bean".
  • Dont use SOP statements.
  • New methods introduced, make sure they are modular so that they can be JUnitized.
  • New Method should aways return a value so that they can be JUnitized.
  • Add Logger statements to the new methods.
  • Make sure you have thrown sufficiently Exceptions.
  • Run JAudit for the file you make changes, from Menu->Run->JAudit file.
  • Make sure to define the Variables with a name starting with small letter.
  • Do not use underscore (_) in Variable and Method names.
  • Make sure to check for Null condition for all operation that could throw NullPointerException. Ex: CollectionModel, Row, ViewObject, ApplicationModule, String objects etc.
  • Right click->Reformat before checkin.

AM - Check Points

  • Number of occurances of createRootApplicationModule() or *AMImpl.getInstance() should be same as releaseRootApplicationModule().

Entity Object - Check Points

  • Can you convert the code you have just written into Groovy?
  • Run JAudit for the file you make changes, from Menu->Run->JAudit file.

ViewObject - CheckPoints

  • Get SQL explain plan everytime you touches a VO.
  • For new Attributes added, make sure you use proper UI hints.
  • If creating a New VO, make sure its is based on an EO(Exceptions to be considered).
  • if createViewObject calls are present, then make sure, you remove those dynamic ViewObjects.
  • If setting rangeSize() to -1, restore the rangeSize after you work on that.
  • Dont set ListRangeSize == '-1' unless the ViewAttribute using the LOV has CONTROLTYPE 'choice' or 'radio.' or 'default'
  • FetchSize should be <= 25 or same as number of rows to be displayed in UI.
  • Avoid use of vo.getROwCount()
  • View Criteria shouldnt have "null checking" checkbox checked.
  • LOVs shouldn't have "query automatically" checked.
  • SQL based VOs,should have query optimizer hint set to "FIRST_ROWS(10)".
  • Always test the application with ampooling= false when our bc4j txn involves any transient vos.

JDBC - Checkpoints

  • Move to the latest releases of Java as they become available.
  • Use prepared statements (PreparedStatement class) [article provides coded example of using Statement vs. PreparedStatement].
  • Note that two database calls are made for each row in a ResultSet: one to describe the column, the second to tell the db where to put the data. PreparedStatements make the description calls at construction time, Statements make them on every execution.
  • Avoid retrieving unnecessary columns: don't use "SELECT *".
  • If you are not using stored procedures or triggers, turn off autocommit. All transaction levels operate faster with autocommit turned off, and doing this means you must code commits. Coding commits while leaving autocommit on will result in extra commits being done for every db operation.
  • Use the appropriate transaction level. Increasing performance costs for transaction levels are: TRANSACTION_NONE; TRANSACTION_READ_UNCOMMITTED; TRANSACTION_READ_COMMITTED; TRANSACTION_REPEATABLE_READ; TRANSACTION_SERIALIZABLE. Note that TRANSACTION_NONE, with autocommit set to true gives access to triggers, stored procedures, and large object columns.
  • Store string and char data as Unicode (two-byte characters) in the database.
  • Avoid expensive database query functions such as: getBestRowIdentifier; getColumns; getCrossReference; getExportedKeys; getImportedKeys; getPrimaryKeys; getTables; getVersionColumns.
  • Use connection pooling, either explicitly with your own implementation, or implicitly via a product that supports connection pooling.
  • Use blocked fetchs (fetching table data in blocks), and tailor the block size to reduce calls to the database, according to the amount of data required.
  • Use batch updates (sending multiple rows to the database in one call).
  • Use stored procedures where appropriate. These benefit by reducing JDBC complexity, are faster as they use static SQL, and move execution to the server and potentially reduce network trips.
  • Use the type-correct get() method, rather than getObject().

EJB - Performance Checkpoints

  • Use session bean wrapper for returning multiple data rows from an entity bean, rather than returning one row at a time.
  • Use session beans for database batch operations, entity beans typically operate only one row at a time.
  • Use entity beans when only a few rows are required for the entity, and when rows need to be frequently updated.
  • Tune the underlying system, e.g. TCP/IP parameters, file limits, connection pool parameters, EJB pools sizes, thread counts, number of JVMs, JVM heap size, shared pool sizes, buffer sizes, indexes, SQL queries, keep/alive parameters, connection backlogs.
  • Transactions should span the minimum time possible as transactions lock database rows.
  • Use the lowest cost locking available from the database that is consistent with any transaction.
  • Use a dirty flag where supported by the EJB server to avoid writing unchanged EJBs to the database.
  • Commit the data after the transaction completes rather than after each method call (where supported by EJB server).
  • Do bulk updates to reduce database calls.
  • Tune the connection pool size to minimize the creation and destruction of database connections.
  • Use JDBC directly rather than using entity beans when dealing with large amounts of data such as searching a large database.
  • Use container-managed persistence when you can. An efficient container can avoid database writes when no state has changed, and reduce reads by retrieving records at the same time as find() is called.
  • Minimize database access in ejbStores. Use a "dirty" flag to avoid writing tee bean unless it has been changed.
  • Always prepare your SQL statements.
  • Close all database access/update statements properly.
  • Avoid deadlocks. Note that the sequence of ejbStore calls is not defined, so the developer has no control over the access/locking sequence to database records.

2 comments:

anika said...

Nice article. Great work.

Patrick Co Eban said...

Very much useful article. Kindly keep blogging

Java Training in Chennai

Java Online Training India