1. Java Style

Java is a language (sort of anyway) and languages come with a culture. One such cultural aspect is the way you format your code, like placing your brackets, parenthesis, spaces and curly braces. This coding style is intended to help you read the code, recognize the structure at a glance and find the interesting details easily and spot on.

The official Java style is derived from the Kernighan and Ritchie (K&R) style for the C programming language. Since syntactically Java inherits quite a lot from C, that would be logical choice.

The current and preferred way of using this java style is best described in the Google Java Style Guide.

1.1. Where have you put your Curly Braces.

Most holy wars are fought over the placement of the curlies '{}', and in some cases other brackets [] or parenthesis () and <> too. In particular: Put them at the beginning of the line or at the end. The Java Style Guide is quite clear about that: Braces.

My personal motivation would be: If your understand that C and Java are block oriented languages, then you immediately will understand that placing a brace at the beginning of a line can only mean that you start a new block. This allows you to define a local scope. This is what you already know from for loops. Well the loop need not be there to allow yourselves to have some very local variables, like in the example below.

If you understand this block aspect of the K&R style, you know that you do not have to search for the name of a method, a class start or anything else. The block is just a block with local scope. It helps readability, because you can define your local variables at the place your need them and confine them there, without having the locals interfere with anything else in the method or class.

example of block with scoped local variable
        {
            int i=0;
            // do something with i
        }

This often overlooked feature can help big time to help improve the readability of your code, in particular when the method is getting big. But since having big methods is a bit of a no go area in a modern programming style.[1], your rarely see it in practice.

In Java there is also another reason. You can have blocks at the class level, which allow you to define some kind of anonymous constructor. Remember Anonymous Inner Classes? Well, sometimes you want to have a constructor, just to initialise things. Here is an examples from the Java FX binding chapter.

initialize a binding in an 'Anonymous' constructor, lines 10..12, which is a block with no name…​
    public static void main( String[] args ) {

        final DoubleProperty a = new SimpleDoubleProperty( 1 );
        final DoubleProperty b = new SimpleDoubleProperty( 2 );
        final DoubleProperty c = new SimpleDoubleProperty( 3 );
        final DoubleProperty d = new SimpleDoubleProperty( 4 );

        DoubleBinding db = new DoubleBinding() {

            { (1)
                super.bind( a, b, c, d );
            } (2)

            @Override
            protected double computeValue() {
                return ( a.get() * b.get() ) + ( c.get() * d.get() );
            }
        };

        System.out.println( db.get() );
        b.set( 3 );
        System.err.println( db.get() );
    }
1 Start of anonymous block in line 10.
2 End of anonymous block in line 12.

So whenever you find a closing bracket, you only have to look up in the same column to find what it belongs to. If you find the start of a method, then that’s what its is, if you find an opening bracket, stop looking, you have found its meaning, a block.

1.2. Javadoc style

Not only does Java code have a proper style, the same applies to java-doc.

  • Public means documented, as in proper javadoc.

    • Everything that is marked public is part of the public API and must be documented.

    • protected and public are alike here. They provide access to members from classes outside the package and must be documented.

  • Because all [2] members in an interface default to public you need to document them too.

You can skip on documentation if * The member is not public or protected * For methods: it overwrites a method in a (documented) interface or super class.

Javadoc starts with /* and ends with /

1.2.1. Class javadoc

A (public|protected) class or interface needs javadoc at its class definition, just before class or interface. A required tag is @author, and you are allowed to have that multiple times in a class, in particular if multiple authors contributed substantially. See the the jdk libraries for examples.

Excerpt from the String javadoc.
<p>A {@code String} represents a string in the UTF-16 format
 * in which <em>supplementary characters</em> are represented by <em>surrogate
 * pairs</em> (see the section <a href="Character.html#unicode">Unicode
 * Character Representations</a> in the {@code Character} class for
 * more information).
 * Index values refer to {@code char} code units, so a supplementary
 * character uses two positions in a {@code String}.
 * <p>The {@code String} class provides methods for dealing with
 * Unicode code points (i.e., characters), in addition to those for
 * dealing with Unicode code units (i.e., {@code char} values).
 *
 * @author  Lee Boynton
 * @author  Arthur van Hoff
 * @author  Martin Buchholz
 * @author  Ulf Zibis
 * @see     java.lang.Object#toString()
 * @see     java.lang.StringBuffer
 * @see     java.lang.StringBuilder
 * @see     java.nio.charset.Charset
 * @since   JDK1.0

As a minimum for class javadoc, have one short sentence describing the purpose of the class. End that line with a period., followed by the author tag. It is considered bad style to leave out author or make substantial changes to a file without adding the author of those changes.

Class java doc
/**
 * Friendly and well known program.
 *
 * @author John Doe
 * @author Jane Doe
 */
 public class HelloWorld {
   public static void main(String... args){
     /// wot goes here should be obvious.
   }

 }

In particular in a project like PRJ2, you should have multiple authors if that best describes how a program came about.

You can configure your IDE to insert the proper author info. In NetBeans IDE go to templates, settings, and uncomment the user property and make it have the proper information. This is particularly important if your user name on your machine is pattatje or some other obscure name that the teachers might not know.

Do Not skimp on Javadoc style. It is just as wrong as writing "Alice and Bob goes to town".

2. Adding your own code templates to NetBeans IDE

Productivity can be helped big time, if you add code templates to NetBeans. Quite a few are predefined but you can add your own too.

Go to Tools > Options > Editor > Code Templates.

You get this dialog:

codetemplatedialog

You can add one with the new button, Duh.

I find this one quite convenient:

Definition of my codetemplate jutm
//@Disabled("think TDD")
@${baseType type="org.junit.jupiter.api.Test" default="Test" editable="false"}
public void ${method}(){
    fail("method ${method} reached end. You know what to do.");
}
  • As of January 2020 jutm is junit 5 specific.

  • Note that @Disabled is a tag that is only used when writing all test bodies beforehand.

  • Once you start writing the test, you should remove or comment (best) the @Disabled to make the test effective.


Adding Code templates

3. Maven

From week two onwards we will use Maven as the preferred build tool. The link in the previous sentence points to the very readable complete reference manual, which also has some pointers for beginners, might you categorize yourselves as one.

3.1. Maven Repositories

A maven repository is a server that provides ready built maven 'artifacts', such as (binary) jar files containing libraries, frameworks or APIs and in many (but not all) companion jar files containing the javadoc (often) and sources of the same binary. A maven repository is NOT a source code management system (CMS),[3] although it typically holds several versions of a binary, and there are tools, such as Nexus Repository Manager.

There is a default repository, called maven central. You (as a team or company) can have your own repository. We at sebi Venlo do that too. Our repository lives at https://www.fontysvenlo.org/repository.

Our sebi Venlo maven repository at fontysvenlo.org is the simplest of simple: A plain (apache2) web server that does automatic indexing. Users with write access, such as your dear teachers (:P), can simply publish their maven artifacts using maven itself, which, with the help of secure copy, places the artifact in the appropriate directory structure, considering names and versions.

If you look at a maven repository you will see that it is organized along the three axes: groupId, artifactId and version.

3.2. Maven Settings

To make the sebi Venlo repository available for your own projects, add the following to your ~/.m2/settings.xml in the profiles section. You may also want to make that profile active.

If you create or open a maven project in NetBeans and open the Project Files folder, it should show a settings.xml file. If not, you can easily create your own in the proper spot on you platform (Linux, Windows, Mac OS-X) by right-clicking on the folder and choose create settings.xml. The settings file applies to all your maven projects, irrespective of the fact of using maven from the IDE or the command line.

create setting xml
Figure 1. Creating settings.xml
adding fontysvenlo repo to your maven settings.xml file.
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
    <profiles>
        <profile>  (1)
            <id>sebivenlo</id>
            <repositories>
                <repository>
                    <id>fontysvenlo.org</id> (2)
                    <url>https://www.fontysvenlo.org/repository</url> (3)
                </repository>
            </repositories>
        </profile>
    </profiles>
    <activeProfiles>
        <activeProfile>sebivenlo</activeProfile> (4)
    </activeProfiles>
</settings>
1 You define a profile inside the profiles section of your settings.xml.
2 Give the profile a name.
3 Specify the URL.
4 Use the given name to make it an active profile by default.

