Java EE schedulers

Java EE application servers have native scheduling support and, in most of the applications, there is no need to include external dependencies like the famous Quartz scheduler library.

The Java EE 6 Timer Service, available on Java EE 6 and 7 full profile, give us many options to define the scheduling interval and what’s happen if we stop and restart the application which contains our scheduler.

A Java EE scheduler can be:

  • persistent: the application server saves the scheduling events when the application is down  in order to not lose them
  • automatic: simple scheduler definition, most of the details are handled by the application server
  • programmatic: we have full control of all scheduler parameters.

To decide which is the best option, we should first answer to the following questions:

1. Is it allowed to miss some scheduling events?

If we stop or restart the application (for example during an update) the scheduler will be stopped and some scheduling events could be lost.

The scheduler can be configured to save the missed events and to execute them when the application will be up again. The application server uses an internal database (it is usually a Java DB like Derby) to store the missed events.

This is a persistent scheduler.

Note: the application server will generate all missed events at application (re)start. This burst of events is configurable in frequency and delay. See you application server documentation for the details.

We have also the option to not persist the scheduling events which will be lost if application is not running.

In the not persistent case, the scheduler life cycle is the same as the application: it is created at application startup and then destroyed at application shutdown.

On the contrary, a persistent scheduler survives to the application restarts; it is simply sleeping when the application is not running.

How to choose?

If the scheduled functionality is business critical and we cannot afford to miss an event, the persistent scheduler is the way to go.

In all other cases, the not persistent scheduler is lighter (no DB is used) and easier to manage (less hurdle when updating the application because there is no a burst of scheduling events at application restart; the scheduler is always created new at application start ).

2. Will the application run in a cluster?

In a cluster, more than one instance of our application is running (one instance per cluster node) and all instances have their own copy of our scheduler.

But we need to have just one scheduler running among all cluster nodes otherwise we will have multiple copies of the same event.

Every application server has its own way to handle the “multiple scheduler instances” problem (for example see [link 2] for WebSphere) but, in general, it is required that the scheduler should be persistent when we are using a cluster.

3. Should the scheduling interval be programmable at production?

Another important question to be answered: should we able to change the scheduling after the application has been deployed?

If the scheduling parameters (its frequency) are fixed, the automatic scheduler is the best solution because very simple to code: just one annotation (or few XML lines if you prefer the old way).

On the contrary, if the scheduler should be somehow configurable, the best solution is the programmatic scheduler which allow us to define all scheduler parameters during the application startup, reading them from a property file, a DB or any configuration solution we are using.

Remember:

  • the automatic scheduler schedule is defined at build time
  • the programmatic scheduler schedule is defined at application start time

Automatic scheduler

It’s very easy to define an automatic scheduler:

  1. Create a singleton EJB executed at startup
  2. Create a method which will be invoked at every scheduling event

Note: the complete code can be found in the article project [see link 3].

First step:

@Startup
@Singleton
public class MyScheduler

The @javax.ejb.Startup annotation asks the EJB container to create the EJB (and so our scheduler) at application startup.

The @javax.ejb.Singleton annotation forces the EJB container to create just one instance.

Important: the scheduler is used by the application server (the EJB container); it should be never instantiated by the rest of the application code.

Then we need the method which will be invoked at scheduling events:

@Schedule(/** scheduling parameters */)
public void doSomeThing() {..}

The method should be public and return void.

The @javax.ejb.Schedule annotation defines:

  • the scheduling interval, in cron format [see link 4]
  • the name of the scheduler (you could have many schedulers in the application)
  • a persistent boolean flag which defines if the scheduler is persistent or not

For example:

@Schedule(
    minute = "*/15",
    hour = "*",
    info = "15MinScheduler",
    persistent = false )

which defines a non persistent scheduler which runs every 15 minutes.

See AutomaticPersistentScheduler and AutomaticNonPersistentScheduler classes in the article project [link 3] for a complete example.

Note: there is also the @Schedules annotation [see link 1] which allows the define multiple @Schedule definitions.

It is useful when there are schedule requirements which cannot be expressed in a single cron definition.

Programmatic scheduler

The programmatic scheduler is more complex to build but it give us the complete freedom
to define the scheduler parameters.

We have more steps:

  1. Create a singleton EJB executed at startup
  2. Lookup the TimerService resource
  3. Create the scheduler at EJB initialization
  4. Create a @Timeout method

First step is the same as the automatic scheduler:

@Startup
@Singleton
public class MyScheduler

Then (second step) we need to lookup the application server timer service but the injection helps us:

@Resource
private TimerService timerService;

At application startup, the EJB container will inject a TimerService instance which allow us
to interact with the Timer service. For example, we can list (and even delete) all scheduler
defined for the application.

In our case, the Timer service will be used to create the new scheduler as follows (third step):

String minuteSchedule = "*/15";
String hourSchedule = "*";
ScheduleExpression schedule = new ScheduleExpression()
 .minute(minuteSchedule)
 .hour(hourSchedule);

The javax.ejb.ScheduleExpression defines the cron [see link 4] schedule like the @Schedule annotation.

The very important difference between @Schedule and ScheduleExpression is that the first one is fixed at build time: to change the schedule parameters (for example, from every 15min to every 30min) we need to change the class code and build and deploy again the application.

In the latter case (SchedulerExpression), the schedule parameters (in the example above
the variables minuteSchedule and hourSchedule ) can be defined and changed at
application startup, reading the minuteSchedule and hourSchedule from, for example,
a property file or a connected DBMS.

TimerConfig timerConfig = new TimerConfig();
timerConfig.setInfo("ProgrammaticPersistentScheduler");
timerConfig.setPersistent(true);

The javax.ejb.TimerConfig gives us the option to define the name of the scheduler (setInfo(String) ) and if it is persistent or not ( setPersistent(boolean) ) .

Using the ScheduleExpression and the TimerConfig instance, we can use the Timer service
to create the scheduler ( a calendar timer, to be more precise).

timerService.createCalendarTimer(schedule, timerConfig);

The createCalendarTime() method returns a javax.ejb.Timer instance which can be used to interrogate the timer like when the next future event will happen or even to destroy
the scheduler.

The last step is to define a method in the class which will be invoked at every scheduling event

