Java Programming Standards | java coding concept


·         Code written to standard is easier to read and maintain. Most code is not maintained for its entire lifetime by the original author.
·         Maintenance accounts for 80% of the lifetime cost of software. The easier code is to maintain, the lower its ultimate cost.
·         Programmer productivity increases over the long term, because programmers become coding to standard becomes second nature, and less efficient coding methods are abandoned, and because of the savings in maintenance time.
Coding standards are important because they lead to greater consistency within your code and the code of your teammates. Greater consistency leads your code that is easier to understand, which in turn means it is easier to develop and to maintain.

Development guidelines provide two high-level benefits: they reinforce techniques to design and code better and they provide consistency even when there is no clear best choice. This document provides guideline recommendations that focus on the first of these benefits: all of the guidelines in here are meant to help build better software.

Standards only work if everyone observes them. Some of the standards in this document deal with fine details, such as white space and other spacing issues. We recognize that pretty print is less important than content, but make the point that it is important that we make shared code readable by a large audience, and to that end, people should conform to the standards as much as possible.

1.1             Purpose

The purpose of this document is to describe the Java programming standards adopted by Project IT Development Group.

1.2             When and How to Apply the Standard

·         All new code in Development Group must conform to the standard
·         You do not need to go through existing code gratuitously to make it conform to the standard
·         Anytime any significant change is made to a piece of code then changes can be made to make the whole file conform to the standard.
·         Configure the IDE you use, for brace style, spacing and javadoc etc. to make it conform to the standard.

2.1             Packages

Create a new Java package for each functional component. Create and use directories as recommended by Java’s package conventions. Packages provide a means of grouping classes of related function or purpose, and create the logic of the file organization. Classes grouped in packages can share access to methods and variables, while hiding the complexity of their interaction from other objects that don't use that information.
See 4.2.1 for package naming conventions.

2.2             Files

Each Java class should be placed in a separate file. A file consists of sections separated by blank lines. Optionally, a comment can identify each section.
Files longer than 1000 lines are cumbersome and should be avoided.

2.2.1          File Structure

Java source files should be structured as follows:
·         Package and import statements.
·         Class and interface declarations.

2.2.1.1         Package and Import Statements

The first non-comment line should be the package statement, followed by import statements.

Example

package com.mortgagefamily.yyy.acl;

import java.util.Vector;
import java.util.Hashtable;

2.2.1.2         Class and Interface Declarations

Class and interface declarations should appear in the Java source file in the following order:
·         Class/interface Javadoc comment (/**...*/) with author, version and copyright information in addion to a class description. See section 3.1.1 for details on javadoc comments.
·         Class or interface statement.
·         Class/interface implementation comment (/**...*/), if necessary. This comment should contain any class-wide or interface-wide information that wasn't appropriate for the class/interface documentation comment.
·         Class (static) variables. The public class variables appear first, then protected, then package level (no access modifier), and then private.
·         Instance variables. First public, then protected, then package level (no access modifier), and then private.
·         Constructors.
·         Methods. Methods should be grouped by functionality rather than by scope or accessibility. For example, a private class method can be between two public instance methods. The goal is to make reading and understanding the code easier.
Making code understandable is especially important in an object-oriented programming environment, because the point is to create reusable objects. Writing logical, clear, concise documentation in the source code itself promotes both well constructed applications and easier maintenance. Creating good source code documentation is time consuming, but well worth the effort over the life of the product.

3.1             Comments

3.1.1          Documentation Comments

A really good rule of thumb to follow regarding documentation is to ask yourself if you’ve never seen the code before, what information would you need to effectively understand the code in a reasonable amount of time.

General Concepts:
·         Comments should add to the clarity of your code
·         If your program isn’t worth documenting, it probably isn’t worth running
·         Avoid decoration, i.e. do not use banner-like comments
·         Keep comments simple
·         Write the documentation before you write the code
·         Document why something is being done, not just what

Use documentation comments immediately before declarations of interfaces, classes, member functions, and fields to document them. Documentation comments are processed by javadoc, to create external documentation for a class. For detailed specifications on Javadoc commenting requirements.

 


Naming conventions make programs more understandable by making them easier to read. They also provide information about the function of the identifier, such as whether the identifier is a constant, package, or class, which can be helpful in understanding the code.

4.1             General Naming Conventions

Observe the following general naming conventions.
·         Use full English descriptors that accurately describe the variable, field, or class. For example, use names like firstName, grandTotal, or corporateCustomer. Although names like x1, y1, or fn are easy to type because they are short, they do not provide any indication of what they represent, and result in code that is difficult to understand, maintain, and enhance.
·         Use terminology applicable to the domain. If users refer to their clients as customers, then use the term Customer for the class, not Client. Many developers make the mistake of creating generic terms for concepts when perfectly good terms already exist in the industry/domain.
·         For readability, follow these case conventions. For class and interface names, use UpperCamelCase. For methods, variables, and so on, use lowerCamelCase.
·         Use abbreviations sparingly and intelligently. Maintain a list of standard short forms (abbreviations). Choose them wisely, and use them consistently. For example, to abbreviate the word "number," choose one of nbr, no, or num, document it, and use it consistently.
·         Avoid long names without jeopardizing readability. Less than 20 characters is an appropriate guideline.
·         Avoid names that are similar or that differ only in case. For example, the variable names persistentObject and persistentObjects should not be used together. Nor should anSqlDatabase and anSQLDatabase.
·         Do not hide names. Name hiding refers to the practice of giving a local variable, argument, or field the same (or similar) name as that of another one of greater scope. For example, if you have a field called firstName do not create a local variable or parameter called firstName, or anything close to it like firstNames or fistName. This makes your code difficult to understand and prone to bugs because other developers, or you, will misread your code while they are modifying it and make difficult to detect errors.
·         Avoid leading or trailing underscores. Names with leading or trailing underscores are usually reserved for system purposes, and should not be used for any user-created names except for pre-processor defines.
·         If the name of the field begins with an acronym, such as sqlDatabase, then the acronym (in this case ‘sql’) should be completely in lowercase. Do not use sQLDatabase for the name.
·         In case of EJB, remote interface name should be the EJB Bean name, home interface should be EJB Bean name with “Home” suffixed and Bean class name should be EJB Bean name with “Bean” suffixed.

4.2             Specific Naming Conventions

This section provides standards for naming specific objects.

4.2.1          Package Names

Packages names shall begin with either the firm’s domain name or with one of the English two-letter codes that identify countries, and should be cast in ASCII alphabetic characters. Current domain suffixes include: com, edu, gov, mil, net, and org.

Example

../com/mortgagefamily/yyy/acl/..

4.2.2          Class Names

Class names should be nouns, cast in UpperCamelCase. Keep class names simple and descriptive. Avoid acronyms and abbreviations (unless the abbreviation is more widely used than the long form, such as URL or HTML).

Example

Customer
FinancialInstrument

4.2.3          Interface Names

Interface names are external facing. Interface names should follow the rules for class names. In addition, you can add an optional suffix, such as able, ible, or er, to interface names to indicate the interface function.

Example

Runnable
Contactable
Prompter
Singleton

4.2.4          Exception Classes

Exception classes follow the naming conventions for classes. Append the word Exception to the end of all exception classes.

Example

RemoteException
NamingException

4.2.5          Method Names

Methods should be verbs cast in lowerCamelCase.
Accessor methods should be prefixed with get or set, as appropriate.

Example

run()
getBackground()
getFirstName()
setFirstName()
isChecked()

4.2.6          Compilation Unit Files

Use the name of the class or interface for the name of the compilation unit and add the extension .java. If there is more than one class or interface, use the name of the primary class.
Customer.java
FinancialInstrument.java

4.2.7          Fields, Attributes, Properties

Field, attribute, property names should be cast as a full English description of the field in lowerCamelCase. Using prefixes and/or hungarian notation is not recommended as these mechanisms are sensitive to data type changes and changing the data type of an attribute changes the name of the accessors, mutators and impacts users. The names of accessors and mutators also become unwieldy with attribute names with prefixes and/or the hungarian notation.
firstName
settleDate
datedDate

4.2.8          Local Variables

Local variables should be cast as a full English description in lowerCamelCase. Take care not to hide existing fields. For example, if there is a field named firstName, do not name a variable firstName. Using prefixes and/or hungarian notation is not recommended to maintain consistency and reduce the number of changes that have to be made to the code if the data type of a variable changes.
issueDate
maturity
yieldToMaturity

4.2.9          Loop Counters

If loops are short it is generally accepted to use the letters i, j, k for the loop counter. If the loop counter has some specific business connotation then use a descriptive name such as customerIndex etc. for the loop counter.
If a loop block becomes long over time then using single character counter names can introduce errors during refactoring, as they are hard to find. Generally loops should be kept short and a long loop usually indicates the need for delegation of some of the functionality in the loop to other methods.

Example

i
j
k
counter
customerIndex

4.2.10      Constants

The names of variables and declared class constants should be all uppercase letters, with words separated by underscores. ANSI constants should be avoided, for ease of debugging.

Example

static final int MIN_WIDTH = 4;
static final int MAX_WIDTH = 999;
Tasteful spacing makes Java code more readable. Conventions regarding spacing are presented in this section.

5.1             White Space

Adding white space to Java code helps make it readable by breaking it up into small, easy-to-digest sections. Without white space, code can be difficult to read and understand.

5.1.1          Blank Lines

Use blank lines as follows:
·         Use a single blank line to separate logical groups of code, such as control structures.
·         Use two blank lines to separate member function documentation.

5.1.2          Inline Spaces

Observe the following standards for using inline spaces.
·         Use a single space to separate a keyword followed by a parenthesis:
while (true) {

·         Do not use a space between a method name and its opening parenthesis.
·         A space should follow each comma in parameter lists.

·         The expressions in a for statement should be separated by blank spaces.
for (expr1; expr2; expr3)

·         Casts should be followed by a blank space.
myMethod((byte) aNum, (Object) x);
myMethod((int) (cp+5), ((int) (x + 3)) +1);

·         Use one space in between the type and identifier in variable declarations.
int     level;
int     size;
Customer   myCustomer;

5.2         Line Spacing and Width

Line width should not normally exceed 80 characters. Indentation size should be set to 4 spaces . Use of tabs for indentation is discourgaed as it causes the code to align differently under different tab settings. If tabs are used they should be set to expand to 4 spaces.

5.3             Braces

Always use braces even if a compound statement has only one line. Illustrated below are three possible recommendations on a brace strategy to be adopted by projects. Pick one and conform to it on your particular project. All example code in this document adheres to strategy 3.
Brace Strategy 1:

class Sample extends Object {
    int Method(){
        for (int i=0; i<10; i++) {
            try {

                // do something
 
            } catch (SomeException e) {
                // corrective action
            } finally {
                // cleanup
            }
        }
    }
}


Brace Strategy 2:

class Sample extends Object
{
    int Method()
    {
        for (int i=0; i<10; i++)
        {
            try
            {
                //do something
            }
            catch (SomeException e)
            {
                // corrective action
            }
            finally
            {
                // cleanup
            }
        }
    }
}

Brace Strategy 3:
class Sample extends Object
{
    int Method()
    {
        for (int i=0; i<10; i++) {
            try {
                //do something
           
            } catch (SomeException e) {
                // corrective action
            } finally {
                // cleanup
            }
        }
    }
}

5.4             Wrapping Lines

When an expression will not fit on a single line, break it according to these general principles:
·         Break after a comma.
·         Break before an operator.
·         Prefer higher-level breaks to lower-level breaks.
·         Align the new line with the beginning of the expression at the same level on the previous line.

Here are some examples of breaking method calls:

someMethod(longExpression1, longExpression2, longExpression3,
           longExpression4, longExpression5);
var = someMethod1(longExpression1,
           someMethod2(longExpression2, longExpression3));


Observe the following standards regarding declarations.

6.1             Number Per Line

Follow these standards regarding number of declarations per line.
·         One declaration per line is recommended to encourage commenting.
·         Do not put different types on the same line.

Preferred:

int level; // indentation level
int size;  // size of table

 

Avoid:

int level, size;
int foo,  fooarray[]; //WRONG!

6.2             Initialization

·         Initialize local variables where they are declared. The only reason not to initialize a variable where it's declared is if the initial value depends on some computation occurring first.
·         Declare a local variable only at that point in the code where you know what its initial value should be. This practice minimizes bad assumptions about the values of variables.
·         Declare and initialize a new local variable rather than reusing (reassigning) an existing one whose value happens to no longer be used at that program point. This practice minimizes bad assumptions about the values of variables.

6.3             Placement

·         Avoid local declarations that hide declarations at higher levels. For example, do not declare the same variable name in an inner block.

Example

int count;
...
myMethod()
{
    if (condition) {
        int count = 0;     // AVOID!
    }
}

·         Within loops, objects should be re-used rather than re-created for performance reasons.

6.4             Method Declarations

For method declarations, follow these format rules.
·         Methods without arguments should be defined on a single line.
·         All method qualifiers (scope, static, abstract, final, native, synchronized, return type) should appear on the same line as the method name.
·         Methods should be kept small.
·         Arguments should follow the method declaration on the same line. If the maximum width is reached and there are more arguments, place subsequent arguments on a new line indented one tab from the method declaration. This is the format created by most code generators. It is also acceptable to place each argument on a new line, indented one tab from the method declaration.
·         For methods that throw exceptions, the throws keyword and exception type should appear on a new line following the argument close parenthesis. The throws keyword should be indented one tab from the method declaration.
·         A blank line should be placed between method declarations.

Example

public Boolean VerifyAccount(String id, String firstName,
       String lastName, double balance)
       throws NegativeBalanceException
{
             
}

Observe the specified format for following constructs.

7.1             If  Else Constructs

Place the if keyword and conditional expression on the same line.The statement is on the next line.

Example

if (expression) {
    statement;
} else {
    statement;
}

7.2             While Constructs

The while construct has the same format as the if construct. The while keyword should appear on its own line, immediately followed by the conditional expression. The statement block should appear on the next line.

Example

while (expression) {
    statement;
}

7.3             Do While Constructs

The DO..WHILE form of the while construct should appear as shown below:

Examples

do {
    statement;
} while (expression);

7.4             Switch Construct

The switch construct uses the same layout format as the if construct. The switch keyword should appear on its own line, immediately followed by its test expression. The statement block is placed on the next line.

Example

switch (expression) {
    case n:
        statement;
        break;
    case x:
        statement;
        break;
    default:              //always add the default case
        statement;
        break;
}

7.5             Try / Catch Construct

The try/catch construct is similar to the others.  The try keyword should appear on its own line; followed by the statement body.
Any number of catch statements are next, consisting of the catch keyword and the exception expression on its own line; followed by the catch body. The finally clause is the same as a catch .

Example

try {
    statement;
} catch (ExceptionClass e) {
    statement;
} finally {
    statement;
}
·         Use exceptions to handle logic and programming errors, configuration errors, corrupted data, resource exhaustion. Report exceptions by the appropriate logging mechanism as early as possible, including at the point of raise.
·         Minimize the number of exceptions exported from a given abstraction.
In large systems, having to handle a large number of exceptions at each level makes the code difficult to read and to maintain. Sometimes the exception processing dwarfs the normal processing.
There are several ways to minimize the number of exceptions:
·         Export only a few exceptions but provide "diagnosis" primitives that allow querying the faulty abstraction or the bad object for more detailed information about the nature of the problem that occurred.
·         Add "exceptional" states to the objects, and provide primitives to check explicitly the validity of the objects.

8.1             Exception Handling

All significant blocks of code begin with a try clause and end with a catch clause. Remember that there is a performance hit with inserting try catch clauses therefore refrain from adding try catch clauses in accessors and mutators.

8.2              Error and Exception Notification

There should be no return codes from methods that have default values like –1, 99 signifying error/failure conditions.
All errors are reported as exceptions. There are two kinds of exceptions.
·         System Exceptions
·         Application Exceptions.
System exceptions are things like, Out of Memory, Database Deadlock, Optimistic Lock etc. Application exceptions a communication mechanism for application errors and user messages like the “Trade details invalid”, “Settlement Date must be on or after Trade Date”, “Invalid CUSIP” etc.
Every Application should declare one sub-type exception. e.g. FrameworksException, BookNewException etc. This ApplicationException inherits from java.lang.Exception and contains within it an ErrorMessage object containing the actual error code, a cryptic error (“technical”) description and friendly error message.
The application code just knows about the appropriate error code that needs to be communicated to the user from that location. When an exception condition happens it creates an appropriate error message object from the error code and throws an Application Exception with the Error Message object included. So that the clients can catch the exception extract the friendly error message and report it to the end user or log it to a file.



9.1             Don't optimize as you go

Write your program without regard to possible optimizations, concentrating instead on making sure that the code is clean, correct, and understandable. If it's too big or too slow when you've finished, then you can consider optimizing it.

9.2             Remember the 80/20 rule

In many fields you can get 80% of the result with 20% of the effort (also called the 90/10 rule - it depends on who you talk to). Whenever you're about to optimize code, use profiling to find out where that 80% of execution time is going, so you know where to concentrate your effort.
Always run "before" and "after" benchmarks:
How else will you know that your optimizations actually made a difference? If your optimized code turns out to be only slightly faster or smaller than the original version, undo your changes and go back to the original, clear code.

9.3             Use the right algorithms and data structures

Don't use an bubblesort algorithm to sort a thousand elements when there's quicksort available. Similarly, don't store a thousand items in an array that requires a search when you could use hash table.

9.4             Document optimizations

Highly optimized code may be hard to read and maintain. Having documentation helps with maintenance.

In this section we will cover several techniques that help to separate the professional developers from the hack coders. These techniques are:
·         Document your code
·         Paragraph your code
·         Follow the thirty-second rule

10.1         Document Your Code

Remember, if your code isn’t worth documenting then it isn’t worth keeping (Nagler, 1995). When you apply the documentation standards and guidelines proposed in this paper appropriately you can greatly enhance the quality of your code.

10.2         Paragraph/Indent Your Code

One way to improve the readability of a member function is to paragraph it, or in other words indent your code within the scope of a code block. Any code within braces, the { and } characters, forms a block. The basic idea is that the code within a block should be uniformly indented one unit.


10.3         Follow the Thirty-Second Rule

Another programmer should be able to look at your member function and be able to  understand what it does, why it does it, and how it does it in less than 30 seconds. If he or she can’t then your code is too difficult to maintain and should be improved. Thirty seconds, that’s it. A good rule of thumb is that if a member function is more than a screen then it is probably too long.

The standards presented are in line with Sun’s Java conventions, and should be relatively easy to conform to. Following these standards will create more consistent code that is easier for colleagues to understand and maintain. Going against the standard is not recommended but, if your project makes a conscious decision for a valid reason to go against one of the standards then this should be clearly documented.


The following sources were used to compile the standards presented in this document.
1.       Sun Microsystems. Code Conventions for the Java Programming Language.
2.       Netscape Java Coding Standards.
3.       Ambler, Scott. Java Coding Standards.
4.       Jonathan Hardwick’s home page.
·         joodcs standards, with links to a Coding Standards Repository for various languages.
·         Javasoft coding standards
·         Netscape coding standards



Adoption of REST for Building Enterprise Integration Architecture


Information Technology Industry is facing huge challenges on adoption of Service Oriented Architecture (SOA) for implementing loosely coupled service based solutions. There are a primarily two architectural practices that have come to forefront in adopting Service Oriented Architecture. One standards is called Web services standards (WsS-*) and other is Representation State Transfer (REST).
There are number of Web Service Standards that are in practice, in terms of implementation and solution adoption. Whereas REST focuses on Simplicity as the fundamental principles with fewer standards.
Enterprise Level Integration Architectures, more specifically EAI(Enterprise Application Integration), Brokers and ESB (Enterprise Service Bus) provide the critical background processing and Integration capability to enterprises. By the very nature of the reason for its existence they need to be stateless, asynchronous and loosely coupled to accommodate for easier integration, flexibility and scalability of the architectural solution.
WS-* and REST are being adopted in the industries to solve their Integration Issues.
Recent technology trends in the Web Services (WS) domain indicate that a solution eliminating the presumed complexity of the WS-* standards may be in sight.
Advocates of Representational State Transfer (REST) have come to believe that their ideas explaining why the World Wide Web works are just as applicable to solve enterprise application integration problems and to simplify the plumbing required to build service-oriented architectures.
The objective of this point of view is to provide adoption parameters from a perspective of enterprise integration architecture principles.
The attached document provides the comparison summary for REST versus WS-* from an architectural principle and technology perspective.


REST has the following strengths over WS-*
a)      Simplicity: REST is intuitive due to simplistic nature of its principles and adoption techniques.
b)     Fewer Standards and Well Proven Standards for Implementation: Fewer Standards means like HTTP, XML, JSON, JAX-RS, RSS and WADL.
c)      Promotes effective Loosely couples architectures without contracts: These features make REST highly extensibility and Open. 
d)     State management can be performed through the use of resources. Therefore promotes very level of scalability
a)      Where Simplicity and Scalability of the Integration Architecture is critical to delivering business needs, then REST is a good choice
b)     Where State Management is not a key function of the Integration architecture and state may be managed through source or target application resources.
c)      Where Synchronous processing is a key requirement: In case an Integration Architecture requires synchronous processing between source and targets applications then choice of REST may be considered a good choice. However where Integration Patterns required are asynchronous, then REST may not be a suitable choice
d)     Where Performance, Reliability, Interoperability is critical to the delivery of the   solution: REST due to choice simplistic and well established mechanism of solution implementation, is a good choice. Use of XML as the base data interchange technology in WS-* standards makes it really resource expensive solution.
e)      Where Cost plays a crucial role in delivering loosely coupled solution, then REST is a good choice.
f)       Where cross domain integration is required, then REST may be a very good choice of Integration
g)      Where Transaction Management, Orchestration, routing, correlation, aggregation, discoverability, choreography and Transformation is a critical to delivering Integration Architecture, then REST may not really a good choice.


Delayed Consistency Validation in Hibernate


There are occasions when the consistency of updates being done on the database needs to be deferred till the point just before the commit. A situation similar to this occurred for one of our client where the consistency of the relationship between entities was to be checked. It is very obvious that the update on the entities participating in the relationship can occur in any order or may not occur at all. Therefore the check needs to be performed just before the commit when all updated have happened.
One simple solution to check the consistency is to create database triggers which perform the consistency checks. This approach has its own drawback which business logic getting spread across the Application Tier and the Database Tier in a typical application. For the same reason, this was not a preferred approach of the client too.
A solution with hibernate of using Interceptors was also ruled out due to the technology stack being used. The entities being EMF objects required use of Teneo which uses the interceptors and replaces any configured interceptor defined on the Entity.
To attack the problem at hand, two very probable directions left were the JDBCContext class and the JEE Synchronization interface.
Hibernate uses a class called the JDBCContext to perform any operations on the database resources. The class has methods which get invoked at start of transaction, and before and after the completion of the transaction. This could have lead to a solution of having a custom JDBCContext class, but was ruled out as hibernate does not provide any hooks to use a different class instead of class it provides.
The JEE Transaction (javax.transaction.Transaction) interface as well as the Hibernate Transaction (org.hibernate.Transaction) interface both use the JEE Synchronization (javax.transaction.Synchronization) interface for notifying the transaction before completion and after completion events. JEE Synchronization being a very light weight object, attaching multiple synchronizations to a transaction was also feasible. The transaction in Hibernate (implementation of Hibernate Transaction interface) is created using a transaction factory (org.hibernate.transaction.TransactionFactory interface) which can be configured very easily in Hibernate.
The solution uses delegation very effectively to achieve the desired result. Following classes were used in the solution
DelegateTransactionFactory
a.            Implements the org.hibernate.transaction.TransactionFactory interface.
b.           Configures the actual factory uses the properties to do the same.
c.            The createTransaction method returns the transaction returned by the actual factory wrapped in the new DelegateTransaction class.
d.           Other methods simply delegate to the actual factory.
e.            This class is configured as the factory_class in the Hibernate configuration with the actual factory as its sub property.
DelegateTransaction
a.       Interestingly this class would not have been required had the JDBC Transaction class (org.hibernate.transaction.JDBCTransaction) been implemented correctly in Hibernate. This class ignores the exception thrown by the JEE Synchronization totally ignoring the JEE specifications recommendation.
b.      Implements the org.hibernate.Transaction interface.
c.       Methods simply delegate to the actual transaction barring the corrections required for first point above.
EntitySynchronization
a.       Implements the javax.transaction.Synchronization interface.
b.      Constructed using entity as an argument
c.       Calls the relationship validation methods on the entity in the implementation of the before transaction completion callback. This is done when the transaction is not rolling back.
d.      Performs the cleaning up operation in the after transaction completion callback.
e.       The actual checks are modeled and there code is generated using MDA
Two other possible solutions which could have been tried out are the following
1.      Using dynamic proxy to create a delegate class for JDBCContext class and overriding the implements of before and after the completion of the transaction callbacks.
2.      Create a composite Interceptor and ensure that the Teneo’s interceptor is the last to be called in the Composite Interceptor.