You could of course also simply copy (ctrl-C) the xml above and slam (ctrl-V) it into your newly created settings.xml file.

4. Sebipom 2.3.8

Spelled all lower case: sebipom, is a super pom to use in Fontys Venlo projects. It keeps your own pom.xml file simple and focused to declare just the dependencies needed. Niceties to do proper Test Driver Development are provided for in the sebipom definitions, including things as being able to create javadoc in a professional looking way, including code highlighted code snippets, checkstyle, reporting, code coverage with maven, pmd, spotbugs etc.

  • sebipom does declares no dependencies other than those for dynamic (e.g. JUnit, AssertJ etc) and static testing in the form of plugins and their configuration.

This way of using maven, having a super or parent pom defined globally (in a repository, not on a local path), is the modern usage. It can be seen in well known big java projects such as Spring Boot and quarkus, to name two contenders in the java-web technology world.

Note that I am using a separately installed maven (3.6.3 at the time of writing) which you can download from apache maven, not the one bundled with NetBeans or any other IDE. You can tell NetBeans (via tools→ options →java→maven) to use the installed one instead of the bundled one.

Doing this gives you the access to sebipom, which defines a parent pom for projects. This again provides some goodies that you would otherwise have to provide yourselves.
Such a parent pom is similar to a super class in Java; your pom inherits all the traits of the parent.
Including that parent is simple. See below for the sebipom (version 2.1.0 at the time of writing).

Setting sebipom as parent.
    <parent>
      <groupId>nl.fontys.sebivenlo</groupId>
      <artifactId>sebipom</artifactId>
      <version>2.3.8</version>
      <relativePath/> (1)
    </parent>
1 The parent pom does not live in a local directory near (relative to) the project, but instead in a repository. This makes a parent pom 'portable'.

All of the starter projects we provide already use this parent in some version. To get those working, apply the settings show in the paragraph [Configuring Maven].

If you want to use sebipom in your own project, either copy the parent definition into the pom file or start by replacing the NetBeans provided pom.xml file in your project by the basic one below. Add dependencies as required.

Basic pom.xml file setting sebipom as parent.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>nl.fontys.sebivenlo</groupId>
    <artifactId>basicsebimaven</artifactId>
    <version>1.0</version>
    <packaging>jar</packaging>
    <parent>
        <groupId>nl.fontys.sebivenlo</groupId>
        <artifactId>sebipom</artifactId>
        <version>2.3.8</version>
        <realtivePath/>
    </parent>
    <!-- The name in the IDE -->
    <name>My App</name>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.release>11</java.release>
        <!-- change mainClass to the proper starting point of your program, if any.-->
        <mainClass>basicsebimaven.Hello</mainClass>
    </properties>
    <dependencies>
      <!--example  -->
      <dependency>

      </dependency>
    </dpendencies>
</project>

4.1. Sebipom and Java FX

If you want to use semipom and build a JavaFX project, you need to activate the fx-profile. In the commandline that would be

mvn withfx profile
Figure 2. Commandline. Real software engineers can use the command line.

In netbeans you can do that by setting the configuration like in this picture:

fx profile nb
Figure 3. Activate a profile in netbeans

4.2. Using the SeBiPom in your own projects

To use the test libraries and other goodies that will be used throughout our course, you should add the sebipom and kind of super-pom (yes, thinking super class is not far off).

Modify the pom.xml file in your project to include sebipom as parent by adding these lines to the pom file:

    <parent>
        <groupId>nl.fontys.sebivenlo</groupId>
        <artifactId>sebipom</artifactId>
        <version>2.3.8</version> (1)
        <relativePath/>
    </parent>
1 Modify version when required. 2.x.x is for Java 11 and above, 1.x.x is for Java 8.

2.3.8 provides modular testing, required from week 12.
2.3.7 provides mockito support for JUnit 5, required from week 6.

  • Version 2.3.7 brings a proper fail message back instead of just a silent assertion failed exception.

  • Version 2.3.7 has preview feature. If you would like to play with new java features such as java 14 instanceof to variable, enable the preview profile in netbeans. If you want to use more profiles, add them as a comma separated list as parameter to the -P (profile) flag, as in
    mvn -P fx,preview package. Then run it with java --enable-preview …​.

As of 2020-04-22, sebipom reached version 2.3.8. Not all projects may have this version number for the parent sebipom. We improve as we go, sometimes because of tips we receive from our students, you for instance. Anyway, if the version is not at the newest, set it to the newest and rebuild. Revisit this part of the site to check the latest version number or look in the fontysvenlo maven reposity for the sebipom version.

Sebipom enables testing for modular projects but does not enforce modular projects.

4.3. Upgrade all projects with one command

Since sebipom is a somewhat moving target, you may have to update the parent pom of the projects that depend on it. All PRC2 projects do. This oneliner will do that for all projects below the current directory. After navigating to the parent of all such projects, do this in the shell:

for i in $(find . -name pom.xml); do (cd $(dirname $i); mvn versions:update-parent  & )   ; done

It works on any bash supporting machine, tested on ubuntu and should work on OS-X and under windows when using git-bash or the windows subsystem for Linux.

4.4. Maven on Steroids or: use it properly

Sometimes you think, maven is not your thing because it is slowing you down, certainly if you are trying to work your way through your code TDD style: Write test, run test red, implement code, run test green, be happy.

But reconsider: Maven takes it’s job very serious, but since it is a computer program it stubbornly stupid, so it might be that you are using it in a wrong way.

Let me explain what maven does:

  • Maven uses build phases: initialize, compile, compile tests, run tests, package the application etc., when you build your application. It will check if all is in order, look if any updates are needed etc. This keeps maven busy and you waiting.

Packaging (which is what you do when you click build in the IDE) the application and
is only useful when your are really done: all tests are complete and the code turns them a nice green.

  • So do not mvn build, but instead mvn test, then maven will do the minimum required.

So if you are in the habit of clicking build and then run your tests, you might want to change you habit.

4.4.1. Maven the proper way, when still in the TDD phase

As long as you are writing test and writing code, just do:

mvn test, or the equivalent in you IDE (click the test button, not the build button)
or mvn clean and then mvn test. (click clean, click test).

Only when you are done with all your tests, do

  1. clean (mvn clean)

  2. build (mvn package mvn -P fx package for fx projects)

and then run your application.

Then maven can do all of it’s serious work of assembling your application for deployment


4.5. Maven Modules

Many projects will have more than just one component (jar or war file). Think of the parallel project project 2.

It is a good idea to reflect this design in the way your structure you source code: Use multiple modules.

4.5.1. Module

A module is just a maven project. Has a pom.xml which defines the relation with other modules.

mavenmodules
Figure 4. Modules and parent.

As you see in the figure, the parent lists its children. The children may have inter-dependencies. Otherwise it is just plain maven.

Snippet from a parent pom
    <groupId>nl.fontys.sebivenlo</groupId>
    <artifactId>parentpom</artifactId>
    <version>1.0</version>
    <packaging>pom</packaging>
    <properties>
      <version>1.0</version>
    </properties>
    <modules>
        <module>entities</module>
        <module>db</module>
        <module>app-logic</module>
        <module>ui</module>
        <module>restserver</module>
    </modules>

As is usual between parents and children, there is an inheritance relationship. The children inherit setting and groupid, and version, if defined as a property.

Do not declare dependencies of the children in the parent pom, because that introduces a cycle in the dependencies: parent depends on child, which depends on parent, which depend …​. etc.

The parent pom can declare all external dependencies, that are shared between the children, such as the testing frameworks, any other external dependencies. The parent can declare its own parent, allowing it to inherit and pass on anything that inherits from such parent.

The parent defines the packaging as pom, the children what ever is required, typically jar, war, or ear.

example pom for rest server.
<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>nl.fontys.sebivenlo</groupId>
        <artifactId>parentpom</artifactId>
        <version>1.0</version>
         <!-- parent directory .. as parent is natural but not mandatory -->
        <relativePath>..</relativePath>
    </parent>
    <artifactId>restserver</artifactId>
    <version>${version}</version>
    <packaging>war</packaging>
    <name>Rest server</name>
</project>