@Timeout
public void doSomeThing() {..}

The method should be public and return void.

And we have our scheduler up and running.

Conclusions

Java EE standard give us many options to define a scheduler which runs our code in a periodical and repetitive way. There is no need for additional project dependencies.

 

Links

  1. Oracle Java EE6 Tutorial on the Timer Service API
  2. IBM WebSphere 8.x Creating timers using the EJB timer service for enterprise beans
  3. Article project on GitHub
  4. Cron on Wikipedia

 

 

Advertisements

Tutorial: Correct SLF4J logging usage and how to check it

SLF4J is a very popular logging facade but, like all libraries we use, there is a chance that we use it in a wrong or at least in a not optimal way.

In this tutorial we will list common logging errors and how we can detect them using FindBugs. We will also mention PMD and Sonar Squid checks when relevant.

We will use two external FindBugs plugins which add logging detectors to FindBugs.

The first one is a SLF4J only plugin by Kengo Toda which contains SLF4J detectors only.

The second plugin is the popular FB Contrib which contains, among many others, some logging detectors.

For how to use FindBugs plugins, please refer to the following posts:

Note: in all examples we will assume the following imports:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

1. Logger definition

Wrong way:

W1a. Logger log = LoggerFactory.getLogger(MyClass.class);
W1b. private Logger logger = LoggerFactory.getLogger(MyClass.class);
W1c. static Logger LOGGER = LoggerFactory.getLogger(AnotherClass.class);

Correct way:

C1a. private static final Logger LOGGER = LoggerFactory.getLogger(MyClass.class);
C1b. private final Logger logger = LoggerFactory.getLogger(getClass());

General rule: the logger should be final and private because there are no reasons to share it with other classes or to re-assign it.

On the contrary there is no general agreement if the logger should be static or not. SLF4J plugin favors non static version (C1b) while PMD (“LoggerIsNotStaticFinal” rule) and Sonar (squid rule S1312) prefer a static logger (C1a) so both options should be considered as valid.

Additional info:

Please note that

  • in the static version (C1a), the logger name is usually in uppercase characters as all constant fields. If not, PMD will report a “VariableNamingConventions” violation.
  • in both cases, the suggested name is “logger/LOGGER” and not “log/LOG” because some naming conventions avoid too short names (less than four characters). Moreover log is the verb, more suited for a method name.
  • the W1c is wrong because we are referring to a class (AnotherClass) which is not the class where the logger is defined. In the 99% of the cases, this is due to a copy & paste from one class to another.

Related FindBugs (SLF4J plugin) checks:

  • SLF4J_LOGGER_SHOULD_BE_PRIVATE
  • SLF4J_LOGGER_SHOULD_BE_NON_STATIC
  • SLF4J_LOGGER_SHOULD_BE_FINAL
  • SLF4J_ILLEGAL_PASSED_CLASS

 

2. Format string

Wrong way:

W2a. LOGGER.info("Obj=" + myObj);
W2b. LOGGER.info(String.format(“Obj=%s”, myObj));

Correct way:

C2. LOGGER.info("Obj={}",myObj);

General rule: the format string (the first argument) should be constant, without any string concatenation. Dynamic contents (the myObj value in the example) should be added using the placeholders (the ‘{}’ ).

Motivation is simple: we should delay logging message creation after the logger has established if the message should be logged or not, depending on the current logging level. If we use string concatenation, message is built any way, regardless the logging level which is a waste of CPU and memory resources.

Related FindBugs (SLF4J plugin) checks:

  • SLF4J_FORMAT_SHOULD_BE_CONST Format should be constant
  • SLF4J_SIGN_ONLY_FORMAT Format string should not contain placeholders only

Related FindBugs (FB Contrib plugin) checks:

  • LO_APPENDED_STRING_IN_FORMAT_STRING Method passes a concatenated string to SLF4J’s format string

 

3. Placeholder arguments

Wrong way:

W3a. LOGGER.info("Obj={}",myObj.getSomeBigField());
W3b. LOGGER.info("Obj={}",myObj.toString());
W3c. LOGGER.info("Obj={}",myObj, anotherObj);
W3d. LOGGER.info("Obj={} another={}",myObj);

Correct way:

C3a. LOGGER.info("Obj={}",myObj);
C3b. LOGGER.info("Obj={}",myObj.log());

General rule: the placeholder should be an object (C3a), not a method return value (W3a) in order to post-pone its evaluation after logging level analysis (see previous paragraph). In W3a example, the mehod getSomeBigField() will be always called, regardless the logging level. For the same reason, we should avoid W3b which is semantically equivalent to C3a but it always incurs in the toString() method invocation.

Solutions W3c and W3d are wrong because the number of placeholders in the format string does not match the number of placeholders arguments.

Solution C3b could be somehow misleading because it includes a method invocation but it could be useful whenever the myObj contains several fields (for example it is a big JPA entity) but we do not want to log all its contents.

For example, let’s consider the following class:

public class Person {
private String id;
private String name;
private String fullName;
private Date birthDate;
private Object address;
private Map<String, String> attributes;
private List phoneNumbers;

its toString() method will most probably include all fields. Using the solution C3a, all their values will be printed in the log file.

If you do not need all this data, it is useful to define a helper method like the following:

public String log() {
return String.format("Person: id=%s name=%s", this.id, this.name);
}

which prints relevant information only. This solution is also CPU and memory lighter than toString().

What is relevant ? It depends on the application and on the object type. For a JPA entity, I usually include in the log() method the ID field (in order to let me find the record in the DB if I need all columns data) and, may be, one or two important fields.

For no reason, passwords fields and/or sensitive info (phone numbers,…) should be logged. This is an additional reason to not log using toString().

Related FindBugs (SLF4J plugin) checks:

  • SLF4J_PLACE_HOLDER_MISMATCH

 

4. Debug messages

IMPORTANT: rule #4 (see 5 rules article) guide us to use a guarded debug logging

if (LOGGER.isDebugEnabled()) {
LOGGER.debug(“Obj={}”, myObj);
}

Using SLF4J, if the placeholder argument is an object reference (see solutions C3a/C3b), we can use avoid the if in order to keep the code cleaner.

So it is safe to use the following:

LOGGER.debug(“Obj={}”, myObj);

 

5. Exceptions

Proper exceptions logging is an important support for problems analysis but it is easy to neglect its usefulness.

Wrong way:

W5a. catch (SomeException ex) { LOGGER.error(ex);}..
W5b. catch (SomeException ex) { LOGGER.error("Error:" + ex.getMessage());}..

Correct way:

C5. catch (SomeException ex) { LOGGER.error("Read operation failed: id={}", idRecord, ex);}..`

General rules:

  1. Do not remove the stack trace information by using getMessage() (see W5b) and not the complete exception. The stack trace often includes the real cause of the problem which is easily another exception raised by the underlying code. Logging only the message will prevent us to discover the real cause of the problem.
  2. Do show significant (for the human which will analyze the log file) information in the logging message showing a text explaining what we wanted to perform while the exception was raised (not the exception kind or messages like “error”: we know already something bad happened). What we need to know is what we were doing and on which data.

The C5 example tells we were trying to read the record with a specific ID whose value has been written in the log with the message.

Please note that C5 use one placeholder in the format string but there are two additional arguments. This is not an error but a special pattern which is recognized by SLF4J as an exception logging case: the last argument (ex in the C5 example) is considered by SLF4J as a Throwable (exception) so it should be not included in the format string.

Related FindBugs (SLF4J plugin) checks:

  • SLF4J_MANUALLY_PROVIDED_MESSAGE: the message should not be based on Exception getMessage()

Tutorial: logging during tests

Logging is a popular solution to show what the software is doing while it is running.

But what happens to the logging when we are unit testing our application with jUnit/TestNG ?

During the automated tests execution, we are usually not interested to see the logging messages because our main interest is the test results.

It would be nice to be able to disable logging messages during standard automated tests.

On the contrary, there are some cases where logging messages can be useful at test time. A typical example is when we are coding missing tests for some legacy code we do not want to touch before having a good test coverage in place. In this case logging messages on the console can help us to understand the code and how it works.

So we can identify three use cases:

  1. Running mode, when the application is executed: the logging is enabled and configured as required by the application
  2. Test execution mode, when the automated tests are executed all together: the logging messages should be disabled

  3. Test creation mode, when we are creating new tests: the logging messages are useful but it would be nice to have them in the console

Let see an example based on Maven and SLF4J, the popular logging facade.

Complete project can be found here.

Typical SLF4J configuration in the project pom.xml is the following:

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
            <scope>runtime</scope>
        </dependency>

the slf4-api dependency is the main SLF4J library while the second one, slf4j-log4j12, is referencing one of the possible logging engines (LOG4J) that can work below the SLF4J.

This is the running mode configuration. In this example, the project resources will contain a LOG4J properties file which dictates what, how and where LOG4J should log.

The same situation happens when we are using a different logging engine like java.util.logging (JDK) and Logback. See Slf4J manual for more details.

In the Test execution mode we do not want logging so we can simply add the following scope test dependency

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-nop</artifactId>
            <version>${slf4j.version}</version>
            <scope>test</scope>
        </dependency>

The NOP Logger (slf4j-nop) simply discards all logging.

Important: the dependencies order in the pom.xml is significant. Put the slf4j-nop dependency just after the slf4-apidependency so it will be used during the tests even if there is another logging engine in the dependency.

When there are multiple logging engines dependencies in the pom.xml, SLF4J will show anyway a message like the following:

    SLF4J: Class path contains multiple SLF4J bindings.
    SLF4J: Found binding in [jar:file:.m2/repository/org/slf4j/slf4j-nop/1.7.12/slf4j-nop-1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class]
    SLF4J: Found binding in [jar:file:.m2/repository/org/slf4j/slf4j-log4j12/1.7.12/slf4j-log4j12-1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class]
    SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
    SLF4J: Actual binding is of type [org.slf4j.helpers.NOPLoggerFactory]

To summarize, a complete configuration example is the following:

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-nop</artifactId>
            <version>${slf4j.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
            <scope>runtime</scope>
        </dependency>

Again, the last dependency should be adjusted to match the desired logging engine.

As I mentioned before, logging can be useful when creating new tests. In this case (Test creation mode), we can temporarily replace the slf4j-nop with the slf4j-simple dependnecy which enables the SLF4J Simple logger.

The logging messages will now be shown in the console window during tests execution as System.err messages. No configuration file is needed.

By default, the Simple logger does not log DEBUG messages. Standard logging level is INFO.

You can customize the Simple logger behaviour using system variables documented here.

A smart way to define Simple logger configuration is using the [Surefire plugin configuration section] (http://maven.apache.org/surefire/maven-surefire-plugin/examples/system-properties.html):

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.18.1</version>
                <configuration>
                    <systemPropertyVariables>
                        <org.slf4j.simpleLogger.defaultLogLevel>DEBUG</org.slf4j.simpleLogger.defaultLogLevel>
                        <org.slf4j.simpleLogger.showDateTime>true</org.slf4j.simpleLogger.showDateTime>
                    </systemPropertyVariables>
                </configuration>
            </plugin>
        </plugins>
    </build>

In the systemPropertyVariables section we can create tags with the Simple logger variable name. In the above example, DEBUG and timestamp logging are enabled.

Tutorial: using FindBugs with Maven

FindBugs can be executed using Maven in two different modes: as stand-alone command or as part of the Maven site command.

These two modes require different settings in the project pom.xml but they are not incompatible to each other so we can use both of them.

info48
You can find complete Maven project here.

Stand-alone mode

Let’s start with the stand-alone mode which requires the following configuration in the pom.xml:

<build>
    <plugins>       
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>findbugs-maven-plugin</artifactId>
            <version>3.0.1</version>
        </plugin>
         ... other build plugins ....
    </plugins>
</build>

Please note that the FindBugs plugin definition is inside build – plugins section of the pom file.

Giving the following command:

mvn findbugs:findbugs

FindBugs is run against our project with the following log in the console output:

[INFO] --- findbugs-maven-plugin:3.0.1:findbugs (default-cli) @ CodeQualityGallery ---
[INFO] Fork Value is true
     [java] Warnings generated: 1
[INFO] Done FindBugs Analysis....

warning48
FindBugs analyze the compiled files (*.class). If the project is not compiled or just cleaned, FindBugs will report nothing, without error messages. So take care to build your project before running FindBugs.

A warnings number is reported on the console. Warnings are possible bugs found by the FindBugs detectors.

The warnings details are included in a report created in the file target/findbugsXml.xml which is in XML format and so not really readable.

A better way to examine the warnings is to use the FindBugs native GUI with the command:

mvn findbugs:gui

The FindBugs window shows the bugs on the left, the (read-only) code on the right and the bug explanation below.

FindBugs GUI

You can filter bugs for bug rank from the most critical (“scariest”) to trivial and even, saving project status, comparing project evolution (which means how may bugs has been eliminated/introduced after previous FindBugs check).

warning48All main IDEs (Eclipse, NetBeans, IntelliJ) FindBugs plugins show similar views and they can also let you modify the code so I don’t suggest to use FindBugs native GUI unless you have to create exclusion files (see below) which is easier with the native GUI: select a bug, filter it out and export bug filters.

 

Site mode

Maven site command is used to generate a project “site”, which is a collection of information on the project nicely reported in HTML pages. You can configure which information is included in the site report and, of course, you can add FindBugs analysis results.

Maven site requires a “reporting section” in the pom file.

<reporting>
    <plugins>       
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>findbugs-maven-plugin</artifactId>
            <version>3.0.1</version>
        </plugin>
         ... other site plugins ....
    </plugins>
</reporting>

Giving the following command (note: clean and install options are in to assure that project is compiled and all tests run):

mvn clean install site

on the console output we will see the following:

.....
[INFO] --- maven-site-plugin:3.3:site (default-site) @ CodeQualityGallery ---
[INFO] configuring report plugin org.apache.maven.plugins:maven-jxr-plugin:2.5
[INFO] configuring report plugin org.apache.maven.plugins:maven-project-info-reports-plugin:2.8
[INFO] configuring report plugin org.codehaus.mojo:findbugs-maven-plugin:3.0.1
[INFO] Fork Value is true
     [java] Warnings generated: 2
[INFO] Done FindBugs Analysis....
[INFO] configuring report plugin org.apache.maven.plugins:maven-pmd-plugin:3.4
[WARNING] No project URL defined - decoration links will not be relativized!
[INFO] Rendering site with org.apache.maven.skins:maven-default-skin:jar:1.0 skin.
[INFO] Skipped "Source Xref" report, file "xref/index.html" already exists for the English version.
[INFO] Generating "Source Xref" report    --- maven-jxr-plugin:2.5
[INFO] Generating "Dependency Convergence" report    --- maven-project-info-reports-plugin:2.8
[INFO] Generating "Dependency Information" report    --- maven-project-info-reports-plugin:2.8
[INFO] Generating "About" report    --- maven-project-info-reports-plugin:2.8
[INFO] Generating "Plugin Management" report    --- maven-project-info-reports-plugin:2.8
[INFO] Generating "Project Plugins" report    --- maven-project-info-reports-plugin:2.8
[INFO] Generating "Project Team" report    --- maven-project-info-reports-plugin:2.8
[INFO] Generating "Project Summary" report    --- maven-project-info-reports-plugin:2.8
[INFO] Generating "FindBugs" report    --- findbugs-maven-plugin:3.0.1
[INFO] Generating "PMD" report    --- maven-pmd-plugin:3.4
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
.....

The “site” is created in the target/site dir. Opening the file target/site/index.html with the browser, we will see something like the following:

2015-06-08bIn the Project Reports section you will find the FindBugs report like the following:

2015-06-08c   The report is interesting because it give us the complete picture of our project in the summary section but also the list of the files which have FindBugs detected issues with all details including the priority (i.e. how dangerous could be the problem).

Configuration options

Regardless the used mode, the FindBugs plugin can be configured to modify and tune its behaviour. All below configurations should be placed in the configuration section of the plugin:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>findbugs-maven-plugin</artifactId>
    <version>3.0.1</version>
    <configuration>
        .....put here
    </configuration>
</plugin>

warning48
Configurations in the build and reporting sections are independent so we can have two different settings in the two modes, stand-alone and site.

Best practice is to use a light and fast configuration on the standalone mode, in order to run quick checks during development and an high effort, production quality configuration for the site mode.

Let’s examine the most important configuration options:

DEBUG: With <debug>true</debug> option, FindBugs will show what is doing during analysis. Useful to fine tune or checks the settings.

EFFORT: with  <effort>Max</effort> we can increase the time FindBugs is allowed to use to analyze the code. More effort means more accurate analysis but, of course, FindBugs run slower.

EXTERNAL PLUGINS: FindBugs can be extended with additional detectors. See my post on the topic. The  <pluginList>plugin1[, plugin2…]</pluginList> configuration option list the plugins to be used. See the sample project for a real example.

EXCLUSIONS: If you need to disable a detector or to disable the analysis on same classes, an exclude list can be specified with the <excludeFilterFile> path_to_exclude_file </excludeFilterFile> option. File syntax is documented here. An easy way to create this file is by using the FindBugs GUI which has an export filter function. See the sample project for a real example.

 

Tutorial: Java abstract classes testing

In Java, abstract classes are used to define the interface of the class, with a list of (abstract) methods to be implemented by the extending class; basically what it is also possible to have with the “real” interfaces, the one defined with the interface instruction.

One significant difference between abstract classes and interfaces is that abstract classes can also have fields and non abstract methods which contain logic.

Abstract classes with code (in non abstract methods) are common in some design patterns implementations and in class hierarchy based frameworks. This is a typical solution to share code inside a class family.

Of course this code should be tested but abstract classes cannot be instantiated.

In this tutorial, we will analyze several cases and all possible alternative solutions to test abstract classes with non abstract methods. Let’s start with the libraries we will use on our tests (all Java 6 source level):

Few important remarks:

  1. Some solutions are based on Mockito version 1.10.12 or above but these versions are not compatible with the latest PowerMock version (1.6.1, see here).
    So in the project we will use two different libraries sets:

    1. Classic: jUnit 4.12, Mockito 1.10.8, PowerMock 1.6.1
    2. Latest: jUnit 4.12, Mockito 1.10.19 (no PowerMock)
  2. All examples are based on the “classic” combination except few ones marked with a special comment. In the project pom.xml, both dependencies sets are defined but one is commented out. Please note that, due to the combinations differences, some tests cannot be compiled in all combinations.
  3. Complete project can be found at https://github.com/gualtierotesta/test-solutions
  4. The examples are not real world code. The code has been kept at the minimum in order to better show the adopted testing strategy.
  5. A basic knowledge about Java unit testing and jUnit framework is needed for a more complete understanding of the examples. Mockito and PowerMock knowledge is not required.
  6. Have also a look at the Test Glossary for the meaning of several test terms used in this post.

CASE 1: independent method

This is the simplest case: the abstract class contains, in addition to abstract methods, a public non abstract method (named “methodToBeTested” in our examples) with no internal dependencies: it does not call any other method in its class.

public abstract class AbstractCase1 {
    public abstract int myAbstractMethod();
    public String methodToBeTested() {
        return "CASE-1";
    }
}

We want to test the logic of the method “methodToBeTested()”. We have three possible testing solutions:

Solution 1.A Using a concrete class

We create a concrete class which extends the abstract class and test the method from this class.

Our test class body:

     private class ConcreteCase1 extends AbstractCase1 {
        @Override
        public int myAbstractMethod() {
            return 0;  //Dummy implementation
        }
    }

    @Test
    public void testUsingConcreteClass() {
        // given
        ConcreteCase1 sut = new ConcreteCase1();
        // when
        String result = sut.methodToBeTested();
        // then
        Assert.assertEquals("CASE-1", result);
    }

Explanation:

  • Line 1: we define a concrete implementation of the abstract class where all abstract methods have a dummy implementation; they are not used so we don’t care.
  • Line 11: we create an instance named “sut” (system under test) of the concrete class. Through this instance we have free access to the method we want to test

The only drawback of this solution is the need to create the concrete class and created a dummy implementation for all abstract methods.

The given, when and then comments are used to separated different test phases: preparation, execution and results analysis. See also http://martinfowler.com/bliki/GivenWhenThen.html

Solution 1.B Using a Mockito spy (Mockito 1.10.12+ required)

We can use Mockito to create a spy instance of the abstract class. A spy is a class instance with standard behavior but that can be controlled by Mockito; for example we can ask Mockito to change the normal method return value, bypassing the return value calculated by the method body. See also the Testing Glossary.

In our case, we use a Mockito spy only because it let us create an abstract class instance, which is normally not possible. This is not a typical Mockito spy use case.

    @Test
    public void testUsingMockitoSpy() {
        // given
        AbstractCase1 sut = Mockito.spy(AbstractCase1.class);
        // when
        String result = sut.methodToBeTested();
        // then
        Assert.assertEquals("CASE-1", result);
    }

Explanation:

  • line 4: create the spy instance using Mockito.spy(class) method.
  • line 6: invoke the method to be tested

The main drawback of this solution is that Mockito.spy() will invoke the abstract class constructor during spy instance creation. In some cases the constructor uses external dependencies which can be an obstacle to our unit test executions. These kind of dependencies are usually called “test impediments”.

Solution 1.C Using Mockito mock

If you cannot use latest Mockito version or the abstract class constructor contains some test impediments, we can use Mockito to create a mock.

In general mocking is used to “empty” a class from its logic: a mocked instance does not have code insides the methods. In our case, we create a mock and then ask Mockito to restore the code inside the method we want to test.

This is not a very clean solution but it works.

    @Test
    public void testUsingMockitoMock() {
        // given
        AbstractCase1 sut = Mockito.mock(AbstractCase1.class);
        Mockito.doCallRealMethod().when(sut).methodToBeTested();
        // when
        String result = sut.methodToBeTested();
        // then
        Assert.assertEquals(&quot;CASE-1&quot;, result);
    }

Explanation:

  • line 4: create the mocked instance using Mockito.mock(class) method.
  • line 5: we ask Mockito to use real (=original) code when method is invoked

CASE 2: independent method with test impediment

In this second use case, the method we want to test calls a private method which contains a test impediment. We cannot simply execute the method to be tested because first we need to disable the test impediment method.

  public abstract class AbstractCase2 {

    public abstract int myAbstractMethod();

    public String methodToBeTested() {
        return prefix() + "2";
    }

    // Test impediment
    private String prefix() {
        return "CASE-";
    }
}

In our example, the method to be tested calls the private method “prefix()”. Note: the method body in the example is NOT a test impediment as it just returns a string. In the real world, the method performs some time and/or resource consuming tasks which should be avoided in our unit tests.
We want to “remove” prefix() standard behavior but to do this we cannot create a concrete class because private methods cannot be overridden. We cannot even use Mockito because it cannot control private (and, by the way, also static ) methods so we will use its stronger companion: PoweMock.

Solution 2.A Using PowerMock
The test class:

@RunWith(PowerMockRunner.class)
@PrepareForTest(AbstractCase2.class)
public class AbstractCase2Test {

    @Test
    public void testWithPowerMock() throws Exception {
        // given
        AbstractCase2 sut = PowerMockito.mock(AbstractCase2.class);
        PowerMockito.doCallRealMethod().when(sut).methodToBeTested();
        PowerMockito.doReturn("TESTCASE-").when(sut, "prefix");
        // when
        String result = sut.methodToBeTested();
        // then
        Assert.assertEquals("TESTCASE-2", result);
    }
}

Explanation:

  • line 1: the @RunWith annotation defines PowerMock as the runner for the test
  • line 2: the @PrepareForTest(class) annotation asks PowerMock to prepare the class for later processing
  • line 8: we create a mock using PowerMockito.mock() which, in turns, call the Mockito mock() method
  • line 9: as we did for the first use case, we ask PowerMock to re-enable the body of the method to be tested
  • line 10: here it is the key element of this test: we ask PowerMock to stub the private method return value so we can test methodToBeTested() without test impediments. Mockito alone cannot do this stub. Please note that the name of the private method, prefix, is passed to PowerMock as string because it is not accessible from outside. PowerMock will use reflection to find it.

CASE 3: method which access instance fields
Abstract classes can have an internal state implemented with class fields. The value of the fields can be significant for the test so we need a way to control them in order to define the initial test context (the “test fixture”).
If the field is public (uh, not very nice OO solution) or protected, it can be freely accessed (and modified) from our test class. But if it is private, we have few options to control it.
Let’s start with the example class:

  public abstract class AbstractCase3 {

    protected boolean type = false;
    private int count;

    public abstract int myAbstractMethod();

    public String methodToBeTested() {
        String res;
        count += 1;
        if (count > 10) {
            res = "Too many times";
        } else {
            if (type) {
                res = "Type is true";
            } else {
                res = "Type is false";
            }
        }
        return res;
    }
}

Two class fields, type and count, control the methodToBeTested() behavior. Note: this is just an example so forgive the meaningless logic.

Solution 3.A Using Mockito mock
This solution is identical to solution 1.C: we create a mock and then later we ask Mockito to re-enable the method body.

    @Test
    public void testTrueTypeWithCountLessThen10() {
        // given
        AbstractCase3 sut = Mockito.mock(AbstractCase3.class);
        Mockito.doCallRealMethod().when(sut).methodToBeTested();
        sut.type = true;
        // when
        String result = sut.methodToBeTested();
        // then
        Assert.assertEquals("Type is true", result);
    } 

Explanation:

  • line 4: create the mocked instance using Mockito.mock(class) method.
  • line 5: we ask Mockito to use real (=original) code when method is invoked
  • line 6: we fix the type field value to be true so we can test the method in this specific condition

As shown, we cannot control the count field value with this kind of solution.

Solution 3.B Using Mockito mock and a setter
Like the solution 3.A but we add a count field setter to the abstract class (not to the test class !) so we can control its value from the test class.

In the abstract class code we add the following lines:

    // Only for test
    void setCount(int pAmount) {
        this.count = pAmount;
    }

This solution is identical to solution 1.C: we create a mock and then later we ask Mockito to re-enable the method body.

    @Test
    public void testCountGreaterThen10WithSetter() {
        // given
        AbstractCase3 sut = Mockito.mock(AbstractCase3.class);
        Mockito.doCallRealMethod().when(sut).methodToBeTested();
        Mockito.doCallRealMethod().when(sut).setCount(Mockito.anyInt());
        sut.setCount(15);
        // when
        String result = sut.methodToBeTested();
        // then
        Assert.assertEquals("Too many times", result);
    } 

Explanation:

  • line 4: create the mocked instance using Mockito.mock(class) method.
  • line 5 and 6: we ask Mockito to use real (=original) code when method is invoked and also for the setter. Note the Mockito.anyInt() call which defines for which value (all, in this specific case) the real method body should be used
  • line 7: we call the count setter with a value, 15, above the condition defined inside the method (10) so we can test this code path

Of course we could also change type field value like we did in the previous solution.

Solution 3.C Using PowerMockito
If we cannot add the setter, for example because abstract class source code cannot be touched, we can use PowerMock to change class fields.

   
    @Test
    public void testWithPowerMock() {
        // given
        AbstractCase3 sut = PowerMockito.mock(AbstractCase3.class);
        PowerMockito.doCallRealMethod().when(sut).methodToBeTested();
        Whitebox.setInternalState(sut, "count", 15);
        // when
        String result = sut.methodToBeTested();
        // then
        Assert.assertEquals("Too many times", result);
    }

Explanation:

  • line 6: PowerMock Whitebox class uses reflection to control internal class contents. In our case we change to 15 the value of the count field (second argument, which should be noted it is a string).

Using Whitebox is not very common and it should be considered only for very untestable code only.

CASE 4: method which call abstract methods
This is the typical case, for example, of the Template Method design pattern (http://en.wikipedia.org/wiki/Template_method_pattern) but also other design patterns and frameworks use this solution. The non abstract method defines the global flow while the abstract method can be implemented in different ways to customize the behavior.

   public abstract class AbstractCase4 {

    public abstract int myAbstractMethod();

    public String methodToBeTested() {
        int val = myAbstractMethod();
        return "CASE-" + val;
    }
}

At line 6, the abstract method is invoked.

To test this code, we have three different solutions: extending the abstract class, using Mockito to create a mock or a spy.

Solution 4.A Using a concrete class
We can extend the abstract class, giving a convenient (for testing purposes) behavior to the abstract method:

   
    private class ConcreteCase4 extends AbstractCase4 {
        @Override
        public int myAbstractMethod() {
            return 4;  //Dummy implementation
        }
    }

    @Test
    public void testUsingConcreteClass() {
        // given
        AbstractCase4Test.ConcreteCase4 sut = new AbstractCase4Test.ConcreteCase4();
        // when
        String result = sut.methodToBeTested();
        // then
        Assert.assertEquals("CASE-4", result);
    }

Explanation:

  • line 1: ConcreteClass4 extends the AbstractClass4Test and gives a convenient implementation of the abstract methods.

Solution 4.B Using a mock with Mockito
We create a mock and we stub the abstract method:

    @Test
    public void testUsingMockitoMock() {
        // given
        AbstractCase4 sut = Mockito.mock(AbstractCase4.class);
        Mockito.doCallRealMethod().when(sut).methodToBeTested();
        Mockito.doReturn(4).when(sut).myAbstractMethod();
        // when
        String result = sut.methodToBeTested();
        // then
        Assert.assertEquals("CASE-4", result);
    }

Explanation:

  • line 6: the abstract method is stubbed with the return value we prefer for the test. Please note that, thanks to Mockito, we are stubbing a method which does not have any implementation (because it is abstract).

Solution 4.C Using a spy with Mockito (Mockito 1.10.12+ required)
Very similar to the previous use case:

   
  @Test
  public void testUsingMockitoSpy() {
        // given
        AbstractCase4 sut = Mockito.spy(AbstractCase4.class);
        Mockito.doReturn(4).when(sut).myAbstractMethod();
        // when
        String result = sut.methodToBeTested();
        // then
        Assert.assertEquals("CASE-4", result);
}

Explanation:

  • line 5: the abstract method is stubbed with the return value we prefer for the test. Please note that, thanks to Mockito, we are stubbing a method which does not have any implementation (because it is abstract).

CONCLUSIONS

Abstract classes code can present a not so short list of use cases. Each of them can be tested using different techniques and different test support libraries.

In this tutorial we went through many examples which hopefully cover many real worlds cases. If not, just let me know so I can extend this post.

 

Tutorial: how to create a JUnit test method template in NetBeans

NetBeans has a very nice feature: code templates.

Let me show how I use it to add a new JUnit test method in the test classes.

Go to Tools → Options → Editor → Code Templates and add the following template:

Abbreviation: te (this is only my proposal)

Expanded text:

@${baseType type="org.junit.Test" default="Test" editable="false"}
public void ${cursor}() {
    // given

    // when

    // then

}

2014-03-05_pic01Then go to a test class, type “te” (our template abbreviation) and press the TAB key.

See what’s happen:

2014-03-05_pic022014-03-05_pic03

First, the org.junit.Test include has been added (if not already in). This is thanks to the ${baseType} instruction we added in the template.

Second, the prompt is waiting for you for the method name. See ${cursor} instruction in the template.

Just write the name and we have complete test method template in our class.

2014-03-05_pic04

Of course, the template can be adjusted to your needs and habits.

Benefits:

  • we code faster
  • we have more uniform code style

NetBeans code template syntax is (partially) documented here.

Tutorial: using Lombok to reduce boilerplate code in Java

Lombok (http://projectlombok.org) is a very useful Java annotation library which help us to:

  • reduce boilerplate code
  • code faster
  • avoid stupid errors like forgetting the getter and setter for a new added field.

Lombok can create getter, setters, toString, constructor, equals and hashCode methods automatically. You just need to write the class and add the fields.

Lombok provides several annotations (see http://projectlombok.org/features/index.html for the complete list) but, in my projects, I usually use few of them and, in this tutorial I will show which and why.

To better show Lombok benefits, let’s start with a very simple (Maven based) project. You can find complete project source code here.

We should first define Lombok Maven dependency in the pom.xml file:

 <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.12.4</version>
    <scope>provided</scope>
</dependency>

Important: scope should be provided because we do not want Lombok jar file to be included in our build file.

Let’s now add to a project a very basic class without using any Lombok annotations.


public class WithoutLombokAnnotations {
    private boolean flag;
    private final int number;
    private final String text;
    private List<String> strList;

    public WithoutLombokAnnotations(int number, String text) {
        this.number = number;
        this.text = text;
    }

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public List<String> getStrList() {
        if (strList == null) {
            strList = new ArrayList<>(128);
        }
        return Collections.unmodifiableList(strList);
    }

    public void setStrList(List<String> strList) {
        this.strList = strList;
    }

    public int getNumber() {
        return number;
    }

    public String getText() {
        return text;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 11 * hash + this.number;
        hash = 11 * hash + Objects.hashCode(this.text);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final WithoutLombokAnnotations other = (WithoutLombokAnnotations) obj;
        if (this.number != other.number) {
            return false;
        }
        if (!Objects.equals(this.text, other.text)) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "WithoutLombokAnnotations{" + "flag=" + flag + ", number=" + number + ",
            text=" + text + '}';
    }
}

Comments on the above code:

  • The class has four fields, two of them are final so we need a constructor.
  • The flag field is a boolean so the getter is named isFlag() and not getFlag()
  • The strList getter method initialize the list if necessary
  • The strList is not included in the toString method
  • Equals and hashCode are calculated on number and text fields only.

A lot of boilerplate code for a very simple class.

Let’s reduce it with the help of Lombok annotations.

GETTER and SETTER

First step: the getters and setters (http://projectlombok.org/features/GetterSetter.html). In our example, all of them are very simple and standard except the strList getter. We can use Lombok’s @Getter and @Setter annotations to remove all standard getters and all setters from our code and have Lombok to generate them during compilation.

Our class code becames:

@lombok.Getter
@lombok.Setter
public class GettersAndSetters {
    private boolean flag;
    private final int number;
    private final String text;
    private List<String> strList;

    public GettersAndSetters(int number, String text) {
        this.number = number;
        this.text = text;
    }

    public List<String> getStrList() {
        if (strList == null) {
            strList = new ArrayList<>(128);
        }
        return Collections.unmodifiableList(strList);
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 11 * hash + this.number;
        hash = 11 * hash + Objects.hashCode(this.text);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final GettersAndSetters other = (GettersAndSetters) obj;
        if (this.number != other.number) {
            return false;
        }
        if (!Objects.equals(this.text, other.text)) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "WithoutLombokAnnotations{" + "flag=" + flag + ", number=" + number + ",
            text=" + text + '}';
    }
}

Great. Same functionality and 18 lines of code removed. We left in the code the strList getter because it has non standard functionality.

By using Lombok’s @Getter and @Setter annotation at class level we ask Lombok to generate getter and setter for all non-static fields. Of course final fields will not have setters.

@Getter and @Setter annotations can be placed at class level (like in the example) and at field level.

I usually prefer to use Lombok annotations at class level for two reasons: to not forget to add proper annotations when I add new fields in the class and to avoid to clutter class code with too many annotations (at fields level; see for example when you are using Lombok in JPA entity classes).

 

CONSTRUCTORS

Second step: the constructor (http://projectlombok.org/features/Constructor.html). By adding the @lombok.RequiredArgsConstructor annotation at class level, we can remove the 4 lines of the constructor.

Lombok has three different annotations for the constructors:

  • @RequiredArgsConstructor, the one we used in the example, generates a constructor for all final fields, with parameter order same as field order
  • @NoArgsConstructor creates an empty constructor.
  • @AllArgsConstructor creates a constructor for all fields

 

HASHCODE and EQUALS

Third step: the hashCode and equals methods (http://projectlombok.org/features/EqualsAndHashCode.html). In the example we have created these methods using the number and text fields.

By adding the @lombok.EqualsAndHashCode(of = {“number”, “text”}) annotation we can remove Equals and HashCode methods, going down by other 26 lines of code. And Lombok also generates the canEqual method. See here (http://www.artima.com/lejava/articles/equality.html) for the reasons.

Important: never use @lombok.EqualsAndHashCode without specifying the fields. Always use the of parameter (or the opposite exclude parameter). Without parameters, @lombok.EqualsAndHashCode will use all fields, possibly creating heavy equals and hashCode methods.

 

TOSTRING

Last step is to use @lombok.ToString (http://projectlombok.org/features/ToString.html) to implement the toString method. While having a toString method is highly suggested (for ex. for debugging and analysis purposes), my usual approach is to avoid collections and arrays fields in the toString method to avoid cluttering logs and messages windows with too long text lines.

After all our changes, the original class is now:

@lombok.Getter
@lombok.Setter
@lombok.RequiredArgsConstructor
@lombok.EqualsAndHashCode(of = {"number", "text"})
@lombok.ToString(exclude = "strList")
public class EveryThing {
    private boolean flag;
    private final int number;
    private final String text;
    private List<String> strList;

    public List<String> getStrList() {
        if (strList == null) {
            strList = new ArrayList<>(128);
        }
        return Collections.unmodifiableList(strList);
    }
}

Very short and with just the relevant code shown: the fields and the custom getter. No boilerplate code. Exactly what we were looking for.

LOGGING

Another quite useful Lombok annotation is related to logging (http://projectlombok.org/features/Log.html): Lombok can create a Logger field, named log, in our class. There are six variations of the annotation depending on the logging framework (java, apache, log4j, slf4j,,,).

The logging annotation does not reduce the amount of code in our class (one line for the annotation vs. one line for the manual logger definition) but it can help us to guarantee that we are using the same logging framework among all project classes. In some projects with large teams, I’ve found different logging frameworks used simply because different programmers were using IDE auto-complete functions in a different way.

Having something like

@Slf4J
public class ….

help us to use the same logger on all the class files.

@DATA

The @lombok.Data annotation (http://projectlombok.org/features/Data.html) is a short version for @Getter @Setter @EqualsAndHashCode, @ToString and @RequiredArgsConstructor.

At first glance it looks very convenient (one annotation instead of five) but, unfortunately, we cannot specify the fields for @EqualsAndHashCode and @ToString so it is not a good idea to use the @Data annotation unless the class is really a very simple POJO, without complex fields.

Moreover @Data does not generated automatically a no args constructor, required by JavaBeans and XML conversions so a @NoArgsConstructor annotation is also needed.

SUGGESTIONS

Lombok is very useful to reduce boilerplate code but it is important to keep in mind what Lombok is doing on our code to avoid useless and heavy generated code.

My personal suggestions:

  1. Always specify the fields you want in @EqualsAndHashCode or, in another words, never use the default @EqualsAndHashCode behaviour (all fields). Very important if the class is a JPA entity, where generated ID field should not be used for equality.
  2. Always exclude heavy fields (collections, arrays) in @EqualsAndHashCode and @ToString unless it is really necessary.
  3. Use @NoArgsConstructor when an empty constructor is needed (like for XML conversions and in JavaBeans)
  4. Never use Lombok @Data. As mentioned before, with the @Data annotation we cannot specify the fields for @EqualsAndHashCode and @ToString (see previous suggestions).
  5. On JPA entities:
    @EqualsAndHashCode: exclude generated @Id fields (persistence equality constraint: a generated ID field is not always defined during entity life-cycle.)
    @ToString: exclude other JPA entities and relationship to reduce method weight and avoid unexpected persistence problems like lazy initialization exceptions.

 

FINDBUGS and PMD

FindBugs works well with Lombok because it analyses the compiled code, so after Lombok.

On the contrary PMD, which analyses the source code, does not work well. I suggest to add a @SuppressWarnings(“PMD”) annotation at class level to tell PMD to completely skip the class. See here (http://pmd.sourceforge.net/pmd-5.1.0/suppressing.html) for more details.

 

DELOMBOK

Lombok provides a “delombok” (http://projectlombok.org/features/delombok.html) function so we can look at the code is really compiled, after Lombok processing.

We should open a terminal window, go to the project root dir and run the following command:

java -jar <path_to_lombok.jar> delombok src -d src-del

where

  • <path_to_lombok.jar> is the path to the lombok jar file. Maven users can find it at <maven_repository>/org/projectlombok/lombok/<version>/lombok-<version>.jar
  • src is the name of source dir (Maven default)
  • src-del is a name of the dir where we want delombok to put all files.

Our delombok-ed file is

public class ToString {
    private boolean flag;
    private final int number;
    private final String text;
    private List<String> strList;

    public List<String> getStrList() {
        if (strList == null) {
            strList = new ArrayList<>(128);
        }
        return Collections.unmodifiableList(strList);
    }

    @java.lang.SuppressWarnings("all")
    public boolean isFlag() {
        return this.flag;
    }

    @java.lang.SuppressWarnings("all")
    public int getNumber() {
        return this.number;
    }

    @java.lang.SuppressWarnings("all")
    public String getText() {
        return this.text;
    }

    @java.lang.SuppressWarnings("all")
    public void setFlag(final boolean flag) {
        this.flag = flag;
    }

    @java.lang.SuppressWarnings("all")
    public void setStrList(final List<String> strList) {
        this.strList = strList;
    }

    @java.beans.ConstructorProperties({"number", "text"})
    @java.lang.SuppressWarnings("all")
    public ToString(final int number, final String text) {
        this.number = number;
        this.text = text;
    }

    @java.lang.Override
    @java.lang.SuppressWarnings("all")
    public boolean equals(final java.lang.Object o) {
        if (o == this) return true;
        if (!(o instanceof ToString)) return false;
        final ToString other = (ToString)o;
        if (!other.canEqual((java.lang.Object)this)) return false;
        if (this.getNumber() != other.getNumber()) return false;
        final java.lang.Object this$text = this.getText();
        final java.lang.Object other$text = other.getText();
        if (this$text == null ? other$text != null : !this$text.equals(other$text)) return false;
        return true;
    }

    @java.lang.SuppressWarnings("all")
    public boolean canEqual(final java.lang.Object other) {
        return other instanceof ToString;
    }

    @java.lang.Override
    @java.lang.SuppressWarnings("all")
    public int hashCode() {
        final int PRIME = 277;
        int result = 1;
        result = result * PRIME + this.getNumber();
        final java.lang.Object $text = this.getText();
        result = result * PRIME + ($text == null ? 0 : $text.hashCode());
        return result;
    }

    @java.lang.Override
    @java.lang.SuppressWarnings("all")
    public java.lang.String toString() {
        return "ToString(flag=" + this.isFlag() + ", number=" + this.getNumber() + ", text=" +
            this.getText() + ")";
    }
}