0% found this document useful (0 votes)
96 views57 pages

JAVA - Manage Code Quality With JLin

Uploaded by

Jorge
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
96 views57 pages

JAVA - Manage Code Quality With JLin

Uploaded by

Jorge
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 57

Best Practice

Manage Code Quality with JLin

Dietmar-Hopp-Allee 16
D-69190 Walldorf
CS STATUS
customer published
DATE VERSION
March 31, 2009 3.0

BP_Jlin_V30.doc – 24.04.2009
Best Practice
Custom Code Management

Table of Contents
1 Management Summary 3
1.1 Goal of Using JLin 3
1.2 Alternative Practices 3
1.3 Staff and Skills Requirements 4
1.4 System Requirements 4
1.5 Duration and Timing 4
1.6 The JLin Tool: Basics 4
1.6.1 SAP NetWeaver Development Infrastructure 4
1.6.2 Basic elements 5
2 Best Practice 7
2.1 Preliminary Tasks 7
2.2 Procedure 7
2.2.1 Installation 7
2.2.2 Creating and editing variants 7
2.2.3 Executing tests 15
2.2.4 Suppressing messages 19
2.2.5 Using CBS 20
2.2.6 Create own tests 22
2.2.7 Results 29
2.2.8 Import a result set 30
2.3 JLin Tests 32
2.3.1 Eclipse compiler warnings 32
2.3.2 Tests 36
2.3.3 Logging 46
2.3.4 Security 47
2.3.5 Metrics 48
2.3.6 EPTests 48
2.3.7 J2EE 51
2.3.7.1 EAR 51
2.3.7.2 EJB 51
2.3.7.3 WEB 53
3 Background Information and References 55

© 2009 SAP AG - BP_Jlin_V30.doc page 2/57


Best Practice
Custom Code Management

1 Management Summary

One of the main goals during software development is to ensure the quality of the final product. To meet the
high demands placed on quality assurance for Java-based application projects, the JLin test tool is provided
as an integral part of the Developer Studio. JLin can be used to investigate the properties of Java source files
and check the syntax of their semantics. Some of the checks are delivered as standard, but it is also possible
to create own checks by specifying check parameters. Thus a check run can include several single checks,
which can be performed on one or more Java source code files.

This document describes how the JLin Tool can help a company to control the quality of their Java Coding,
how the tool can be used, how tests can be executed and own tests can be created. It also presents all
available predefined tests for example with respect to logging, security or metrics.

1.1 Goal of Using JLin

Use the JLin tool to perform predefined static tests on Java sources.

Static testing is a form of software testing where the software isn’t actually used or executed (non-execution
based methods). It is primarily formal syntax checking of the code.

The tests are delivered as part of the Developer Studio. JLin tests include:
ƒ Identifying error sources
ƒ Enforcing code conventions
ƒ Evaluating metrics and statistics
ƒ Enforcing architectural patterns
ƒ Monitoring

1.2 Alternative Practices

Some simple analyses are often already integrated in the Compiler of the programming language. The SAP
NetWeaver Developer Studio also offers some basic checks, like for example the test for initialization of a
variable.

Since JLin performs static tests on Java sources, it can only provide a sort of basic result in some cases. A
static performance check, for example, does not guarantee that a program has no performance flaws. For
critical code it is a must to do additional checks of the program execution with the help of monitoring and
tracing tools.

There are many approaches for software testing. Besides static testing, the dynamic testing is another
possibility to perform software tests. Thereby the programmed code gets actually executed with a given set of
test cases. The whole testing process can also be divided into different levels, for example Unit testing,
Integration tests, System testing, etc. The SAP Support Standard for Test Management contains detailed
information on testing procedures and management.

JUnit for example is a standard tool to perform Java Unit tests.

In order to create and execute functional tests, the SAP extended Computer Aided Test Tool (eCATT) can be
used. Chapter 3 offers some additional links, to get more information on these tools.

© 2009 SAP AG - BP_Jlin_V30.doc page 3/57


Best Practice
Custom Code Management

1.3 Staff and Skills Requirements

While executing JLin is very intuitive and can be accomplished by any person with basic development skills,
the interpretation of the check results ranges from ‘easy’ to ‘complex’.
ƒ There should be at least one person with good to very good knowledge of the relevant aspects covered by
the JLin checks, for example performance, security, or metrics. They should
- be able to discuss the meaning and significance of the check results with developers
- be respected among their colleagues for their knowledge about code quality
- use JLin and other tools regularly and know their capabilities
ƒ The JLin framework allows the development of own tests. If you want to capitalize on these options, one
developer with good to very good Java skills is needed.

1.4 System Requirements


ƒ JLin is part of the Developer Studio. Therefore, a Developer Studio installation is required.
ƒ Many of the predefined JLin tests described later in this document are available in all SAP NetWeaver
releases of the tool. Nevertheless, some tests have been implemented later in the release cycle and/or
were not ported down to lower releases. For technical reasons it is not possible to provide all checks in all
releases. All available tests in each release are listed in the default variant.

1.5 Duration and Timing

Managing code quality is a continuous process.

Creating and executing JLin inspections takes only a few minutes, even if many objects have to be checked.
Most time will be spent to analyze the check messages and to modify the code accordingly.

1.6 The JLin Tool: Basics

JLin is a tool to perform static tests and can be used for example to identify potential error sources like null
references or unchecked generic type operations. For example if a parameterized method or constructor is
invoked without using type arguments. JLin is also helpful to enforce code conventions like for example
naming conventions or One Statement per line. It is also possible to evaluate metrics and statistics like
Methods per class or Statements per method. All currently available tests are listed in chapter 2.3.

JLin can be used in two environments: As an Eclipse plug-in within the Developer Studio or inside the SAP
NetWeaver Development Infrastructure (Development Infrastructure), as part of a development component
(DC) build.

1.6.1 SAP NetWeaver Development Infrastructure

The Developer Studio provides access to the Java Development Infrastructure. It enhances the concept of an
IDE by server-side services, which centrally provides the development teams with a consistent development
environment and supports the software development during the entire life cycle of a product. Figure 1 shows
an overview of the elements of the Development Infrastructure.

© 2009 SAP AG - BP_Jlin_V30.doc page 4/57


Best Practice
Custom Code Management

Figure 1: Elements of the Development Infrastructure

ƒ Design Time Repository (DTR): Versioning source code management. Distributed development of
software in teams. Transport and replication of sources.
ƒ Component Build Service (CBS): Central build based on the component model.
ƒ Change Management Service (CMS): Central administration of the Java development landscape and the
transports covering the entire software life cycle.
ƒ Software Deployment Manager (SDM): Manual and automatic deployment of archives in central runtime
systems.
ƒ System Landscape Directory (SLD): Information on the system landscape.
- Name Service: Central check instance for the uniqueness of names.
ƒ Java Dictionary: Supports the global definition of tables and data types.
ƒ SAP Java test tools: Predefined static tests and runtime tests for Java development.

1.6.2 Basic elements

JLin knows three basic elements: the check variant containing the type of tests that should be performed
and the parameters of the tests, the source or projects that should be checked, and the execution. The
execution is a combination of a source/project and a check variant that can be executed to deliver the
inspection results.

© 2009 SAP AG - BP_Jlin_V30.doc page 5/57


Best Practice
Custom Code Management

Figure 2: Execution

SAP ships some predefined JLin tests, but it is also possible to develop own test (see chapter 2.2.6). The
predefined tests can be found in the DEFAULT variant.

© 2009 SAP AG - BP_Jlin_V30.doc page 6/57


Best Practice
Custom Code Management

2 Best Practice
2.1 Preliminary Tasks

Before using this tool, ensure that you perform the following preliminary tasks or checks in the system:
ƒ Set up a code check plan that fits to your company’s standards and procedures with regard to code quality
assurance. Answer the following questions:
- Do you expect your developers to proactively check their own code?
- Which projects or sources shall be checked?
- Which JLin tests do you want to perform?
- In which phases do you want to check the code? Permanently or only at special quality gates?
- Which role shall the JLin tool play in the code quality process?
- Are the default check priorities, as they come from SAP suitable?
- Which goals do you want to reach with respect to static code checks?
- Which procedures need to be set up to control that code checks are being executed?
- How can the code improvement process be monitored and how should the results be reported?
ƒ Depending on the answers given above, you may have to modify existing (global) check variants, so that
the executed checks fit your requirement profile. Maybe you also need to modify check priorities.

2.2 Procedure

The use of the JLin tool described in this document is only one way of controlling code quality. In some areas
you may find it more practicable to check code quality in another way (see chapter 1.2).

JLin has been designed thinking of three user groups:


ƒ Individual developers, who need a tool as part of the coding/testing development cycle
ƒ Quality managers, who need a tool to monitor the development of large-scale software projects
ƒ Final assembly teams, who need to ensure that the delivered product satisfies given quality standards

The following chapters show the main steps of the test procedure.

2.2.1 Installation

JLin is delivered as part of the Developer Studio installation. If you have installed the Developer Studio, you
have JLin installed.

2.2.2 Creating and editing variants

JLin is used to perform predefined static tests on Java sources. The tests are delivered as part of the
Developer Studio. All the predefined tests are included in the default variant. This initial variant cannot be
edited or removed. The groups of predefined tests are:
ƒ Eclipse Compiler Warnings (e. g. Constructor Name, Null Reference, …)
ƒ Tests (e. g. Block Test, Exception Test, …)
ƒ Logging (e. g. Logging and Tracing Test, Configuring Logging, …)
ƒ Security (e. g. Generic SQL Functions, Suspicious Functions, …)
ƒ Metrics (e. g. Global Counters, Methods per class, …)
ƒ EPTests (e. g. File access, NullPointer Check, …)
ƒ J2EE
- EAR (e. g. References Test, Uniqueness Test, …)
- EJB (e. g. Bean Interfaces, EJB Model Builder, …)
- WEB (e. g. Mapping Test, Web Model Builder, …)

© 2009 SAP AG - BP_Jlin_V30.doc page 7/57


Best Practice
Custom Code Management

An overview of all the tests within these groups can be found in chapter 2.3. The predefined tests cannot be
added or removed, but the user can create own variants, where the predefined tests can be activated or
deactivated. It also possible to create own tests (see chapter 2.2.6). Within the own variants, the user has the
possibility to adapt the checks according to the guidelines of the company. A variant consists of a number of
JLin tests along with their respective parameters. Also the parameter values of each test can be edited.

To configure own variants, go to Windows • Preferences • Java • JLin (see Figure 3 and Figure 4). A
default variant is delivered from SAP. It contains all available predefined tests.

Figure 3: NWDS Menu

© 2009 SAP AG - BP_Jlin_V30.doc page 8/57


Best Practice
Custom Code Management

Figure 4: JLin-tool menu

In order to create new variants, the default variant has to be copied to another name (see Figure 5) by

marking the default variant and clicking the Copy button ( ). For that, all variants have the
same predefined tests as the default.

A new variant can also be created by clicking the New button. In that case, the parameters are not set and
none of the tests are marked as selected. After clicking New or Copy, a name for the new variant has to be
entered (see Figure 5).

© 2009 SAP AG - BP_Jlin_V30.doc page 9/57


Best Practice
Custom Code Management

Figure 5: Create own variant

