Coding style definitions

Sun Coding Guidelines

The OpenEngSB Coding Guidelines are based upon the Code Conventions for the Java Programming Language. There are some additions and deviations for this project.

Line length

A line length of 80 was standard 10 years ago, but with increasing screen size and resolution a length of 120 is more reasonable.

Wrapping

Use the auto-formatter of your IDE. Import the Eclipse Formatter file.

Number of declarations per line

Only one declaration per line is allowed.

Declaration placement

Declare variables where they are needed. It's easier to read and restricts the scope of variables. Don't overshadow variables.

Blank lines

The body of a method should not start with a blank line.

General

File format

Every Java file has to be UTF-8 encoded and has to use UNIX line endings. Indentations consist of four spaces, tab-stops are not allowed.

Every source file has to start with this header:

/**

  Licensed to the Austrian Association for Software Tool Integration (AASTI)
  under one or more contributor license agreements. See the NOTICE file
  distributed with this work for additional information regarding copyright
  ownership. The AASTI licenses this file to you under the Apache License,
  Version 2.0 (the "License"); you may not use this file except in compliance
  with the License. You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

 */

Duplication

Code duplication has to be avoided at all costs.

Use guards

Guards are a possibility to reduce the amount of nesting. Heavily nested code is much harder to read. Bad:

public void foo() {
    if (conditionA) {
        if (conditionB) {
            if (conditionC) {
                // do some work
            }
        } else {
            throw new MyException();
        }
    }
}

Good:

public void foo() {
    if (!conditionA) {
        return;
    }

    if (!conditionB) {
        throw new MyException();
    }

    if (!conditionC) {
        return;
    }

    // do some work
}

Keep methods short

Methods longer than 40 lines are candidates for refactoring. A method should only do one thing and has to be easily understandable. The number of arguments should be minimized. A method should only be at a single level of abstraction.

Use enums

Prefer typesafe enumerations over integer constants.

Avoid use of static members

Static members are a sign of a design error because they are like global variables. It's fine if you declare a constant as final abstract of course.

Use fully qualified imports

Don't import org.example.package.*, instead import the needed classes.

Never declare implementation types

Use interfaces or the abstract base class instead of concrete implementation classes where possible. Don't write:

ArrayList<String> names = new ArrayList<String>();

Instead use the interface name:

List<String> names = new ArrayList<String>();

SerialVersionUID

Don't declare serialVersionUID just because your IDE tells you. Have a good reason why you need it. This can cause bugs that are hard to detect.

Restrict scope of suppressed warnings

If you have to suppress a warning make sure you give it the smallest possible scope. This means you should never annotate a whole class with @SuppressWarnings. A method may be acceptable but you should try to annotate the problematic statements instead.

Use String.format()

Use String.format() instead of long concatenation chains which are hard to read.

Array declaration style

Always use

Type[] arrayName;

instead of the C-like

Type arrayName[];

Comments

Don't make funny comments, be professional. All comments have to be in English. Comment what methods do, not how they do it. Do not comment what is already stated in code.

Naming

Interfaces

Interfaces are not marked by starting their names with I. This exposes more information than necessary and is not Java-like.

Don't abbreviate

Do not use abbreviations if it's not a project wide standard. Long method names are preferable to inconsistency. With automatic code completion this isn't a problem anyway.

No clutter

*) Exception/Log Messages have to be concise. Don't end messages with "...".
*) Don't overuse FINAL, use it where you have a good reason something has to be final. Although it doesn't hurt to declare everything as final it clutters the code.
*) Don't use history tables in source files. Use the SCM system if you are interested in the changes of a file.
*) Don't use the JavaDoc author tag. Also use the SCM system.
*) Don't declare unnecessary constructors, especially the empty default constructor.
*) Don't make implicit calls explicitly, i.e. calling super(); in every constructor.*) Don't specify modifiers that are implicit, i.e. don't make methods in interfaces

public abstract ...

.
*) Don't initialize fields with null, they are automatically initialized with null.
*) Don't use banners in comments.
*) Don't use closing brace comments, i.e. } // end if, they are a sign of too long methods.
*) Don't comment out code and commit it. This confuses programmers why it is there. Simply delete it, it's still present in the SCM history.

Exception Handling

*) Don't log and throw. Either a exception should be logged or thrown to be processed at a more appropriate place.
*) Don't swallow exceptions silently. If you have to do it, you have to make a comment stating the reason.
*) Use runtime exceptions where possible.
*) Wrap exceptions in a RuntimeException if you don't want to specify the Exception in your method signature and you can't handle it.
*) Write meaningful exception message.

Tests

General

*) Make use of JUnit 4 features, e.g. @Test(expected = SomeException.class).
*) Tests should not output anything. They have to be automatically verified.
*) Don't catch exceptions just to fail manually. Declare the method to throw the exception.
*) Install a shutdown hook for test data files. This assures that they will be deleted and the project remains in a clean state.
*) Use Mockito for mocking.*) Tests should have descriptive method names. It should be deducible what will be tested. Bad:

testError()

Good:

invalidInMessage_ShouldReturnErrorResponse()

Naming Scheme

The Maven profiles for running the tests are configured to filter based on the naming of the test class. The package layout is just a further convenience for the developer for running the tests manually.

Unit tests

Unit Tests test one class/method/feature in isolation from their dependencies by using test doubles as replacement. They should be fast and need no special environment setup for execution.
*) Filenames end with Test.java.*) Located in the normal package structure, i.e.

outer.project.package.inner.project.package

.

Integration tests

Integration Tests combine individual software modules to test their interaction with each other. They do not need a special environment setup for execution.
*) Filenames end with IT.java.*) Located in

outer.project.package.it.inner.project.package
User tests

User Tests need a special execution environment and thus are not run automatically during any maven phase.
*) Filenames end with UT.java.*) Located in

outer.project.package.ut.inner.project.package

XML Formatting

File Format

Every XML file has to be UTF-8 encoded and has to use UNIX line endings. Indentations consist of TWO spaces, tabstops are not allowed. The line length shouldn't exceed 120 characters.

Eclipse Settings

If you use Eclipse please choose these settings for your OpenEngSB workspace:

Recommended Readings

*) Clean Code, Robert C. Martin, 2008
*) Effective Java Second Edition, Joshua Bloch, 2008
*) 7 tips on writing clean code