Putting things in modules has the following advantages:

  • It promotes loose coupling.

  • It can avoid the hen and egg problem: In a normal build, it wants all tests to pass, to be able to continue. For business code that is correct, but things like integration tests need a built war file, which cannot be built with failing tests.
    Solution: Put the integration tests in a separate module of its own, which can be run at any time and will not slow you down or worse, disable testing or not having any tests.

5. Flex Your Java Muscles

No, it is not about heavy lifting. It is about reconfiguring your Java environment easily. It also assumes that you are in the habit of using the command line over the GUI.

Sure, a GUI is 'user friendly' if you are willing to look for the things your want to use, and know where you need to look for it. But what about the computer listening to you for a change, instead of you having to scroll through its wealth of options and other stuff you may have installed.

This is a POSIX hack, meaning that it applies to Linux and to Mac OS-X (with a little tweaking) alike. It may also apply to Windows when using git-bash, MINGW, Powershell or the 'Linux extensions for windows'. You mileage may vary though.

5.1. Concepts used

  • $PATH The PATH environment variable that determines the way programs are found in the command line.
    all commands that you can enter on the commandline are found using the $PATH variable.

  • $JAVA_HOME The environment variable that tells where your java installation lives. It is used by apache-ant (ant) and apache-maven (mvn) alike.

  • You set these variables in your start-up script, like .bashrc.

  • You use aliases to abbreviate your commands.

  • You start the IDE from the command line. Always, so YOU are in control of where and how it’s started.

The whole operation involves three modifications:

  1. Set the variables in your ~/.bashrc.

  2. Add a helper script, called J, put it in a directory in your PATH. ${HOME}/bin is a good place, if that is on your path.

  3. Create aliases, to make typing the command simple, like j8 to switch to Java 8 and j12 to do the same for Java 12.

5.2. Setting in startup script

setting JAVA_HOME and PATH in ~/.bashrc
## DEFAULT IS JAVA 8 HERE
export JAVA_HOME=/usr/lib/jvm/java-8-oracle
export PATH=${JAVA_HOME}/bin:$PATH

5.3. Switching to other Java version

updating JAVA_HOME and PATH to switch java version.
#!/bin/bash

## This script assumes that the JAVA_HOME environment variable is set
##   and that the PATH contains ${JAVA_HOME}/bin
## The java variant that is to be put in JAVA_HOME and PATH is determined
##   by how what this script is called.
## J8 for Java 8, J11 for Java 11 and J12 for Java 12. It could easily be
##   extended to include Java 9 and 10 too, buy at the time of writing I see
##   little point because 12 is the current open JDK and 11 the LTS version.
##   J8 is in because it is the default for many still.
##
## You typically have (sym) links pointing to this script, so it appears
##   to have different names, changing its meaning.
##
## Usage: eval $(scriptname) e.g. eval $(J12)
## By using  bash aliases, such as alias j8='eval $(J8)' the use of
##   this script will become a feast.


## get this script name
thisname=$(basename $0)
## get the current path setting
OPATH=${PATH}

## Let my name do the choosing
case ${thisname} in
    J8)
	NJAVA_HOME=/usr/lib/jvm/java-8-oracle;;
    J11)
	NJAVA_HOME=/usr/lib/jvm/jdk-11.0.2;;
    J12)
	NJAVA_HOME=/usr/lib/jvm/jdk-12;;
    *)
	echo call me as 'eval $(J8)', 'eval $(J11)' or 'eval $(J12)'
	exit 1
	;;
esac

## edit path to use the new java_home
p=$(echo ${OPATH} | sed -e "s@${JAVA_HOME}/bin@${NJAVA_HOME}/bin@")

##
echo export JAVA_HOME=${NJAVA_HOME}
echo export PATH=${p}

5.4. All made simple with aliases

You can tie this all together with some aliases which classically are stored in a file called ${HOME}/.bash_aliases and are loaded on login and each time you open a terminal.

using aliases to switch with simple command. Excerpt from my .bash_aliases file.
alias j12='eval $(J12)'
alias j11='eval $(J11)'
alias j8='eval $(J8)'
j8j11 terminal
Figure 5. see it all work

As you will notice, switching Java versions in this way is very fast.




1. if your method gets big, you should break it up in smaller parts, like private methods
2. In java 11 you can have private static methods in interfaces
3. Guess why