For most tests, the results of a JLin test run are displayed in the standard Problems view (in older releases
they are displayed in the standard Tasks view). It is also possible to export the results to a file, which can be
imported and displayed again in the Problems view. For that, the checkbox Export XML result files to
directory has to be checked and a directory has to be located (see Figure 6).

If JLin is executed manually from a project, the results of older test runs are remaining in the Problems view.
If these old results should be cleared, the option Clear old results has to be chosen.

It is also possible to set some Message Display Filter for a variant. Developers can suppress JLin messages
for their own code by inserting pseudo comments in their code (see chapter 2.2.4). By selecting Suppressed
messages only, only these JLin messages will be visible in the problems view.

In order to filter out less important messages, a priority threshold can be set. For example, if only priority
levels 1 and 2 (serious messages and warnings) shall be displayed, the priority threshold can be set to 2.

© 2009 SAP AG - BP_Jlin_V30.doc page 10/57


Best Practice
Custom Code Management

Figure 6: properties for variants

In the new variant, tests cannot be added or removed, they can just get activated or deactivated and their

parameters can be edited (mark the new variant can click Edit ).

© 2009 SAP AG - BP_Jlin_V30.doc page 11/57


Best Practice
Custom Code Management

Figure 7: Tree of JLin-Tests

The tests for the new variant can be activated or deactivated via the checkboxes (see Figure 7).

The “Fatal Priority Level” setting can be used to determine which messages will be shown as Errors and
which of them as Warnings in the Problems view. For example if you set Fatal Priority Level to 2, then all
priority 1 and priority 2 messages will be shown as errors (red) and priority 3 will be shown as warnings
(yellow).

In order to edit the parameters of a test, the corresponding test has to be right-clicked. The context menu
offers the possibility to Edit Parameters and Priorities (see Figure 9) and to display a description to each of
the tests. Before editing any of the parameters, it is recommended to read the description first. Figure 8
shows the topics considered in each test description.

© 2009 SAP AG - BP_Jlin_V30.doc page 12/57


Best Practice
Custom Code Management

Figure 8: Test description

Figure 9: Edit Parameters and Priorities of a test

Tests can only be activated if their parameters are set. The most trivial parameters are provided with default
values in the default variant.

The meaning of the icons in front of the test name is the following:

© 2009 SAP AG - BP_Jlin_V30.doc page 13/57


Best Practice
Custom Code Management

Table 1: Icon Descriptions

There are two types of parameter – string and string array. The values can be edited by clicking in the
corresponding value field and entering a parameter value (see Figure 10). Each value in a string array has its
own node. Nodes can be added or removed by using the context menu (see Figure 11).

Figure 10: Edit Test Parameters

© 2009 SAP AG - BP_Jlin_V30.doc page 14/57


Best Practice
Custom Code Management

Figure 11: Editing a string array

It is also possible to configure the priority of a message in the tests. All JLin test messages have a default
priority, which can be either 1 (Error), 2 (Warning) or 3 (Information). An additional option is disabled (no
message). In order to change the message priorities, the corresponding priority can be chosen from a drop
down list (see Figure 12).

Figure 12: Edit Message priority

After editing the parameters according to the company’s values and having activated the relevant tests, click
OK.

2.2.3 Executing tests

There are two possibilities to execute JLin tests: Either from the run menu or in the package explorer view.

© 2009 SAP AG - BP_Jlin_V30.doc page 15/57


Best Practice
Custom Code Management

From the run menu, you can create a reusable launch configuration that will test all the sources in a single
project or package, or test a single class. You have to choose Run • Open Run Dialog from the menu (see
Figure 13).

Figure 13: Open Run Dialog

In the Configurations pane, select JLin and choose • New_configuration. You have to enter a name for the
configuration. Select the sources that are to be tested: either a Java Element or a Working Set. After that,
enter the variant that is to be executed (see Figure 14). Choose • Apply and click • Run to execute the test
run (see Figure 15).

© 2009 SAP AG - BP_Jlin_V30.doc page 16/57


Best Practice
Custom Code Management

Figure 14: Create, manage and run configurations

© 2009 SAP AG - BP_Jlin_V30.doc page 17/57


Best Practice
Custom Code Management

Figure 15: Run a JLin test

Alternatively, you can select any combination of sources from the package explorer view for immediate
testing. You can choose one or several Java source file(s), packages, source roots or projects. Then go to
Run • Run As • JLin on the toolbar (see Figure 16). You will then be prompted to choose a variant (see
Figure 17). The tests in the variant will be run on your selection in the package explorer.

Figure 16: Executing tests from Package Explorer view

© 2009 SAP AG - BP_Jlin_V30.doc page 18/57


Best Practice
Custom Code Management

Figure 17: Choose variant

2.2.4 Suppressing messages

Developers can suppress some of the JLin messages for their own code by inserting pseudo comments in
their code. But there are certain checks that cannot be suppressed, for example Assertion Test. In chapter
2.3 you will find a list of all available tests. In the description of these tests within the Developer Studio, it is
mentioned if a pseudo comment is available or not.

At the properties for a variant, it is possible to select Display suppressed messages only. By enabling this
feature, only the suppressed messages will be visible in the Problems view.

To check if there is a pseudo comment defined for the test you want to disable, you have to display the test
description for the individual test (To display the test description see chapter 2.2.2 and Figure 8). Pseudo
comments disable a test for a certain sub tree of the abstract syntax tree used internally by JLin.

The general rule for pseudo comments is the following:

A pseudo comment must be the first line-end (//) comment directly (whitespaces allowed) following the
statement for which you want to disable the test. All JLin pseudo comments are of the form:

//$JL–<PSEUDOCOMMENT–ID OF TEST GOES HERE>$

The Catch Block Test for example uses the following pseudo-comment:

//$JL–EXC$

Example:

© 2009 SAP AG - BP_Jlin_V30.doc page 19/57


Best Practice
Custom Code Management

A certain method should not be used according to a JLin test. However you are sure you must use it and it is
OK in your case to do so:

forbiddenCall(); //$JL-<PSEUDOCOMMENT-ID OF TEST GOES HERE>$

Characters between // and $JL-<PSEUDOCOMMENT-ID OF TEST GOES HERE>$ as well as after


$JL-<PSEUDOCOMMENT-ID OF TEST GOES HERE>$ are allowed; however it is considered good style to
use pure pseudo-comment line-end comments. Any further info you want to include should go into comments
following this first line-end comment.

To disable a test for a whole block, the pseudo comment must be the first line-end (//) comment directly
(whitespace allowed) following the opening curly brace of the block for which you want to disable the test.

Examples:

To disable a test for a whole class, use


ƒ public class Disabled { //$JL-<PSEUDOCOMMENT-ID OF TEST GOES HERE>$
ƒ [...]
ƒ }

or a method:
ƒ public void disabled() { //$JL-<PSEUDOCOMMENT-ID OF TEST GOES HERE>$
ƒ [...]
ƒ }

or a block:
ƒ { //$JL-<PSEUDOCOMMENT-ID OF TEST GOES HERE>$
ƒ [...]
ƒ }

2.2.5 Using CBS

JLin can also be used within the SAP NetWeaver Developer Infrastructure as part of a Development
Component (DC) build.

SAP's Java development is fully based on components. Java development starts with the definition of a
development component and a detailed plan on which other component definitions the given component
depends. This plan also describes how to (re-) build the component once source changes have been made in
the component's source files. Component definitions and content are held in the Design Time Repository
(DTR).

DCs working on a project level of granularity add metadata to the project which defines the visibility of the
development objects.

The features of the component model are the following:


ƒ Structuring application into easily reusable objects
ƒ DC types for all Java based development
ƒ Encapsulation of functionality due to the DC-visibility concept (black box principle)
ƒ Explicit definition of public parts (DC-interfacing) and use dependencies (where-used list)
ƒ Component API to retrieve component definitions
ƒ Component handling (link to related areas like component repository and software logistics)

© 2009 SAP AG - BP_Jlin_V30.doc page 20/57


Best Practice
Custom Code Management

The Component Build Service (CBS) is the central build environment in the development infrastructure taking
care also of the management of the archives needed in each development project. The CBS stores all
archives that are used during development in separate storage spaces for each product state. This way it's
guaranteed that every developer accesses the archives he needs. We can differentiate between two states of
archives: Archives from used software components (SCs) are readily imported into the CBS build space
before development starts so there is a common basis for the whole team to start with. The newly created
archives that result from development are produced in the build process and stored in the same build space.
Because the same set of available components is used there are no inconsistencies in the build space. That
true also for newly created DCs: Because the central storage of the archives each developer accesses the
latest build results automatically when he or she downloads used archives to their Developer Studio. More
than that there is a separation of DCs that have been newly created and those that have been activated by a
central build. By convention every developer should use only those objects that have already been activated.
Because in the build process used archives are only used from the build space – not the developer's local
machine – the build result is in sync with the actual state of the build space. The only exception is if a
developer uses his own objects or objects from a direct team member that are not yet available in an
activated form. To guarantee that the build space is always up to date, dependent DCs are rebuilt
automatically if a used DC is changed. The build process in the CBS is based on the use of SAP’s
component model. DCs are the units of the build process in the CBS. The build is triggered by the developer
who activates his changes stored in his closed activities by starting the central build. Activated changes can
be safely used by other developers: They are in sync with the most up-to-date versions available in the
database.

In order to run JLin using CBS you need to switch on a special build option in your development configuration
file (.confdef) for every SC and build variant for which you want to run JLin. You can configure the SCs using
the Web UI of your CMS. (Landscape Configurator • Choose a track • Track Data • Software
Components • Choose an SC • View/Edit XML content).

Sample .confdef snippet:

© 2009 SAP AG - BP_Jlin_V30.doc page 21/57


Best Practice
Custom Code Management

<build-variant name="default" required-for-activation="yes">

<build-options>

<!-- switch on JLin -->


<build-option name="jlin_run">
<option-value>true</option-value>
</build-option>
<!--
optional test configuration file URL; if not specified, the
installation
default config file applies. A custom file should be stored in the
corresponding DTR. Note that you need to specify a user which has read
access to DTR. You can create/edit such a file using the IDE and then
export it to XML.
-->
<build-option name="jlin_testconfig_file">
<option-
value>http://anzeiger:display@DTR_HOST:PORT/dtr/ws/TRACK/sap.com_MY_SC/dev/act
ive/DCs/sap.com/jlinconfig/_comp/src/packages/config/testconfig.xml</option-
value>
</build-option>

</build-options>

</build-variant>

On successful build, you should get a raw JLin XML result file in the /gen/logs/ folder of the Development
Component which you built.

2.2.6 Create own tests

With the JLin framework it is also possible to write, run, test and contribute own static Java source code
checks/metrics. For that, JLin requires SAP NetWeaver Developer Studio 7.1.x.

There are several things to be considered before actually implementing a static source code test:

First you have to check for all currently available JLin tests and make sure that there is no such check
implemented already. All currently available tests are listed in chapter 2.3. You can also have a look in the
DEFAULT variant which contains all available tests.

Many tests simply check for the usage of some old or no longer supported API. Consider making the methods
deprecated instead. This will give a much more direct feedback to the user. If you want to restrict the usage of
some API, you should also consider defining a public part or facade that has an Access Control List (ACL).

Try to reuse existing tests instead of solving similar problems twice. Read the descriptions of the existing
tests to find out if you could reuse something. A common example is the restricted components test: This test
allows you to detect usage of certain packages/classes/fields/methods.

You can add more classes simply by changing the XML configuration file. Another way to reuse an existing
test is to define a new test which extends the existing test class.

© 2009 SAP AG - BP_Jlin_V30.doc page 22/57


Best Practice
Custom Code Management

Writing a simple Java Test

In order to create a blank new plug-in project, use the PDE project wizard (File • New • Project • Plug-in
Development • Plug-in Project).

In plugin.xml, go to the Dependencies tab and add

com.sap.tc.jtools.jlin.ui,

com.sap.tc.jtools.jlin.java.core,

com.sap.tc.jtools.jlin.core

as plug-ins that your plug-in depends on (see Figure 18).

Figure 18: Dependencies

Use the new JLin Test Class wizard to create a JLin test class and create/update the tests descriptor file
ƒ Choose File • New • Other • Java • JLin • JLin Test Class
ƒ Specify package, class name, display name, responsible, description
ƒ Choose a test type (in this example: Java test)
ƒ Choose a project-relative test descriptor file (a new one will be created if you specify the name, e. g.
data/tests.xml)
ƒ Add a message description consisting of a resource bundle key, priority and display name for each
message that the test may produce as part of a test result, e. g. here: message key mytest.1

© 2009 SAP AG - BP_Jlin_V30.doc page 23/57


Best Practice
Custom Code Management

ƒ Optionally add test parameters that can be set by the test user at runtime, e. g. parameter par1 of type
String
ƒ Optional: specify test category (for organizing tests in groups of tests), here: mytests. Press Next.
ƒ Optionally specify a pseudo-comment ID, here: MYTEST. This is used to switch off tests by means of
pseudo comments (format: //$JL-<PSEUDOCMT-ID>$). Note: It should be checked that the pseudo
comment is unique, in other words it does not overlap with already existing pseudo comments.
ƒ Optionally specify a resource bundle used for the localization of the messages produced by this test (here:
leave empty)
ƒ Press Finish to generate a new JLin test class which extends
com.sap.tc.jtools.jlint.jom.JomTestVisitor. This class implements the visitor pattern.
ƒ Getter methods for test display name and parameters (if any) are generated
ƒ A new test descriptor file data/tests.xml is added to the project. It contains the meta-information about the
test class that you have just provided (if you create more JLin test classes in this project, their description
will be added to an already existing descriptor)
ƒ The superclass com.sap.tc.jtools.jlint.jom.JomTestVisitor provides stub visitor methods: boolean visit
(<NodeType>) and void endVisit (<NodeType>) for all Java node types. These methods will be called by
the JLin framework when traversing the abstract syntax tree (visit (<NodeType>)) when descending a
node, endVisit (<NodeType>) when the traversal of the <NodeType> subtree is finished.
if you return true, all child nodes of this node will be traversed, too (in general this is the case)
ƒ Use right-click • Source • Override/Implement Methods… in the editor and pick any visit methods you
wish to override, e.g.

public boolean visit(IMethodDeclaration node);

In the method body, you can use

addError(

String messageKey,

Properties messageParameters,

Position position)

to create messages that you want to be put into the test result.

messageParameters are String key-value pairs that can be used to construct a localized message.

If you specify the priority, use the constants declared in

com.sap.tc.jtools.jtci.interfaces.ResultInterface:

/**
* Severity level used for JLin-internal errors
*
*/
public static final int SEVERITY_INTERNAL_ERROR = 0;
/**
* Severity level used for errors
*
*/
public static final int SEVERITY_ERROR = 1;
/**
* Severity level used for warnings

© 2009 SAP AG - BP_Jlin_V30.doc page 24/57


Best Practice
Custom Code Management

*
*/
public static final int SEVERITY_WARNING = 2;
/**
* Severity level used for information messages
*
*/
public static final int SEVERITY_INFO = 3;

All nodes that have a position (line and column) inside the java file implement
com.sap.tc.jtools.jlint.jom.interfaces.Position.

In our example test class sourcecode, we override public boolean visit(IMethodDeclaration


node) and generate a message for each method visited:

package test;

import java.util.Properties;

import com.sap.tc.jtools.jlint.Result;
import com.sap.tc.jtools.jlint.jom.JomTestVisitor;
import com.sap.tc.jtools.jlint.jom.interfaces.IMethodDeclaration;

public class MyTest extends JomTestVisitor {

public MyTest() {
}

public boolean visit(IMethodDeclaration node) {


Properties msgProps = new Properties();
msgProps.setProperty("par1", getPar1());
msgProps.setProperty("method", node.getName());
addError("mytest.1",msgProps, node);
return true;
}

We declare that all tests in the category mytests use test.Messages as resource bundle for result
localization by adding the green line to our example tests descriptor (data/tests.xml):

<?xml version="1.0" encoding="utf-8" ?>


<TOOL_DESCRIPTOR VERSION="1" NAME="JLIN">
<TESTS>
<TESTS CATEGORY="mytests" RESOURCE_BUNDLE="test.Messages">
<TEST RESPONSIBLE="D037913" LABEL="MyTest" VERSION="1">
<DESCRIPTION>MyTest</DESCRIPTION>
<TEST_OBJECT_TYPE>Java file list</TEST_OBJECT_TYPE>
<INTERNAL_PARAMETERS>
<PSEUDO_COMMENT_SUFFIX>MYTEST</PSEUDO_COMMENT_SUFFIX>
<TEST_CLASS>test.MyTest</TEST_CLASS>
</INTERNAL_PARAMETERS>
<SIGNATURE>
<INPUT_PARAMETER NAME="par1" TYPE="STRING" />
</SIGNATURE>
<MESSAGES>

© 2009 SAP AG - BP_Jlin_V30.doc page 25/57


Best Practice
Custom Code Management

<MESSAGE DISPLAYNAME="mytest.1" KEY="mytest.1"


PRIO="1" />
</MESSAGES>
</TEST>
</TESTS>
</TESTS>
</TOOL_DESCRIPTOR>

We create a new file Messages.properties in the test package that will be used as resource bundle. The
message key mytest.1 we used above has to be defined in this file:

mytest.1=visited method {method}, par1 value: {par1}

Names in curly brackets will be replaced by the value of the message parameter with the corresponding
name (file and par1 in this case). To internationalize your test messages, you would simply add properties
files, e. g. Messages_de.properties to enable for German messages if the locale is German.

We still have to declare our new test(s) by using the extension point

com.sap.tc.jtools.jlin.ui.tests:
ƒ Go to plugin.xml, extensions tab
ƒ Choose Add…, select com.sap.tc.jtools.jlin.ui.tests
ƒ Press Finish
ƒ Right-click on com.sap.tc.jtools.jlin.ui.tests and choose New • testSet
ƒ In the properties view for testSet, choose for descriptorFile: data/tests.xml and for moduleId:
com.sap.tc.jtools.jlin.java.ui.javaModule.

Debug your test

Create a launch configuration for testing your test class:


ƒ Choose Run • Debug • Eclipse Application • New
ƒ In the Plug-ins tab, select Choose plug-ins and fragments to launch from the list and check your
plug-in project and all external plug-ins
ƒ Press Debug

After the eclipse runtime workbench has started, when you go to Window • Preference • Java • Jlin, your
new test should show up in the DEFAULT variant. Create a new variant with your new test as the only active
test (and set its parameters if any, here: par1)

Pick any Java source file, package or project in the Package Explorer, right-click and choose Run As • JLin
with your test variant.

In our example, you should see one message per visited method in the Problems view with the following
description:

JLin MyTest: visited method <METHOD_NAME>, par1 value: <PAR1_VALUE>

If you double-click on the message, the editor will open on the corresponding Java file and line.

Try if you can switch off your test by appending the pseudo comment //$JL-MYTEST$ to the end of a
method declaration line and re-running JLin on the same file.

© 2009 SAP AG - BP_Jlin_V30.doc page 26/57


Best Practice
Custom Code Management

Additional Hints
ƒ If a runtime exception is thrown from within a test, JLin will catch this exception and log its stack trace into
the results XML file as a message with severity =0 (see SEVERITY_INTERNAL_ERROR above). Results
with this severity will not show up in the eclipse task list or in a generated HTML report, so you will have to
check the result file for internal errors.
ƒ For further examples of how to implement tests or metrics, have a look at the classes in
com_sap_tc_jtools_jlin_jom_tests.jar (should be among the jars your plug-in project depends on).
ƒ If you want your test to run on code that has been classified with a special attribute only, you should
override
public void setParameters(ParameterInterface[] parameters,
com.sap.tc.jtools.jtci.TestObject testObject), call super.setParameters() and use
TestObject.getAttributes() to find out about the attributes the test object has been assigned by
the code classification. Use the String constants defined in
com.sap.tc.jtools.jtci.CodeClassificationConstants only. E. g. override
visit(ICompilationUnit) and stop further traversal of the tree by returning false if the classification
attribute(s) you are looking for is not found. For now automatic code classification can only be done based
on the DC information (DC type, public parts…) available during DC make.

Writing a simple Java Metric

Use the new JLin Test Class wizard (see above). Choose Java Metric as test type. After you pressed Next
you can specify metric name(s) and statistic quantities like sum, average, max, min and standard deviation.

A metric represents a floating point measurement quantity to which measured values can be added. Statistics
such as average, standard deviation etc. are computed automatically.

In this example, we want to measure the number of methods per class/interface, so we enter methodcount
as metric name and check average, max, min and standard deviation as statistics. After pressing Finish, your
tests descriptor file should contain an entry similar to this one:

<TEST RESPONSIBLE="D037913"
RESOURCE_BUNDLE="com.sap.tc.jtools.jlint.tests.metrics.reso
urces.Messages" LABEL="MyMetric" VERSION="1">
<DESCRIPTION>MyMetric</DESCRIPTION>
<TEST_OBJECT_TYPE>Java file list</TEST_OBJECT_TYPE>
<INTERNAL_PARAMETERS>
<TEST_CLASS>test.MyMetric</TEST_CLASS>
</INTERNAL_PARAMETERS>
<SIGNATURE>
<INPUT_PARAMETER NAME="METHODCOUNT_INFO_LEVEL"
TYPE="FLOAT">
<VALUE>0.0</VALUE>
</INPUT_PARAMETER>
<INPUT_PARAMETER NAME="METHODCOUNT_WARNING_LEVEL"
TYPE="FLOAT">
<VALUE>0.0</VALUE>
</INPUT_PARAMETER>
<INPUT_PARAMETER NAME="METHODCOUNT_ERROR_LEVEL"
TYPE="FLOAT">
<VALUE>0.0</VALUE>
</INPUT_PARAMETER>
</SIGNATURE>
</TEST>

© 2009 SAP AG - BP_Jlin_V30.doc page 27/57


Best Practice
Custom Code Management

Thus a class extending com.sap.tc.jtools.jlint.jom.metrics.JomMetricVisitor should have been created.


JomMetricVisitor in turn extends JomTestVisitor and thus implements the same visitor algorithm as used
for Java Tests above. For notifying JLin of a measured quantity, use

protected final void addMetricValue(


String metricName,
float value,
Position pos);

In this case, we override

public boolean visit(ITypeDeclaration node);

to notify about the number of methods for each class/interface:

package test;

import com.sap.tc.jtools.jlint.jom.interfaces.ITypeDeclaration;
import com.sap.tc.jtools.jlint.jom.metrics.JomMetricVisitor;
import com.sap.tc.jtools.jlint.jom.metrics.Metric;

public class MyMetric extends JomMetricVisitor {

/** keep in sync with tests.xml! */


private static final String METRIC_NAME = "methodcount";

public MyMetric() {
}
protected final MetricInfo[] getMetricInfos() {
return new MetricInfo[] {
new MetricInfo(
METRIC_NAME,
MetricInfo.AVERAGE | MetricInfo.MIN | MetricInfo.STD_DEV |
MetricInfo.MAX)};
}

public boolean visit(ITypeDeclaration node) {


addMetricValue(METRIC_NAME, node.getMethods().length, node);
return true;
}

Now try out your metric using a runtime workbench (see above). Note that each metric has three parameters
per metric name:

<metric_name>_INFO_LEVEL, <metric_name>_WARNING_LEVEL, <metric_name>_ERROR_LEVEL.

You can set these at runtime to specify the threshold from which on a message of the given severity will be
generated for a single measurement event. A typical use case for these thresholds would be to run the metric
on a large amount of sources with very high thresholds, check the maximum value and then set the
thresholds just beneath it in order to pinpoint locations in source that cause high values.

A single message with the statistics you specified is always created and attached to the Java project under
test.

© 2009 SAP AG - BP_Jlin_V30.doc page 28/57


Best Practice
Custom Code Management

In our case, you should see one statistics message similar to this one:

JLin MyMetric: methodcount average: 10.0, standard deviation: 0.0, min: 10.0,
max: 10.0

on the project level and several other messages pointing to individual measured quantities (depending on
your sources under test and the thresholds you have set):

JLin MyMetric: methodcount value: 10.0

2.2.7 Results

When the variant has finished executing, you will get a summary consisting of the total number of messages
and the number of messages in each priority category (see Figure 19).

Figure 19: Result summary

The results of a JLin run are displayed in the standard Problems view. JLin results are categorized as
warnings and can have priority high (error), normal (warning) or low (info) (see Figure 20).

Figure 20: Results in the Tasks/Problems view

Double-click or right-click • Go to takes you to the line in the source code that has been detected by the
test as problematic. You can also get a description of the JLin warning as a popup if you hover over the
warning icon ( ). Just as with compiler warnings, you will see little decorator icons in the package explorer
(see Figure 21).

Figure 21: decorator icons in package explorer

© 2009 SAP AG - BP_Jlin_V30.doc page 29/57


Best Practice
Custom Code Management

To show the test description for a JLin test, right-click on the message in the Problems view and choose
Display Test description.

The filter function in the Problems view has an entry for JLin. You can set a filter for JLin problems using the
Filter Button ( ) in the Problems view (see Figure 22).

Figure 22: Setting a filter

2.2.8 Import a result set

You can display results that have previously been exported to an XML file. Either choose File • Import

( ) from the menu or right-click in the package explorer and also choose “Import…” ( ).

As an import source select Other • JLin result (see Figure 23).

© 2009 SAP AG - BP_Jlin_V30.doc page 30/57


Best Practice
Custom Code Management

Figure 23: Import source

You have to specify the XML file and the corresponding eclipse project which the results refer to (see Figure
24). It is also possible to Clear all JLin problem markers in selected project before importing. Therefore
you have to check the corresponding box.

© 2009 SAP AG - BP_Jlin_V30.doc page 31/57


Best Practice
Custom Code Management

Figure 24: Specify XML file

After clicking Finish, the results will be displayed in the Problems view just the way they would be if you
generated them on the fly.

2.3 JLin Tests

JLin offers an open framework that can be extended by new tests. Over the time, the number of check
categories and tests has grown. We will present here the status as of release SAP NetWeaver Developer
Studio 7.1. All available tests in each release can be found in the default variant. A short description to all of
these tests can also be found within the SAP NetWeaver Developer Studio.

2.3.1 Eclipse compiler warnings

Test What it does

AccessEmulation Access a private member (fields or methods) of the enclosing class


inside an inner class (anonymous, local or member classes).
The compiler uses a static access method to access the private
member in order to workaround the VM access violation. You
cannot access directly a private member from another class. From
the VM point of view, an inner class is a different class and has no
relation with its enclosing class.
So doing this access to a private member you pay the price of a
method invocation each time you access the member at runtime.

© 2009 SAP AG - BP_Jlin_V30.doc page 32/57


Best Practice
Custom Code Management

Test What it does


This is not the case if the member is package visible.

AccidentalBooleanAssign Mostly a spelling error trying to compare two values but forgetting
the second =.
(e. g. a = b instead of a == b)

AnnotationSuperInterface In J2SE 5.0, the Java language allows a class to implement an


annotation type.

AssertUsedAsIdentifier Checks if assert is used as identifier. Trying to compile the code


with JDK 1.4 or greater will result in an error.

Autoboxing The J2SE 5.0 autoboxing capability is powerful but it can lead to
unexpected behavior especially when passing arguments. This test
introduces a diagnosis that indicates when autoboxing or
autounboxing is performed.

Compiler This test reports all compile errors of the Eclipse JDT compiler
which normally leads to an interruption of the compile process. All
warnings are therefore set to high priority.

ConstructorName Checks if a method has a constructor name.

EmptyStatement Searches for empty control flow statements and superfluous


semicolons.

EnumUsedAsAsIdentifier Checks if enum is used as identifier. Trying to compile the code


with JDK 1.5 or greater will result in an error.

FieldHiding A field is hiding a field or is hiding a local variable defined in an


enclosing type scope.

FinalBlocks Checks if break, continue, return or throw is used inside a finally


block. If you return from within a finally block, an uncaught
exception thrown in the try block is silently swallowed.

FinalParameterBound In J2SE 5.0, a type parameter should not be bounded by a final


type (e.g. Integer, String). Final types cannot be further extended.

IncompleteEnumSwitch For J2SE 5.0, this test can flag incomplete enum switch statements.

IndirectStaticAccess When enabled, the compiler will issue an error or a warning


whenever a static field or method is accessed in an indirect way. A
reference to a static member should preferably be qualified with its
declaring type name.

InvalidJavadocTags Checks for errors in Javadoc comments and tags. It detects invalid
@link, @return, @see, @throws tags and malformed arguments,
references. Furthermore unexpected and invalid tags are reported.

LocalVariableHiding A local variable or argument is hiding a field or is hiding a local


variable defined in an enclosing type scope.

© 2009 SAP AG - BP_Jlin_V30.doc page 33/57


Best Practice
Custom Code Management

Test What it does

MaskedCatchBlock Locally to a try statement, some catch blocks may hide others, e.g.
try { throw new java.io.CharConversionException();
} catch (java.io.CharConversionException e) {
} catch (java.io.IOException e) {}.
MissingDeprecatedAnnotation In J2SE 5.0, the Java compiler recognizes the @Deprecated
annotations, and treats them equivalent to the doc comment /**
@deprecated */. This test can optionally flag deprecated fields,
methods and types missing a proper @Deprecated annotation (to
encourage using annotations instead of doc comment tag).

MissingJavadocComments Reports missing Javadoc comments.

MissingJavadocTags Checks if the Javadoc tags @param, @return or @throws are


missing.

MissingOverrideAnnotation In J2SE 5.0, this test can flag a method overriding a superclass
method, but missing a proper @Override annotation.

NoEffectAssign The Test will issue a warning whenever an assignment has no


effect (e. g. 'x = x').

NoImplicitStringConversion The test will issue a warning whenever a char[] expression is used
in string concatenations:
hello + new char[]{'w','o','r','l','d'}

NonExternalStringLiterals The test will issue a warning whenever a String literal has no
following //$NON-NLS-[NR]$ in the same line. Normally all String
literals should be fetched from an external file in terms of
translation.

NonInheritedInterface The test will issue a warning whenever an interface defines a


method incompatible with a non-inherited Object method. Until this
conflict is resolved, such an interface cannot be implemented.

NonStaticAccessToStatic The test will issue a warning whenever a static field or method is
accessed with an expression receiver. A reference to a static
member should be qualified with a type name.

NullReference The test will issue a warning whenever a local variable reference is
unnecessarily checked for (non-)null. It was either set to a (non-
)null value or assumed to be (non-)null when last used.

OverridingNonVisibleMethod A package default method is not visible in a different package, and


thus cannot be overridden.

ParameterAssignment The Test will issue a warning when an assignment is made to a


method parameter.

PotentialNullReference The test will issue a warning whenever a variable is statically known
to potentially hold a null value.

© 2009 SAP AG - BP_Jlin_V30.doc page 34/57


Best Practice
Custom Code Management

Test What it does

RedundantNullCheck The test will issue a warning whenever a variable that is statically
known to hold a null value is used to access a field or method.

SerialVersionUID The will issue a warning if a serializable classes is missing a


declaration of a serialVersionUID field.

Switch Case Fall-Through Checks for switch cases which fall through – whether there are
case statements without a break statement after them. Without an
explicit brake the program control will flow sequentially through
subsequent case statements.

TypeParameterHiding In J2SE 5.0, a generic type parameter can hide another type. This
test flags such a construct.

UncheckedTypeOperation In J2SE 5.0, the compiler will issue an error or a warning whenever
it encounters an unchecked generic type operation e.g. invoking a
parameterized method or constructor without using type arguments.

UndocumentedEmptyBlock The test will issue a warning whenever an empty block is not
documented. Mostly an empty block is a leftover following some
programming ideas.

UnhandledWarningToken In J2SE 5.0, this test detects unhandled warning tokens used as
arguments of the annotation @SuppressWarnings.

UnnecessaryElse The test checks if a statement is unnecessarily nested within else


clause. The corresponding then clause does not complete normally.

UnnecessaryTypeCheck This test finds unnecessary casts and instance of operations.

UnqualifiedFieldAccess This test finds non-qualified references to an instance field. It


supports a coding style where all references to instance fields are
qualified in order to make them visibly distinct from references to
local variables.

Unused Label Checks for unused break or continue labels.

UnusedArgument Checks for unused arguments. If


REPORT_IMPLEMENTING_ABSTRACT = true also arguments
when implementing abstract methods are detected. If
REPORT_OVERRIDING_CONCRETE = true also arguments when
overriding concrete methods are detected.

UnusedImport Checks for unused imports.

UnusedLocalVariable Checks for unused local variables.

UnusedPrivateMember Checks for unused private types, fields, methods and constructors.

UnusedThrownException Checks for unused thrown exceptions in methods and constructors.


If CHECK_OVERRIDING_METHODS = true also overriding
methods are detected.

© 2009 SAP AG - BP_Jlin_V30.doc page 35/57


Best Practice
Custom Code Management

Test What it does

UsingDeprecatedAPI Checks for the usage of deprecated types, fields, methods and
constructors.
If CHECK_OVERRIDING_METHODS = true the test will also signal
when trying to override a deprecated method.

VarargsArgumentNeedCast In J2SE 5.0, this test can flag suspicious varargs method
invocations. A null last argument is not wrapped as a 1-element
array as one might expect; adding an explicit cast makes the
intention of the code clear.

Table 2: Eclipse compiler warnings

2.3.2 Tests

Test What It does

Accessibility Checks if the SAP Accessibility Product Standard is fulfilled.


Product Standard
All user interface elements and relevant information in an application shall be
available to and usable by users with disabilities, including users who employ
assistive technologies such as screen readers and screen magnifiers.
ƒ The user must be able to get to everything using only the keyboard (keyboard
access and navigation).
ƒ The user must be able to see and/or hear what everything is (identification).
ƒ If an action is available, the user must be able to perform that action (keyboard
access).

Assertion Test This test checks for the usage of the Java assert statement (since JDK 1.4).
Assertions should generally not be used at SAP because:
1. A failed assertion results in AssertError which is of type Error. Errors usually
are used as signal for VM exit, because they represent a very heavy problem in
runtime, which cannot be recovered. Examples are OutOfMemoryError,
LinkageError(s). In general, assertions should be very carefully set, which is
not the case within SAP.
2. SAP Exception framework: Where AssertError is logged, SAP Exception
framework is ignored in this case. If an exception has to be thrown, the Exception
framework should be used which is SAP standard.
3. Wrong usage. Currently some assertions are used as a method arguments
check. This is wrong, since it changes the semantic of normal behaviour.
Normally method arguments boundaries are part of method contract and if this
contract is broken then a set of standard exceptions can be used :
ƒ IllegalArgumentException if argument is breaking the contract.
ƒ NullPointerException if argument is null and null is not
allowed(java.util.Hashtable) - IndexOutOfBoundsException
4. Switch of assertion mode requires VM restart. It is much more useful to have a

© 2009 SAP AG - BP_Jlin_V30.doc page 36/57


Best Practice
Custom Code Management

Test What It does

system property which can be switched on/off in runtime and when it is on, then
we can check conditions and throw/log an exception. This can be used as debug
option and does not require VM restart.

Assignment Test This JLin test checks for questionable assignments, i.e.
ƒ boolean assignments within conditional expressions
ƒ assignmnents to for loop variables outside the loop initializer

Block Test This test checks if body statements of if, else, for and while are included in a block.
If no block is used, readability of the code can be impaired.

Cloneable Test This test checks if classes that implement the empty java.lang.Cloneable
interface declare implement a public Object clone() method.
It also ensures that classes overriding public Object clone() method are
implementing java.lang.Cloneable tag interface as well.

Close Connections Checks if connections opened to I/O resources are closed properly.
The check is performed on method level, meaning that connections declared and
opened within the method body are checked.
If the created connection is passed outside of the method (via method/constructor
call or assignment to a field) a low priority message is generated.
Also if the connection is closed, but outside of a finally block a low priority message
will be generated.
The classes that are checked include implementations of java.sql.Connection,
java.sql.Statement and java.sql.ResultSet as well as extensions of
java.io.InputStream, java.io.OutputStream, java.io.Reader and
java.io.Writer. However there are several classes that do not provide specific
implementation of the close method and thus calling it does not take any effect. The
classes that are not checked for closing are java.io.ByteArrayInputStream,
java.io.ByteArrayOutputStream, java.io.StringBufferInputStream,
java.io.StringWriter and java.io.CharArrayWriter.

DB/OS Portability This test checks for DB- or OS-specific coding.


It checks if:

ƒ OS-specific file path names ('\\', windows drive letters, windows UNC share paths)
are used
ƒ OS-specific line separators '\r' and/or '\n' are used
ƒ OS-specific system properties os.name, os.arch, os.version or
java.library.path are used
ƒ OS-specific environment variables are accessed using java.lang.System.getenv()
ƒ native methods are declared or java.lang.System.load*() or
java.lang.Runtime.load*() methods are used

Development Checks if the SAP Development Environments Product Standard is fulfilled.


Environments
The standard defines which development environments are used as a default at SAP
Product Standard

© 2009 SAP AG - BP_Jlin_V30.doc page 37/57


Best Practice
Custom Code Management

Test What It does


to develop and run applications and solutions.
For each development environment and content type, the standard defines rules to
be followed when using the development environment. These rules comprise (but are
not limited to) the criteria:
ƒ Platform independence (Hardware, OS, DB)
ƒ Involvement in standard development and deployment process
ƒ Correct enablement of the UI and testability
The standard also defines requirements for the development environments
themselves. These requirements must be considered by the creators of the
development environments. Examples: ability of development applications to support
multiple languages, ability to debug applications or transportability.

Double-Checked This test detects the double-checked locking (DCL) antipattern.


Locking
DCL is an often used pattern for implementing lazy initialization in a multithreaded
environment which does not work. The reasons why this pattern is not thread-safe lie
in the Java memory model (See the articles referenced for details).
How to fix it?
Either use method-level synchronization or use static fields. Only with JSR 133
(revision of the Java memory model) incorporated in Java 5 there is way to make
DCL work correctly by using the redefined semantics of the volatile keyword.
NOTE that this will only work when using a Java runtime starting from version 5 on.

Eclipse API This test checks if org.eclipse.* classes used are part of official API, i.e. are not inside
a org.eclipse.*.internal.* package.

EJB programming This test checks the programming restrictions for EJBs (see the EJB spec):
restrictions
forbidden packages: java.awt, javax.swing, java.lang.reflect
forbidden classes: java.lang.ClassLoader, java.io.File,
java.lang.SecurityManager, java.lang.Thread,
java.io.FileDescriptor, java.lang.Runtime
forbidden methods: java.lang.System.exit(),
java.lang.System.setErr(), java.lang.System.setIn(),
java.lang.System.setOut(), java.lang.System.load(),
java.lang.System.loadLibrary()
It is triggered for all classes that implement javax.ejb.EnterpriseBean.

EJB serializable This test checks if all method parameter types and return types declared on the
parameters remote interface of an EJB (i.e. an interface that extends javax.ejb.EJBObject)
implement java.io.Serializable or java.rmi.Remote.
It will only generate a message if the runtime type can not be serializable, i.e. the
type neither implements java.io.Serializable nor java.rmi.Remote nor
provides a no-args constructor.

Equals/HashCode This test checks that if public boolean equals(Object obj) is overridden,
Test public int hashCode() is also overridden and vice versa. Overriding only one of
these methods with changed semantics (breaking the contract that is described in
java.lang.Object.equals) will lead to objects that cannot be stored/retrieved

© 2009 SAP AG - BP_Jlin_V30.doc page 38/57


Best Practice
Custom Code Management

Test What It does


correctly in hash-based collections. The problem might only show up when hashkeys
collide in the set. This means that testing with small sets of data may work, but as
soon as huge amounts of data are used, the code may behave unexpectedly. As the
developer of a class usually does not know if it will be stored in a hash-based
collection later on, and the user of a class will not expect that a contract from
java.lang.Object is broken in that class, this kind of error is very likely to remain
undetected. The test also checks if you declare any public boolean equals()
methods. This can also break the contract of equals and hashCode.
How to fix it • See test description

Exception Test This JLin test checks for some exception-related antipatterns:
ƒ throw or catch Throwables that are not subclasses of java.lang.Exception
ƒ catch unrecoverable VM errors (java.lang.VirtualMachineError and
java.lang.ThreadDeath)
ƒ catch an exception and throw a new one that doesn't preserve the causing
exception's stacktrace
ƒ (optionally) define a subclass of Throwable that is not a subclass of
java.lang.Exception
ƒ (optionally) throw or catch too generic exception (i.e. java.lang.Exception)
Unrecoverable VM errors should never be caught unless re-thrown. If they are caught
without re-throwing, subsequent behavior of the VM is undefined.
If you have to catch Throwable, use the following pattern to ensure you don't catch
one of these unrecoverable errors:
try {
doSomething();
} catch (VirtualMachineError vme) {
throw vme;
} catch (ThreadDeath td) {
throw td;
} catch (Throwable t) {
// handle the Throwable caught
}

Extendable Classes Test for constructors/behaving like constructors methods (which includes clone for
Initialization Cloneable classes and readObject plus readObjectNoData for Serializable
classes). This test checks only classes that can be extended.
It ensures that no methods that can be overridden are called directly or indirectly
during class initialization.
The calling of overriddable methods (which can have different behaviour in
subclasses) on non-completely created object (i.e. not all of the fields of superclass
are initialized explicitly) possesses a risk that in a subclass this methods can be
overridden to use the superclass instance variables which at this moment are
implicitly initialized to their default values (e.g. 0 for int, false for boolean, null for
reference types etc.), because at the moment these methods are called the
superclass is not fully initialized. This directly results in an exceptional situation in the
subclass and finally results in initialization failiure (and broken clone, not working
deserialization respectively).

© 2009 SAP AG - BP_Jlin_V30.doc page 39/57


Best Practice
Custom Code Management

Test What It does


A similar error scenario during static initialization is also detected by this test:
If a superclass accesses any subclass during its static initialization, it may see the
statically not yet initialized subclass.
Even worse, due to lazy class loading and static initialization in Java, the result of
static initialization in this scenario depends on which of the two classes (super- or
subclass) is accessed first at runtime.
For more information see the references.

Finalization Test This test checks if:


ƒ finalize() is overridden. You should avoid overriding finalize() because
when this method is invoked depends on the garbage collection mechanism
specific to the VM and there is no guarantee that this method will be called at all.
ƒ if finalize() is overriden, super.finalize() should be called from
finalize()
ƒ finalize() should only be invoked by the garbage collector, not explicitly

Functional Checks if the SAP Functional Correctness Product Standard is fulfilled.


Correctness
Functional correctness is regarded as a key quality characteristic of software. A lack
Product Standard
of functional correctness makes the software solution worthless from a customer’s
perspective. The minimum requirements regarding functional correctness every SAP
product has to meet are described in this standard and are incorporated in templates.
Focus areas are interfaces, programs that are relevant to upgrades, adequate test
coverage, and results regarding major functions and scenarios.

Globalization Checks if the SAP Globalization Product Standard is fulfilled.


Product Standard
In order to meet global market requirements, solutions need to ensure that these
globalization features are implemented. Globalization consists of Internationalization
and Localization.
Internationalization focuses on the technical components but also all other programs
to be developed in order to support multiple cultural and technical environments (e.g.
Unicode enabling, Data Communication & Encoding, Text Processing, Cultural
Awareness, Display, Input, Printing, Time zones, Translatability, Localizability)
Localization mainly affects applications to adapt the software to country-specific
needs. This covers legal requirements, common business practices and the
corresponding translation for the countries within the scope.

Illegal Regular Searches recursively trough java sources for matching of specified list of regular
Expression expression patterns.
The pattern to search for can be configured in an external file specified in the
PATTERN_CONFIGURATION parameter.
There can be specified the priority of the message that is generated for each pattern.

Instantiation in loop This test checks if temporary objects are instantiated in a loop body.
This should be avoided if possible because instantiating and directly garbage-
collecting temporary objects for each loop iteration is a possibly expensive operation.

Internationalization This test checks for possible problems concerning internationalization.

© 2009 SAP AG - BP_Jlin_V30.doc page 40/57


Best Practice
Custom Code Management

Test What It does


One of them is usage of java.lang.String.toLowerCase() and
toUpperCase() methods.
The problem is that these methods use the default (current for this user) locale for
performing the conversion. This provides unexpected results in certain locales
(Turkish for instance), like lower case 'i' being converted to the turkish capital 'I' with a
dot.
This behavior results in severe problems on customer installations with non-English
locales.
To fix this, always use the respective methods that accept a specific locale as a
parameters –
toUpperCase(Locale locale) and toLowerCase(Locale locale) and specify
Locale.ENGLISH as locale.
This will ensure that all internal string conversions are performed in the English locale
and the results are always determinate. An alternative way to fix this is to use
com.sap.i18n.text.Utf16String.toUpper(string) method instead.
Another problem is char to byte and vice versa conversion without specifying the
encoding.
This means the runtime default encoding is used which can be different on different
platforms or in different locations.
This check also verifies if ResourceBundle.getBundle(String) which uses the
default runtime Locale is used, use one of the getBundle methods with Locale,
explicitly specifying the needed locale.
Example:
A client-server program converts String to byte[] using the default encoding on the
client side in Europe and sends it to the server located in China.
The server converts it back from byte[] to String using its default encoding which may
very well be different from the client, which will result in serious conversion errors.
To fix this, always specify hard coded references to one of the encodings guaranteed
to be supported on all Java platforms:
UTF-8, UTF-16, US-ASCII, ISO-8859-1, UTF-16BE, UTF-16LE

JDK 1.3 – 1.4 This test checks if code that compiles and runs under JDK 1.3 may cause problems
compatibility test under JDK 1.4.

JDK 1.4 – 1.5 This test checks the following incompatibilities between JDK 1.4 and 1.5 officially
Incompatibilities listed by Sun on
http://java.sun.com/j2se/1.5.0/compatibility.html#source: items 1, 4, 8, 9, 10, 14, 17,
22, 23.
It also checks the following incompatibilities:
ƒ java.math.BigDecimal.toString() implementation changed in JDK 1.5
ƒ the new class java.util.Queue can make existing on-demand imports
ambiguous (colliding with javax.jms.Queue)

Jumbled This tests checks if the incrementor statement(s) of a nested for loop are exactly the
Incrementer same as those of an outer for loop, indicating a possible copy-paste error.

© 2009 SAP AG - BP_Jlin_V30.doc page 41/57


Best Practice
Custom Code Management

Test What It does


This is the example of code which will trigger the error message:
for (int i = 0; i < 10; i++) {
for (int k = 0; k < 20; i++) {//possible copy paste error
System.out.println("Hello");
}
}

Loose Coupling Basically the test is searching for particular implementation classes and then
produces a message that it should be replaced with certain interface. It checks for
defining fields, arguments of methods and return types. The test does not check
definitions of local variables.
The list of implementation classes is configurable using the file
data/looseCoupling/looseCoupling.properties. With the following structure:
[fully qualified class name]=[fully qualified interface name],
Where class name is the name of the particular implementation which will be search
for and the interface name is the interface with which you should change the
implementation declaration.

Naming This test checks if package, class, interface, method, field, variable and argument
Conventions names comply with the naming conventions specified as regular expression
parameters.
The default parameters supplied check for compliance with the official Java code
conventions from Sun except for the fact that packages should start with
"com.(ts)sap" (see
http://java.sun.com/docs/codeconv/html/CodeConventions.doc8.html).
The test also checks if declared type names conflict with any java.lang.* types.
Apart from being confusing, clients of such a type will be forced to always use the
fully qualified name because the java.lang.* is always imported by default.

New Catch Block This test checks for handling of exceptions in catch blocks.
Test

One Statement Per This test checks if there is only one statement per line.
Line
If you declare several statements on one line, this may make stepping through the
code using a debugger difficult.

One Top-Level This test checks if you declare only one top-level class per java file.
Class Only
It is considered good style to have one top-level class per java file. Also, there may
be differences in how a compiler implementation treats non-public top-level classes
inside the same java file.
Solution: put further top-level classes in separate java files in the same package or
use inner classes.

Path Length Checks if the package root-relative path length of a Java class file exceeds
MAX_PATH_LENGTH.

Performance Checks if the SAP Performance Product Standard is fulfilled.


Product Standard
The pragmatic product standard Performance defines criteria that ensure good
performance and scalability of applications. This refers to both new solutions and

© 2009 SAP AG - BP_Jlin_V30.doc page 42/57


Best Practice
Custom Code Management

Test What It does


existing ones.

Product Standards Checks that are currently not assigned to a SAP Product Standard.
(Not Assigned)

Restricted The test can check if certain "forbidden" packages, classes, fields or methods are
Components used.

Return Array Test This test checks if methods which return arrays or java.util.Collection do not
return null. Instead, an empty array or collection should be returned.
This saves the client from checking for null. For collections, you can use the static
members java.util.Collections.EMPTY_LIST,
EMPTY_MAP and EMPTY_SET.

Security Product Checks if the SAP Security Product Standard is fulfilled.


Standard
The security standard is a product standard which defines a common baseline level
of security for all SAP applications. It addresses
ƒ Security vulnerabilities,
ƒ Security relevant legal requirements, and
ƒ TCO requirements which are security related.

Serialization This JLin test checks some of the oddities when implementing the empty
java.io.Serializable interface:

ƒ Check if all non-static, non-transient and non-primitive class-type fields of the


implementing class implement java.io.Serializable or provide a no-args
constructor
ƒ Check if super classes implement Serializable; if not, the first non-serializable
superclass must have a zero-args constructor
ƒ Check if static final long serialVersionUID is declared by all Serializable
classes
ƒ If private void writeObject(java.io.ObjectOutputStream out) is
implemented, check that private void
readObject(java.io.ObjectInputStream in) is implemented, too and vice
versa.
ƒ read/writeObject() methods and declaration of static final
ObjectStreamField[] serialPersistentFields are mutually exclusive
NOTE: If you have to extend a class that implements Serializable, but your subclass
is not serializable and you cannot change the superclass (this is the case for many
Swing classes), you should make this explicit by declaring:
private void writeObject(java.io.ObjectOutputStream out)
throws java.io.NotSerializableException {
throw new java.io.NotSerializableException(className);
}
private void readObject(java.io.ObjectInputStream in) throws
java.io.NotSerializableException {
throw new java.io.NotSerializableException(className);

© 2009 SAP AG - BP_Jlin_V30.doc page 43/57


Best Practice
Custom Code Management

Test What It does


}
A good introduction/tutorial for Serialization can be found on
http://www.onjava.com/pub/a/onjava/excerpt/JavaRMI_10 (chapter 10 of William
Grosso: Java RMI, O'Reilly, ISBN 1-56592-452-5).
Also see Joshua Bloch: Effective Java, Chapter 10, ISBN 0201310058.

Simplify Boolean This test searches for unnecessary if..then..else statements returning or
assigning a boolean literal and for unnecessary comparisons in boolean expressions.

Solution Checks if the SAP Solution Management Product Standard is fulfilled.


Management
Product Standard

Source Scanner Searches trough java sources for usages of one of the following java elements:

1. Package
2. Class
3. Field
4. Method
The elements to search for are specified into an external configuration file called
config.xml.

Static Collection This test checks if static collections are used. They can grow without bounds and
Test potentially cause memory leaks.

String Pitfalls This test checks for possible pitfalls when java.lang.Strings are used in the
java program.
One of the them is if you checks for equals Strings using‘==’ or ‘!=’ instead of
String.equals(Object) method. These operations are meaningful only if you
are trying to check 2 constants or if you first call String.intern() method to both
Strings.
Otherwise those operations will check only if both objects have the same address.
The test will not complain if you are comparing 2 String constants, but it does not
check if the string is interned. If you are comparing 2 interned strings you should
disable the check using defined pseudo-comment.
The second check concerns the usage of String.toString() method of declared
String objects. It does not produces an error if you call the toString() method on
any other object. Just checks if you are calling String.toString() method, which
is basically unnecessary.

Switch Test This test checks for frequent sources of error when using switch:
1. The switch statement has no default case
2. A case statement "falls through", i.e. has no break, return, continue or throw
statement
3. The default case is not the last case
4. The number of cases exceeds MAX_CASE_NUMBER
5. Label declaration inside switch statement –it is misleading, because of the similar

© 2009 SAP AG - BP_Jlin_V30.doc page 44/57


Best Practice
Custom Code Management

Test What It does

structure of label and case statements.

SWT Accessibility This test checks for the following accessibility rules which apply when developing
eclipse plugins using SWT:
1. Avoid direct instantiation of org.eclipse.swt.graphics.Font for
accessibility reasons. Use getters or constants in
org.eclipse.jface.resource.JFaceResources instead
2. Avoid direct instantiation of org.eclipse.swt.graphics.Color for
accessibility reasons. Use getters in
org.eclipse.jface.resource.JFaceColors instead
3. Avoid using non-accessible color IDs with Display.getSystemColor(id)
4. Avoid explicitly setting colors/fonts using
Control.setBackground(Color)/setForeground(Color)/setFont(F
ont)
5. The text argument of setText(String text) method invocations on
org.eclipse.swt.widgets.Label/Button/MenuItem and
org.eclipse.jface.Action should define a keyboard shortcut using the
mnemonic letter "&"

Unneeded Object This test searches for unneeded temporary object instantiation. In detail it checks
Creation unneeded Boolean instantiation and Boolean.valueOf(), String instantiation with
String literals and primitive wrapper objects during conversion to String.
Similarly, creating unnecessary primitive type wrapper objects using the primitive-
argument constructors of java.lang.Byte/Character/Integer/Long/Short
should be replaced by the corresponding static valueOf() method which improves
performance by using an object cache.

URL Test This test checks for usages of java.net.URL#openStream() method. If this
method is used on URL that refers to a JAR file (especially if the URL was created
using java.lang.ClassLoader#getResource(String)) the file handle to the
JAR file remains opened even if the InputStream that is returned is explicitly closed
(prior to JDK 1.4.2_08).
On the SAP J2EE engine, if you are using custom class loading mechanism, please
use java.lang.ClassLoader#getResourceAsStream(String) which is
overidden in all of the engine class loaders and closes the file handles properly.
For more information on the topic see
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5105410

Usability Product Checks if the SAP Usability Product Standard is fulfilled.


Standard
The term “usability” is defined as “adapting the software tool to people and their tasks
at hand”. The primary focus of usability is the end user (not the customer and not the
administrator) and his tasks. The software tool, i.e. business process step fulfills the
user's and the task's needs if the end user is able to complete his tasks efficiently
and effectively.

Wait only in This test checks if wait() invocations comply to the following rules:
synchronized loops
1. they should be inside a synchronized block or method

© 2009 SAP AG - BP_Jlin_V30.doc page 45/57


Best Practice
Custom Code Management

Test What It does

2. they should be inside a loop (while, for or do)

Table 3: Tests

2.3.3 Logging

Test What it does

Configuring Logging Restricted Logging API methods: The test can check if certain forbidden methods
are used.
The invocations of these methods have to be avoided, because their invocations in
the sources of the components will not have a result in the Log Configurator service
and in such case the administrators of the server can't see the real configuration.
All configurations have to be made in the log-configarion.xml.
Wrong severity settings affects log and trace file size, log clarity and system
performance. All categories should be set to severity INFO and all locations should
be set to severity ERROR.
Refer to the references to learn how to set up your logging configuration.

Logging and Tracing For each log call, there is a message including the log message (if it can be
Test detected statically).
For each category name used, there is a message including the category name (if it
can be detected statically).
There is an error message if a Log with a custom log formatter is instantiated
(because this is deprecated).
The total number of trace and log method calls is counted.

Logging Severities The Logging Severities Check generates warnings in each of the following cases:
Check
ƒ When a trace is written with severity WARNING
ƒ When a trace is written with severity ERROR and the writing statement is not
contained in a catch block nor immediately precedes the throwing of an
exception
ƒ When a trace is written with severity FATAL
ƒ When a log is written with severities DEBUG or PATH

Logging Standard Restricted write in standard outputs.


Outputs
The test can check if the fields System.err and System.out have been accessed.
All logs and traces should be written into the responsible locations and categories.
See the references to learn how to write your logs and traces.
For more detailed information about the Logging API, please refer to the links from
references.

© 2009 SAP AG - BP_Jlin_V30.doc page 46/57


Best Practice
Custom Code Management

Test What it does

Logs in ConsoleLog The test can check if an instance of ConsoleLog is created.


All logs and traces should be written into the responsible locations and categories.

Table 4: Logging

2.3.4 Security

Test What it does

Generic SQL The test searches for functions, which contain generic SQL-Statements. Such
Functions Statements are dangerous, because an attacker can use such functions for his own
purposes. For example he could use the function to read any entry of the database.
These errors are connected to SQL-Injection vulnerabilities. The test searches for
all generic SQL-Queries, which are used in an execute(…)-method, to query the
database. Currently there are no known false positive results of the test. False
negative results are not known either. The scope of the test is limited to one
method. If you like to have more information on the topic SQL-Injection, please
check the SAP NetWeaver Developer's Guide (Java) for detailed information.

Hard Coded The test searches for hard coded security credentials. Such credentials are
Security Credentials passwords and usernames. Hard coded credentials must be avoided, because it's
easy for an attacker to get them. Further more it’s not possible to change the
credentials after delivering the software to the customer. The credentials should be
stored as mentioned in the
SAP NetWeaver Developer’s Guide (Java). If it should be necessary to store
credentials in the code, please check with a security expert before. The test
determines for all defined functions, if they use hard coded usernames or
passwords and then indicates an error. There are currently no known false positives
and false negatives. The scope of the test is limited to one method.
SAP NetWeaver Developer's Guide:
Using hard-coded passwords is strictly prohibited! There are several reasons for
this as follows: Hard-coded passwords cannot be changed by customers,
maintenance tasks will become more difficult, and there exists no transparency. In
addition, services such as the SAP Optimization Service are not able to find hard-
coded passwords. Furthermore, hard-coded passwords are not stored in a way to
keep them confidential since the code (or the binary) is shipped to the customer and
thus the passwords can be retrieved.
In case a hard-coded password is recovered and published in the Internet, for
example, then security will be compromised in all customer installations.
Use a technology such as one-time passwords.
Use the Destination Service instead.
Apply a changeable password in a central function, such as transaction SM59.
Do not invent your own encryption algorithm.

Suspicious Suspicious functions are functions that may be dangerous, because they use an
Functions unchecked string parameter. Such uses of unchecked external data can lead to
Cross-Site Scripting (XSS) vulnerabilities or other security issues. It must be
determined from case to case, if the detected function is dangerous or not. The test
can be used to find some statements in the code, which are interesting for an

© 2009 SAP AG - BP_Jlin_V30.doc page 47/57


Best Practice
Custom Code Management

Test What it does


investigation. The test searches for all getParameter(…)-method invocations and
marks the variable on the left side of this method invocation as insecure. If such an
insecure variable is used as a parameter of a method, the function is considered
suspicious. The test could cause false negatives, because the search pattern is
defined not precisely enough to find all issues. False positives are also possible,
because the test can not determine automatically, if the found issue could lead to a
problem or not.
The scope of the test is limited to one method. If you want to have more information
about XSS, please check the SAP NetWeaver Developer's Guide (Java).

Table 5: Security

2.3.5 Metrics

Test What it does

Arguments per method This metric measures the number of arguments per method.
NOTE: constructors are excluded because they often necessarily have
many arguments.

Cyclomatic Complexity This metric measures the cyclomatic complexity of each method in a class.
Metric
A method without any "decision points" has a cyclomatic complexity of 1.
Each time a decision point is encountered within a method, its complexity
value is incremented by 1. This implementation considers if, for, while,
case, catch, throw statements as decision points.
NOTE: interfaces and local classes are not measured.

Global Counters This test counts the global number of classes, methods and lines of code
(LoC), comments and whitespace in the files parsed.
Comment lines are pure comment lines, i.e. no statement on this line;
whitespace lines are pure whitespace lines.
Thus the sum of code, comment and whitespace lines is the total number of
lines in the files parsed.
The lines of code can be used to normalize the number of messages
generated by other tests (e.g. number of messages/1000 LoC).

Inheritance Hierarchy Depth This metric measures the depth of the inheritance hierachy per
class/interface.

Max nesting level per This metric measures the maximum statement nesting level per method.
method

Methods per class This metric measures the number of methods per class/interface.

Statements per method This metric measures the number of statements per method.

Table 6: Metrics

© 2009 SAP AG - BP_Jlin_V30.doc page 48/57


Best Practice
Custom Code Management

2.3.6 EPTests

Test What it does

Candidates for Prepared This check finds SQL statements which are created instantly and executed
Statements in a loop. These are candidates for a prepared statement.
Often, an SQL statement is invoked with different parameters. For this
purpose JDBC offers the facility of prepared statements. Prepared
statements are SQL statements that contain a question mark for each
parameter. Upon creation the statement is precompiled by the DBMS and
on every execution of the statement the current parameters are inserted
and the action performed. Another advantage of prepared statements is the
ability to insert even those values that cannot be expressed in SQL (as
string), like BLOBS.

File access This rule detects repeated access to files from portal applications. File
access is only ignored from within static initializers and a portal component
initializer method.

Iteration over Map entries This check finds usage of Map.keySet().


A simple way to get all entries of a map is using the keySet method and get
for each entry in the set:
Iterator iter = map.keySet().iterator();
while (iter.hasNext()) {
Object key = iter.next();
Object value = map.get(key);
}
While this works perfectly well from the functional point of view, the
performance is less than acceptable. Consider that the lookup operation get
is called once for any element in the map. The following implementation
does not need a single lookup and should therefore be preferred in any
case:
Iterator iter = map.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry e = (Map.Entry) iter.next();
Object value = e.getValue();
}

Loop condition This check finds condition statements of loops with expensive calculations.
Following example shows a popular idiom how to implement a loop:
for (int i=0; i < list.size(); i++) {
...
}
The weak spot in this code snippet is that the constant expression is
evaluated repeatedly. Any part of the condition statement whose result
does not change during the loop execution should be evaluated before the
loop is entered and assigned to a local variable.

NullPointer Check Prefer check for NULL to catch of NullPointerException.


The creation and throwing of exceptions is an expensive operation in Java.

© 2009 SAP AG - BP_Jlin_V30.doc page 49/57


Best Practice
Custom Code Management

Test What it does


Therefore exceptions should not be provoked without good reason.
Some programmers try to circumvent explicit null-checks by catching the
corresponding runtime exception NullPointerException. The resulting
source code is expected to be faster because it lacks an if-statement. In
fact the cost of the exception is so huge that a single null value in 1.000.000
cases will be enough to eradicate the performance advantange of the
avoided if statements. So this trick will not save time in any case that can
be thought of and it will lead to noticable performance degradation when
null values occur more often. As a conclusion, NullPointerExceptions
should serve their original purpose: to signal programming errors and
nothing else.

Release of Resources Checks if a resource is always closed inside of a finally block.


Resources with limited availability should be released as soon as possible
and in a reliable way. This can be ensured by calling the release method
(e.g. close) of the resource from inside a finally block. This block has to be
declared even when there are no checked exceptions, i.e. no try clause.
A resource is identified by its classname which should match
java.io*(Stream|Reader|Writer).

String concatenation This check indicates expensive string concatenation in a loop.


The string concatenation operator + is a convenient way to combine a few
strings into one. It is fine for generating a single line of output or for
constructing the string representation of a small, fixed-size object.
Unfortunately the immutability has some significant side effects here:
For every concatenation a new string instance has to be created (creating
garbage objects).
All characters, not only those that are added, have to be copied to the new
string. This leads to quadratic complexity when concatenating in a loop.

Unnecessary creation of This check indicates unnecessary creations of String.


Strings
It is not necessary to create new string instances explicitly (new
String("text")), except for some very rare cases where equal strings are
considered different when they belong to different objects (the == operator
is used for comparison).

Unnecessary substrings This check tests if a call of method substring() create a string with one
character only. Use of method charAt() would be more appropriate here.

Usage of obsolete Checks for usage of Vector.elements(), Hashtable.elements(),


Collection and Hashtable.keys(). The functionality is duplicated by the Iterator
interface. Implementations should consider using Iterator in preference to
Enumeration.

Usage of Thread Checks for usage of class Thread.


Thread creation is one of the core responsibilities of the J2EE container
and the portal sitting on top. It is strongly interconnected with transaction
and context management. Therefore the creation of threads is not allowed
for applications.
An application only benefits from parallelization when the CPU would be

© 2009 SAP AG - BP_Jlin_V30.doc page 50/57


Best Practice
Custom Code Management

Test What it does


idle otherwise. Message Driven Beans are the technology of choice to
parallelize tasks.

Table 7: EPTests

2.3.7 J2EE

2.3.7.1 EAR

Test What it does

Application Model Builder Checks if the application.xml and optional application-j2ee-engine.xml


descriptors are present and valid according to their corresponding XML
schema or DTD.

Application Name Test Checks application name correctness.

References Test Checks correspondences of application deploy time and runtime


references.

Uniqueness Test Checks for the uniqueness of context-root's and security role-names in
application.xml

Table 8: EAR

2.3.7.2 EJB

Test What it does

Bean Injection Check This test checks if there are injection targets that are static or final in beans.

Bean Interfaces This test checks if all declared EJB interfaces and classes in ejb-jar.xml
extend/implement the correct javax.ejb.* interfaces.

Beans And Fields Modifiers This test checks the beans modifiers and the modifiers of beans' fields.
Check

Business Interfaces Check This test checks if the RemoteInterface extends the BusinessInterface,
containing only the business methods of the bean.

Classes Exposure Check This test checks whether a local business interface is exposed through a
remote interface.

CMP Field Checks Check if cmp field entries in ejb-jar.xml match their corresponding EJB
Classes:
For each CMP field declared there must be two public abstract methods in
its bean class:
public abstract void set(JavaType param)
public abstract JavaType get()

© 2009 SAP AG - BP_Jlin_V30.doc page 51/57


Best Practice
Custom Code Management

Test What it does

CMR Field Checks Check if cmr field entries in ejb-jar.xml match their corresponding EJB
Classes

CMR Many-to-Collection Check if CMR field entries in ejb-jar.xml have java.util.Set or


Checks java.util.Collection type if the relation ship was declared many:*

EJB Interceptors Check This test checks the interceptors in the EJB application.

EJB Model Builder Builds up the EJB model.

EJB Query Method Check Checks if declared EJB query methods exist and method names start with
'find' or 'ejbSelect'. Finder methods must be declared in the EJB home
and/or local home interfaces. EJB select methods must be declared in the
bean class.

Enumeration Value Test This test checks the values of the following elements of ejb-jar.xml which
are restricted to a certain enumeration of values, but this is only stated as a
comment in the DTD:
cmp-version: '1.x', '2.x'
cmr-field-type: 'java.util.Collection', 'java.util.Set'
ejb-ref-type: 'Entity', 'Session'
env-entry-type: 'java.lang.Boolean', 'java.lang.String',
'java.lang.Character', 'java.lang.Integer',
'java.lang.Double', 'java.lang.Byte',
'java.lang.Short', 'java.lang.Long', 'java.lang.Float'
method-intf: 'Remote', 'Home', 'LocalHome', 'Local',
'ServiceEndpoint'
multiplicity: 'One', 'Many'
persistence-type: 'Bean', 'Container'
res-auth: 'Application', 'Container'
res-sharing-scope: 'Shareable', 'Unshareable'
result-type-mapping: 'Remote', 'Local'
session-type: 'Stateful', 'Stateless'
transaction-type: 'Bean', 'Container'
trans-attribute: 'NotSupported', 'Supports', 'Required',
'RequiresNew', 'Mandatory', 'Never'

Interceptors Injection Check This test checks if there are injection targets that are static or final in
interceptors.

Interceptors Taker Tests This test takes all interceptors found in module and put them in a Set. It
allows the tests over interceptors to depend on it and if there are no
interceptors to not execute at all.

MDBs Parents Check This test checks if the parent classes of an MDB are themselves MDB
classes.

© 2009 SAP AG - BP_Jlin_V30.doc page 52/57


Best Practice
Custom Code Management

Test What it does

MDBs Taker Test This test takes all MDBs and put them in a Set. It allows the tests over
MDBs to depend on it and if there are no MDBs to not execute at all.

Sessions Taker Test This test takes all session beans and put them in a Set. It allows the tests
over session beans to depend on it and if there are no session beans to not
execute at all.

Transaction Attribute Check The transaction attribute is a declarative property that automatically
manages transactions for the component developer. By setting this
attribute, you eliminate the need to use explicit transaction controls in your
component.

Table 9: EJB

2.3.7.3 WEB

Test What it does

Implicit Constraints Test This web test checks for some XML constraints that are not explicitly stated
in the web.xml DTD:
ƒ Error-code must be a valid HTTP 1.1 error code (i.e. integer between
100 and 599)
ƒ Session-config, login-config and jsp-config elements must not occur
more than once
ƒ Error-code and exception-type must be unique within the web
application
ƒ Distributable elements should not occur more than once (warning only)
ƒ Form-login-page and form-error-page paths must start with a slash
ƒ Enumeration type values for the following elements are checked:
ƒ env-entry-type: 'java.lang.Boolean', 'java.lang.Byte',
'java.lang.Character', 'java.lang.String',
'java.lang.Short', 'java.lang.Integer',
'java.lang.Long', 'java.lang.Float',
'java.lang.Double'
ƒ res-auth: 'Application', 'Container'
ƒ res-sharing-scope: 'Shareable', 'Unshareable'
ƒ transport-guarantee: 'NONE', 'INTEGRAL', 'CONFIDENTIAL'
ƒ ejb-ref-type: 'Entity', 'Session'

JSF Application Test Tests whether current application is a JSF application.

Mapping Test This test checks the following restrictions for servlet-mapping, filter-mapping
and mime-mapping entries in web.xml:

ƒ Servlet-mapping: referenced servlet-name must exist and url-pattern


must be valid

© 2009 SAP AG - BP_Jlin_V30.doc page 53/57


Best Practice
Custom Code Management

Test What it does

ƒ Flter-mapping: referenced filter-name must exist and url-pattern must be


valid
ƒ mime-mapping: extension must no start with a dot ('.')
ƒ rules for valid url-patterns:
ƒ url-patterns must not contain any carriage return ('\r') or linefeed ('\n')
characters
ƒ url-patterns should be absolute (warning only), i.e. starting with '/' (path-
mapping) or start with "*." (extension-mapping) (warning only)
ƒ If the pattern starts with "*.", no additional '/' , '.', nor '*' is allowed.

Portal Application Descriptor This tests verifies that the following conditions apply for the elements of
Validator Test portalapp.xml descriptor:
1. There is a "Vendor" property inside every portal application.
2. The "Vendor" is set to "sap.com"
3. There is a "SecurityArea" inside every portal application.
4. The "SecurityArea" starts with prefix "NetWeaver." (it has a dot after the
word)
5. Every portal service and portal component inside the portal application
should have a "SafetyLevel" property.
6. The "SafetyLevel" is set to one of the 4 possible values: "no_safety" \
"low_safety" \ "medium_safety" \ "high_safety".

Security Role Test This test checks if references to security role names match an existing
security role name definition:
ƒ security-constraint • auth-constraint • role-name must be a defined
security role name for this web application or '*'
ƒ servlet • run-as • role-name must be a defined security role name for
this web application
ƒ servlet • security-role-ref • role-link must be a defined security role
name for this web application

Web Class Existence Test Checks the existence of declared servlet, filter, listener, resource and
environment types. Furthermore, it is checked whether the declared classes
implement the correct interfaces/ extend the correct superclasses and
provide no-args constructors.

Web File Existence Test This test checks for the existence of the following files referenced in the
web.xml descriptor: taglib-location, jsp-file. Also, jsp-files and taglib-
locations should start with a slash (warning only). Error-page location, form-
login-page and form-error-page must either exist as files or match one of
the defined url-patterns for servlets or filters (warning only).

Web Model Builder Builds up the web model from validated descriptors and/or annotations.

Table 10: WEB

© 2009 SAP AG - BP_Jlin_V30.doc page 54/57


Best Practice
Custom Code Management

3 Background Information and References

For further information on the JLin tool and its checks see:
ƒ SAP Java Test Tools

Detailed information on Test Management is contained in:


ƒ SAP Support Standard for Test Management

More about performance of SAP software solutions is available from:


ƒ https://service.sap.com/performance

© 2009 SAP AG - BP_Jlin_V30.doc page 55/57


Best Practice
Custom Code Management

Index of Figures
Figure 1: Elements of the Development Infrastructure........................................................................................5
Figure 2: Execution..............................................................................................................................................6
Figure 3: NWDS Menu ........................................................................................................................................8
Figure 4: JLin-tool menu......................................................................................................................................9
Figure 5: Create own variant .............................................................................................................................10
Figure 6: properties for variants.........................................................................................................................11
Figure 7: Tree of JLin-Tests ..............................................................................................................................12
Figure 8: Test description ..................................................................................................................................13
Figure 9: Edit Parameters and Priorities of a test..............................................................................................13
Figure 10: Edit Test Parameters .......................................................................................................................14
Figure 11: Editing a string array ........................................................................................................................15
Figure 12: Edit Message priority........................................................................................................................15
Figure 13: Open Run Dialog..............................................................................................................................16
Figure 14: Create, manage and run configurations...........................................................................................17
Figure 15: Run a JLin test .................................................................................................................................18
Figure 16: Executing tests from Package Explorer view...................................................................................18
Figure 17: Choose variant .................................................................................................................................19
Figure 18: Dependencies ..................................................................................................................................23
Figure 19: Result summary ...............................................................................................................................29
Figure 20: Results in the Tasks/Problems view ................................................................................................29
Figure 21: decorator icons in package explorer ................................................................................................29
Figure 22: Setting a filter ...................................................................................................................................30
Figure 23: Import source ...................................................................................................................................31
Figure 24: Specify XML file................................................................................................................................32

Index of Tables
Table 1: Icon Descriptions .................................................................................................................................14
Table 2: Eclipse compiler warnings...................................................................................................................36
Table 3: Tests ....................................................................................................................................................46
Table 4: Logging................................................................................................................................................47
Table 5: Security................................................................................................................................................48
Table 6: Metrics .................................................................................................................................................48
Table 7: EPTests ...............................................................................................................................................51
Table 8: EAR .....................................................................................................................................................51
Table 9: EJB ......................................................................................................................................................53
Table 10: WEB ..................................................................................................................................................54

© 2009 SAP AG - BP_Jlin_V30.doc page 56/57


Best Practice
Custom Code Management

© Copyright 2009 SAP AG. All Rights Reserved


No part of this publication may be reproduced or transmitted in any form or for any purpose without the express permission of SAP AG.
The information contained herein may be changed without prior notice.
Some software products marketed by SAP AG and its distributors contain proprietary software components of other software vendors.
Microsoft, Windows, Outlook, and PowerPoint are registered trademarks of Microsoft Corporation.
IBM, DB2, DB2 Universal Database, OS/2, Parallel Sysplex, MVS/ESA, AIX, S/390, AS/400, OS/390, OS/400, iSeries, pSeries, xSeries,
zSeries, z/OS, AFP, Intelligent Miner, WebSphere, Netfinity, Tivoli, and Informix are trademarks or registered trademarks of IBM
Corporation.
Oracle is a registered trademark of Oracle Corporation.
UNIX, X/Open, OSF/1, and Motif are registered trademarks of the Open Group.
Citrix, ICA, Program Neighborhood, MetaFrame, WinFrame, VideoFrame, and MultiWin are trademarks or registered trademarks of Citrix
Systems, Inc.
HTML, XML, XHTML and W3C are trademarks or registered trademarks of W3C®, World Wide Web Consortium, Massachusetts
Institute of Technology.
Java is a registered trademark of Sun Microsystems, Inc.
JavaScript is a registered trademark of Sun Microsystems, Inc., used under license for technology invented and implemented by
Netscape.
MaxDB is a trademark of MySQL AB, Sweden.
SAP, R/3, mySAP, mySAP.com, xApps, xApp, SAP NetWeaver, and other SAP products and services mentioned herein as well as their
respective logos are trademarks or registered trademarks of SAP AG in Germany and in several other countries all over the world. All
other product and service names mentioned are the trademarks of their respective companies. Data contained in this document serves
informational purposes only. National product specifications may vary.

The information in this document is proprietary to SAP. No part of this document may be reproduced, copied, or transmitted in any form
or for any purpose without the express prior written permission of SAP AG.
This document is a preliminary version and not subject to your license agreement or any other agreement with SAP. This document
contains only intended strategies, developments, and functionalities of the SAP® product and is not intended to be binding upon SAP to
any particular course of business, product strategy, and/or development. Please note that this document is subject to change and may
be changed by SAP at any time without notice.
SAP assumes no responsibility for errors or omissions in this document. SAP does not warrant the accuracy or completeness of the
information, text, graphics, links, or other items contained within this material. This document is provided without a warranty of any kind,
either express or implied, including but not limited to the implied warranties of merchantability, fitness for a particular purpose, or non-
infringement.
SAP shall have no liability for damages of any kind including without limitation direct, special, indirect, or consequential damages that
may result from the use of these materials. This limitation shall not apply in cases of intent or gross negligence.
The statutory liability for personal injury and defective products is not affected. SAP has no control over the information that you may
access through the use of hot links contained in these materials and does not endorse your use of third-party Web pages nor provide any
warranty whatsoever relating to third-party Web pages.

© 2009 SAP AG - BP_Jlin_V30.doc page 57/57

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy