Table of Contents

FallPits

Libs

Object Comparisson Details
Apache Commons EqualsBuilder.reflectionEquals(Object o1, Object o2) Helps to implement Object comparison
Javassist Implements powerfull reflection funcitonality, e.g. proxies

Available JDKs

https://sdkman.io/jdks

install alternative JDK using SDKman

install SDK man

# sdkman
curl -fsSL "https://get.sdkman.io?rcupdate=false" | bash

Install sdk man in silent mode

# sdkman
curl -fsSL "https://get.sdkman.io?rcupdate=false" | bash

List and install java

sdk list java

================================================================================
Available Java Versions for Linux 64bit
================================================================================
 Vendor        | Use | Version      | Dist    | Status     | Identifier
--------------------------------------------------------------------------------
 Corretto      |     | 19.0.2       | amzn    |            | 19.0.2-amzn
               |     | 19.0.1       | amzn    |            | 19.0.1-amzn
               |     | 17.0.6       | amzn    |            | 17.0.6-amzn
               |     | 17.0.5       | amzn    |            | 17.0.5-amzn
               |     | 11.0.18      | amzn    |            | 11.0.18-amzn
               |     | 11.0.17      | amzn    |            | 11.0.17-amzn
               |     | 8.0.362      | amzn    |            | 8.0.362-amzn
               |     | 8.0.352      | amzn    |            | 8.0.352-amzn
 Dragonwell    |     | 17.0.6       | albba   |            | 17.0.6-albba
               |     | 17.0.5       | albba   |            | 17.0.5-albba
               |     | 17.0.4       | albba   |            | 17.0.4-albba
               |     | 11.0.18      | albba   |            | 11.0.18-albba
               |     | 11.0.17      | albba   |            | 11.0.17-albba
               |     | 11.0.16      | albba   |            | 11.0.16-albba
               |     | 8.0.362      | albba   |            | 8.0.362-albba
               |     | 8.0.352      | albba   |            | 8.0.352-albba
               |     | 8.0.345      | albba   |            | 8.0.345-albba
 Gluon         |     | 22.1.0.1.r17 | gln     |            | 22.1.0.1.r17-gln
               |     | 22.1.0.1.r11 | gln     |            | 22.1.0.1.r11-gln
 GraalVM       |     | 22.3.r19     | grl     |            | 22.3.r19-grl
               |     | 22.3.r17     | grl     |            | 22.3.r17-grl
               |     | 22.3.r11     | grl     |            | 22.3.r11-grl
               |     | 22.3.1.r19   | grl     |            | 22.3.1.r19-grl
               |     | 22.3.1.r17   | grl     |            | 22.3.1.r17-grl
               |     | 22.3.1.r11   | grl     |            | 22.3.1.r11-grl
               |     | 22.2.r17     | grl     |            | 22.2.r17-grl
               |     | 22.2.r11     | grl     |            | 22.2.r11-grl
               |     | 22.1.0.r17   | grl     |            | 22.1.0.r17-grl
               |     | 22.1.0.r11   | grl     |            | 22.1.0.r11-grl
               |     | 22.0.0.2.r17 | grl     |            | 22.0.0.2.r17-grl
               |     | 22.0.0.2.r11 | grl     |            | 22.0.0.2.r11-grl
               |     | 21.3.3.r17   | grl     |            | 21.3.3.r17-grl
               |     | 21.3.3.r11   | grl     |            | 21.3.3.r11-grl
               |     | 21.3.3.1.r17 | grl     |            | 21.3.3.1.r17-grl
               |     | 21.3.3.1.r11 | grl     |            | 21.3.3.1.r11-grl
               |     | 21.3.2.r17   | grl     |            | 21.3.2.r17-grl
               |     | 21.3.2.r11   | grl     |            | 21.3.2.r11-grl
               |     | 21.3.1.r8    | grl     |            | 21.3.1.r8-grl
               |     | 21.2.0.r8    | grl     |            | 21.2.0.r8-grl
               |     | 21.1.0.r8    | grl     |            | 21.1.0.r8-grl
               |     | 20.3.6.r11   | grl     |            | 20.3.6.r11-grl
               |     | 20.3.3.r8    | grl     |            | 20.3.3.r8-grl
               |     | 20.3.2.r8    | grl     |            | 20.3.2.r8-grl
               |     | 19.3.6.r11   | grl     |            | 19.3.6.r11-grl
               |     | 19.3.6.r8    | grl     |            | 19.3.6.r8-grl
 Java.net      |     | 21.ea.8      | open    |            | 21.ea.8-open
               |     | 21.ea.7      | open    |            | 21.ea.7-open
               |     | 21.ea.6      | open    |            | 21.ea.6-open
               |     | 21.ea.5      | open    |            | 21.ea.5-open
               |     | 21.ea.4      | open    |            | 21.ea.4-open
               |     | 20.ea.34     | open    |            | 20.ea.34-open
               |     | 20.ea.33     | open    |            | 20.ea.33-open
               |     | 20.ea.32     | open    |            | 20.ea.32-open
               |     | 20.ea.31     | open    |            | 20.ea.31-open
               |     | 20.ea.30     | open    |            | 20.ea.30-open
               |     | 19.ea.1.pma  | open    |            | 19.ea.1.pma-open
               |     | 19.0.2       | open    |            | 19.0.2-open
               |     | 19.0.1       | open    |            | 19.0.1-open
               |     | 11.0.12      | open    |            | 11.0.12-open
               |     | 11.0.2       | open    |            | 11.0.2-open
               |     | 8.0.302      | open    |            | 8.0.302-open
               |     | 8.0.282      | open    |            | 8.0.282-open
               |     | 8.0.265      | open    |            | 8.0.265-open
 Liberica      |     | 19.0.2.fx    | librca  |            | 19.0.2.fx-librca
               |     | 19.0.2       | librca  |            | 19.0.2-librca
               |     | 19.0.1.fx    | librca  |            | 19.0.1.fx-librca
               |     | 19.0.1       | librca  |            | 19.0.1-librca
               |     | 17.0.6.fx    | librca  |            | 17.0.6.fx-librca
               |     | 17.0.6       | librca  |            | 17.0.6-librca
               |     | 17.0.5.fx    | librca  |            | 17.0.5.fx-librca
               |     | 17.0.5       | librca  |            | 17.0.5-librca
               |     | 11.0.18.fx   | librca  |            | 11.0.18.fx-librca
               |     | 11.0.18      | librca  |            | 11.0.18-librca
               |     | 11.0.17.fx   | librca  |            | 11.0.17.fx-librca
               |     | 11.0.17      | librca  |            | 11.0.17-librca
               |     | 8.0.362.fx   | librca  |            | 8.0.362.fx-librca
               |     | 8.0.362      | librca  |            | 8.0.362-librca
               |     | 8.0.352.fx   | librca  |            | 8.0.352.fx-librca
               |     | 8.0.352      | librca  |            | 8.0.352-librca
               |     | 8.0.332.fx   | librca  |            | 8.0.332.fx-librca
 Liberica NIK  |     | 22.3.r17     | nik     |            | 22.3.r17-nik
               |     | 22.3.r11     | nik     |            | 22.3.r11-nik
               |     | 22.3.1.r17   | nik     |            | 22.3.1.r17-nik
               |     | 22.3.1.r11   | nik     |            | 22.3.1.r11-nik
               |     | 22.2.r17     | nik     |            | 22.2.r17-nik
               |     | 22.2.r11     | nik     |            | 22.2.r11-nik
               |     | 22.1.r17     | nik     |            | 22.1.r17-nik
               |     | 22.1.r11     | nik     |            | 22.1.r11-nik
               |     | 22.0.0.2.r17 | nik     |            | 22.0.0.2.r17-nik
               |     | 22.0.0.2.r11 | nik     |            | 22.0.0.2.r11-nik
               |     | 21.3.3.r17   | nik     |            | 21.3.3.r17-nik
               |     | 21.3.3.r11   | nik     |            | 21.3.3.r11-nik
               |     | 21.3.3.1.r17 | nik     |            | 21.3.3.1.r17-nik
               |     | 21.3.3.1.r11 | nik     |            | 21.3.3.1.r11-nik
               |     | 21.3.2.r17   | nik     |            | 21.3.2.r17-nik
               |     | 21.3.2.r11   | nik     |            | 21.3.2.r11-nik
               |     | 21.2         | nik     |            | 21.2-nik
               |     | 21.1         | nik     |            | 21.1-nik
               |     | 21.0.0.2.r11 | nik     |            | 21.0.0.2.r11-nik
               |     | 21.0.0.2     | nik     |            | 21.0.0.2-nik
 Mandrel       |     | 22.3.1.r17   | mandrel |            | 22.3.1.r17-mandrel
               |     | 22.3.0.1.r17 | mandrel |            | 22.3.0.1.r17-mandrel
               |     | 22.2.r17     | mandrel |            | 22.2.r17-mandrel
               |     | 22.2.r11     | mandrel |            | 22.2.r11-mandrel
               |     | 22.1.0.0.r17 | mandrel |            | 22.1.0.0.r17-mandrel
               |     | 22.1.0.0.r11 | mandrel |            | 22.1.0.0.r11-mandrel
               |     | 22.0.0.2.r17 | mandrel |            | 22.0.0.2.r17-mandrel
               |     | 22.0.0.2.r11 | mandrel |            | 22.0.0.2.r11-mandrel
               |     | 21.3.5.1.r17 | mandrel |            | 21.3.5.1.r17-mandrel
               |     | 21.3.5.1.r11 | mandrel |            | 21.3.5.1.r11-mandrel
               |     | 21.3.4.r17   | mandrel |            | 21.3.4.r17-mandrel
              |     | 21.3.4.r11   | mandrel |            | 21.3.4.r11-mandrel
               |     | 21.3.3.r17   | mandrel |            | 21.3.3.r17-mandrel
               |     | 21.3.3.r11   | mandrel |            | 21.3.3.r11-mandrel
               |     | 21.3.2.0.r17 | mandrel |            | 21.3.2.0.r17-mandrel
               |     | 21.3.2.0.r11 | mandrel |            | 21.3.2.0.r11-mandrel
               |     | 21.3.1.1.r17 | mandrel |            | 21.3.1.1.r17-mandrel
               |     | 21.3.1.1.r11 | mandrel |            | 21.3.1.1.r11-mandrel
               |     | 21.3.1.0.r17 | mandrel |            | 21.3.1.0.r17-mandrel
               |     | 21.3.1.0.r11 | mandrel |            | 21.3.1.0.r11-mandrel
               |     | 21.3.0.0     | mandrel |            | 21.3.0.0-mandrel
               |     | 21.2.0.2     | mandrel |            | 21.2.0.2-mandrel
               |     | 20.3.3.0     | mandrel |            | 20.3.3.0-mandrel
 Microsoft     |     | 17.0.6       | ms      |            | 17.0.6-ms
               |     | 17.0.5       | ms      |            | 17.0.5-ms
               |     | 11.0.18      | ms      |            | 11.0.18-ms
               |     | 11.0.17      | ms      |            | 11.0.17-ms
 Oracle        |     | 19.0.2       | oracle  |            | 19.0.2-oracle
               |     | 19.0.1       | oracle  |            | 19.0.1-oracle
               |     | 17.0.6       | oracle  |            | 17.0.6-oracle
               |     | 17.0.5       | oracle  |            | 17.0.5-oracle
 SapMachine    |     | 19.0.2       | sapmchn |            | 19.0.2-sapmchn
               |     | 19.0.1       | sapmchn |            | 19.0.1-sapmchn
               |     | 17.0.6       | sapmchn |            | 17.0.6-sapmchn
               |     | 17.0.5       | sapmchn |            | 17.0.5-sapmchn
               |     | 11.0.18      | sapmchn |            | 11.0.18-sapmchn
               |     | 11.0.17      | sapmchn |            | 11.0.17-sapmchn
 Semeru        |     | 18.0.2       | sem     |            | 18.0.2-sem
               |     | 17.0.5       | sem     |            | 17.0.5-sem
               |     | 17.0.4.1     | sem     |            | 17.0.4.1-sem
               |     | 11.0.17      | sem     |            | 11.0.17-sem
               |     | 11.0.16.1    | sem     |            | 11.0.16.1-sem
               |     | 8.0.352      | sem     |            | 8.0.352-sem
               |     | 8.0.345      | sem     |            | 8.0.345-sem
 Temurin       |     | 19.0.2       | tem     |            | 19.0.2-tem
               |     | 19.0.1       | tem     |            | 19.0.1-tem
               |     | 17.0.6       | tem     |            | 17.0.6-tem
               |     | 17.0.5       | tem     |            | 17.0.5-tem
               |     | 11.0.18      | tem     |            | 11.0.18-tem
               |     | 11.0.17      | tem     |            | 11.0.17-tem
               |     | 8.0.362      | tem     |            | 8.0.362-tem
               |     | 8.0.352      | tem     |            | 8.0.352-tem
               |     | 8.0.345      | tem     |            | 8.0.345-tem
 Trava         |     | 11.0.15      | trava   |            | 11.0.15-trava
               |     | 11.0.9       | trava   |            | 11.0.9-trava
               |     | 8.0.282      | trava   |            | 8.0.282-trava
               |     | 8.0.232      | trava   |            | 8.0.232-trava
 Zulu          |     | 19.0.2       | zulu    |            | 19.0.2-zulu
               |     | 19.0.2.fx    | zulu    |            | 19.0.2.fx-zulu
               |     | 19.0.1       | zulu    |            | 19.0.1-zulu
               |     | 19.0.1.fx    | zulu    |            | 19.0.1.fx-zulu
               |     | 17.0.6       | zulu    |            | 17.0.6-zulu
               |     | 17.0.6.fx    | zulu    |            | 17.0.6.fx-zulu
               |     | 17.0.5       | zulu    |            | 17.0.5-zulu
               |     | 17.0.5.fx    | zulu    |            | 17.0.5.fx-zulu
               |     | 11.0.18      | zulu    |            | 11.0.18-zulu
               |     | 11.0.18.fx   | zulu    |            | 11.0.18.fx-zulu
               |     | 11.0.17      | zulu    |            | 11.0.17-zulu
               |     | 11.0.17.fx   | zulu    |            | 11.0.17.fx-zulu
               |     | 8.0.362      | zulu    |            | 8.0.362-zulu
               |     | 8.0.362.fx   | zulu    |            | 8.0.362.fx-zulu
               |     | 8.0.352      | zulu    |            | 8.0.352-zulu
               |     | 8.0.352.fx   | zulu    |            | 8.0.352.fx-zulu
               |     | 7.0.352      | zulu    |            | 7.0.352-zulu
               |     | 6.0.119      | zulu    |            | 6.0.119-zulu
================================================================================
Omit Identifier to install default version 17.0.6-tem:
    $ sdk install java
Use TAB completion to discover available versions
    $ sdk install java [TAB]
Or install a specific version by Identifier:
    $ sdk install java 17.0.6-tem
Hit Q to exit this list view
================================================================================

silent installing some java

# java open GraalVM from liberica "native image kit"
sdk install java 22.3.r17-nik < /dev/null

# java openjdk
sdk install java 19.0.2-open < /dev/null

switching version

sdk use java 19.0.2-open
sdk use java 22.3.r17-nik

install alternative JDK in parallel and switch

https://ubunlog.com/en/instala-java-8-9-y-10-en-ubuntu-18-04-y-derivados/

sudo apt-get update

// check which openjdk versions are available
apt-cache search openjdk.*-jdk

// install some JDK
sudo apt install openjdk-8-jdk
sudo apt install openjdk-9-jdk
sudo apt install openjdk-11-jdk
sudo apt install openjdk-17-jdk

// list 
update-java-alternatives -l

// switch
sudo update-alternatives --config java

There are 3 choices for the alternative java (providing /usr/bin/java).

Selection    Path...
------------------------------------------------------------
  0            /usr/lib/jvm/java-9-oracle/bin/java...
* 1            /usr/lib/jvm/java-7-oracle/jre/bin/java...
  2            /usr/lib/jvm/java-8-oracle/jre/bin/java...
  3            /usr/lib/jvm/java-9-oracle/bin/java...

JDK Tools

Java consists of many tools Here is a full list: http://docs.oracle.com/javase/8/docs/technotes/tools/#basic

Here are some tools, which I think are most useful:

java launcher for java apps
javac compiler for the Java programms
keytools manages keystores, certificates
jar creates jars
jarsigner signs the jars using certificates
jvisualvm Tool to monitor a Java-Application (JVM)
jconsole wie jvisualvm

Garbage Collector, Java Memory (Heap, Stack)

Heap

Java-Heap is reclaimed by garbage collector.
More about garbage collector is described here:
http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

In Java8 the memory model was redesigned (PermGen was eliminated)

JavaDoc

JavaDoc can contain Pictures

    /** Sorts labels according to {@link #LABEL_PRIORITY} 
     * <img alt="" src=png;base64,iVBORw0KGgoAAAANSUhEUgAAARYAAAiBMy1wVPx/7leh9m/FkN8AAAAASUVORK5CYII=" />
     */
    public static final method() {   }

Annotations

Details are here: http://en.wikipedia.org/wiki/Java_annotation

package com.annotation;
 
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD,
 ElementType.CONSTRUCTOR,ElementType.ANNOTATION_TYPE,
 ElementType.PACKAGE,ElementType.FIELD,ElementType.LOCAL_VARIABLE})
@Inherited
 
public @interface Unfinished {
        public enum Priority { LOW, MEDIUM, HIGH }
        String value();
        String[] changedBy() default "";
        String[] lastChangedBy() default "";
        Priority priority() default Priority.MEDIUM;
        String createdBy() default "James Gosling";
        String lastChanged() default "08/07/2011";
}

@Unfinished( Proority = HIGH, value=2, createdBy="Mr. Anderson")
class MyClass{

}

POJO, JavaBean, DTO, ValueObject

Here are some details about the differences: http://stackoverflow.com/questions/1612334/difference-between-dto-vo-pojo-javabeans

Java provides some API to work with JavaBean getter / setter

BeanInfo info = Introspector.getBeanInfo(domainObjectType);
PropertyDescriptor[] props = info.getPropertyDescriptors();

for (PropertyDescriptor pd : props) {
   Class<?> propertyType = pd.getPropertyType();
   String propertyName = pd.getName();
}

Collections

LinkedList
// good to iterate over elements, stop on each element while condition is true
LinkedList.getFirst();
LinkedList.removeFirst();

Comparisson

The Following code does different things.

Collection.equals(Collection)

In HashMaps<MyObject>:

it copares the elements in collections, <fc #FF0000>by computing a key for every element, which is a hash</fc> and checking, whether the other collection contains the key. The implementation of MyObject.equals() is never called.

In ArrayList<MyObject>: it copares the elements in collections, by doing MyObject.equals(MyObject2) for every element.

Multithreading

Threadlocal variables

It may happen, that every thread should have an own variable.

    private static final ThreadLocal<ApplicationContext> current = new ThreadLocal<>();

    public static void setCurrent(ApplicationContext context) {
        current.set(context);
    }

    public static ApplicationContext getCurrent() {
        return current.get();
    }

Enums with Parameters

The Enum can hava a Constructor and Methods. It can be used to create many constants, dependent on X factors, like price …

Example: http://www.avajava.com/tutorials/lessons/how-do-i-use-the-enum-type-with-a-constructor.html

Logging

Logging Fascade

The jar with a logging Fascade contains a bunch of interfaces, without implementation. The implementation of the interfaces are provided in a separate jar, see logging engine. The following logging Fascade are available:

Slf4J Most popular logging interfaces in the java world.
Apache’s commons-logging Less popular option.

Logging Engine

Log4j2 Replaces Log4j. Claims to be faster, than the predecessor.
LogBack

which is an evolved version of Log4j. Logback is the implementation of the SL4J interfaces. The Details are here: http://logback.qos.ch/

This implementation is available for all platforms. Once learned it can be reused.

The configurations may be done in XML or in code. Sometimes they do not work in XML, here an example of a configuration in code.

Details Logback

Concept Explanation
Logger

hiererachy - loggers are hierarchically arranged by name. The names mark the packages/classes which the messages d ooriginate from!

			"com.test.logger" is parent of 
			"com.test.logger.core" is parent of 
			"com.test.logger.core.gui" is parent of ..
Appender

the Objects which are attached to the Loggers. They are responsible for writing down the output into Files, Consoles etc. Each Logger may have multiple appenders.

LoggerContext

is reponsible for maufacturing loggers! Every logger is attached to one.

Layout

configures the Format of the output messages, e.g. : 176 [main] DEBUG manual.architecture.HelloWorld2 - Hello world.

TurboFilter

is used to deny or accept messages according to some conditions.

		LevelFilter can be used to filter messages below of level ERROR for an appender.
		Then several appenders with different LevelFilters can be applied to the same logging level.	

import java.io.File;

import org.slf4j.LoggerFactory;

import android.os.Environment;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.android.LogcatAppender;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.filter.LevelFilter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.rolling.RollingFileAppender;
import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy;
import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
import ch.qos.logback.core.spi.FilterReply;

public class LoggerConfig {

	//The path is relative to the Android External storage.
	final static String LOG_DIR_REL_PATH = "/Android/data/de.ivu.eticket.app/logs";
	final static String MAX_FILE_SIZE = "30MB";
	final static String LOG_PATTERN = "%-7level %date{dd MMM HH:mm} [%thread]: %message%n";
	final static String FILENAME_ERRORS = "logErrors";
	final static String FILENAME_TRACE = "logТrace";
	
	public static void configureLogbackDirectly() {

	    
		File file = Environment.getExternalStorageDirectory();
		String pathExternalStorage = file.getPath();
		String logPathAbsolute = pathExternalStorage + LOG_DIR_REL_PATH;

		LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
	    context.reset();
	    
	    

	    
	    
	    //FILE ERRORS
	    RollingFileAppender<ILoggingEvent> rollingFileAppenderErrors = new RollingFileAppender<ILoggingEvent>();
	    rollingFileAppenderErrors.setAppend(true);
	    rollingFileAppenderErrors.setContext(context);

	    // OPTIONAL: Set an active log file (separate from the rollover files).
	    // If rollingPolicy.fileNamePattern already set, you don't need this.
	    rollingFileAppenderErrors.setFile(logPathAbsolute + "/"+FILENAME_ERRORS+".txt");

	    TimeBasedRollingPolicy<ILoggingEvent> rollingPolicy1 = new TimeBasedRollingPolicy<ILoggingEvent>();
	    rollingPolicy1.setFileNamePattern(logPathAbsolute + "/" +FILENAME_ERRORS+".%d.txt"); //is overridden by setFile() but necessary
	    rollingPolicy1.setMaxHistory(7);
	    rollingPolicy1.setParent(rollingFileAppenderErrors);  // parent and context required!
	    rollingPolicy1.setContext(context);
	    rollingPolicy1.start();
	    rollingFileAppenderErrors.setRollingPolicy(rollingPolicy1);
	    
	    SizeBasedTriggeringPolicy<ILoggingEvent> sizePolicy1 = new SizeBasedTriggeringPolicy<ILoggingEvent>();
	    sizePolicy1.setMaxFileSize(MAX_FILE_SIZE);
	    sizePolicy1.start();
	    rollingFileAppenderErrors.setTriggeringPolicy(sizePolicy1);
	    
	    LevelFilter levelFilter1 = new LevelFilter();
	    levelFilter1.setLevel(Level.ERROR);
	    levelFilter1.start();
	    levelFilter1.setOnMatch(FilterReply.ACCEPT);
	    levelFilter1.setOnMismatch(FilterReply.DENY);
	    rollingFileAppenderErrors.addFilter(levelFilter1);
	    
	    PatternLayoutEncoder encoder1 = new PatternLayoutEncoder();
	    encoder1.setPattern(LOG_PATTERN);
	    encoder1.setContext(context);
	    encoder1.start();
	    rollingFileAppenderErrors.setEncoder(encoder1);
	    
	    rollingFileAppenderErrors.start();
	    
	    
	    
	    
	    
	    
	    //FILE DEBUG
	    RollingFileAppender<ILoggingEvent> rollingFileAppenderDebug = new RollingFileAppender<ILoggingEvent>();
	    rollingFileAppenderDebug.setAppend(true);
	    rollingFileAppenderDebug.setContext(context);

	    // OPTIONAL: Set an active log file (separate from the rollover files).
	    // If rollingPolicy.fileNamePattern already set, you don't need this.
	    rollingFileAppenderDebug.setFile(logPathAbsolute + "/"+FILENAME_TRACE+".txt");

	    TimeBasedRollingPolicy<ILoggingEvent> rollingPolicy2 = new TimeBasedRollingPolicy<ILoggingEvent>();
	    rollingPolicy2.setFileNamePattern(logPathAbsolute + "/" +FILENAME_TRACE+".%d.txt"); //is overridden by setFile() but necessary
	    rollingPolicy2.setMaxHistory(7);
	    rollingPolicy2.setParent(rollingFileAppenderDebug);  // parent and context required!
	    rollingPolicy2.setContext(context);
	    rollingPolicy2.start();

	    
	    SizeBasedTriggeringPolicy<ILoggingEvent> sizePolicy2 = new SizeBasedTriggeringPolicy<ILoggingEvent>();
	    sizePolicy2.setMaxFileSize(MAX_FILE_SIZE);
	    
	    rollingFileAppenderDebug.setRollingPolicy(rollingPolicy2);
	    rollingFileAppenderDebug.setTriggeringPolicy(sizePolicy2);
	    

	    
	    PatternLayoutEncoder encoder2 = new PatternLayoutEncoder();
	    encoder2.setPattern(LOG_PATTERN);
	    encoder2.setContext(context);
	    encoder2.start();

	    rollingFileAppenderDebug.setEncoder(encoder2);
	    rollingFileAppenderDebug.start();
	    

	    
	    
	    
	    
	    //LOGCAT
	    PatternLayoutEncoder logCatENcoder = new PatternLayoutEncoder();
	    logCatENcoder.setContext(context);
	    logCatENcoder.setPattern(LOG_PATTERN);
	    logCatENcoder.start();
	    
	    LogcatAppender logcatAppender = new LogcatAppender();
	    logcatAppender.setContext(context);
	    logcatAppender.setEncoder(logCatENcoder);
	    logcatAppender.start();
	    
	    
		
	    
//	     add the newly created appenders to the root logger;
	    ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
	    root.setLevel(Level.TRACE);
	    root.addAppender(rollingFileAppenderDebug);
	    root.addAppender(rollingFileAppenderErrors);
	    root.addAppender(logcatAppender);
	    
	}

}

Internationalization

The internationalization is made via *.properties files. The *.properties files may be translated to Excelt files, using an open source tool: https://code.google.com/p/i18n-binder/

If you would like to insert some values into the translated strings do that as following:

locale.properties

Define the places, where the data should be inserted into the strings by inserting {i} into the strings.
i is the number of the parameter you will pass beginning with 0.

UserNameMessage={0} users with the name {1} have been found
code

Insert the data into the String at predefined places:

MessageFormat.format(Messages.UserNameMessage, "3", "Steve");

This mehtod is better than adding %s into the translations and inserting the data by doing the following, because Runtime-Exceptions will be thrown, if the string does not contains enoughh placeholders %s

UserNameMessage=%s users with the name %s have been found
String.format(Messages.UserNameMessage, "3", "Steve");

Date

Details: http://tutorials.jenkov.com/java-date-time/java-util-timezone.html

ACHTUNG:

Timezones

Java knows TimeZones.

   TimeZone utc = TimeZone.getTimeZone("UTC");
// TimeZone berlin = TimeZone.getTimeZone("Europe/Berlin");
// TimeZone cassablanca = TimeZone.getTimeZone("Africa/Casablanca");
   TimeZone local = TimeZone.getDefault();

Objects

 TimeZone utc = TimeZone.getTimeZone("UTC");
 Date barcodeDateInUTC = new Date(2014,22,05);
		
 // assume barcodeDate is in UTC
 GregorianCalendar gregorianCalendar = new GregorianCalendar();
 gregorianCalendar.setTimeZone(utc);
 gregorianCalendar.setTime(barcodeDateInUTC); 

Conversion between TimeZones

TimeZone local = TimeZone.getDefault();

// assume barcodeDate is in UTC
GregorianCalendar gregorianCalendar = new GregorianCalendar();
gregorianCalendar.setTimeZone(utc);
gregorianCalendar.setTime(barcodeDateInUTC); 

// ACHTUNG: 
// offset is given relative to the LOCAL ZONE, not to UTC.
// GMT-1 		gives an offset of -1  Convert from UTC: utc --1 
// GMT+1 		gives an offset of  1  Convert from UTC: utc - 1
// "Europe/Berlin"	gives an offset of  1. 
int offset = local.getOffset(0); 

// calendar is UTC now. Convert to European time.
gregorianCalendar.add(Calendar.MILLISECOND, -offset);
Date localTime = gregorianCalendar.getTime();

Format of Date

The Date is conveted from String and back by using DateFormat. It should by used, considering the Local formats. E.g. in Europe you display date as 24.12.2014. In USA you display date as 12.24.2014.

DateFormat dateFormat =  DateFormat.getDateInstance(DateFormat.LONG, Locale.getDefault());

DateFormat.SHORT 24.12.06 21:54
DateFormat.MEDIUM 24.12.2006 21:54:46
DateFormat.LONG 24. Dezember 2006 21:54:20 GMT+02:00
DateFormat.FULL Sonntag, 24. Dezember 2006 21.54 Uhr GMT+02:00

Bit arithmetik

Bit arithmetik in Java. Details: http://openbook.galileocomputing.de/javainsel/javainsel_18_001.html#dodtp63255d32-d0b5-4be8-9423-e891b6949017

May be used to pass settings to a method in java, if many settings are allowd in arbitrary combinations, like SWT bits in java

/**
	 * 
	 * 0  in binary format is 0000 0000 0000 0000
	 * 1  in binary format is 0000 0000 0000 0001
	 * -1 in binary format is 1111 1111 1111 1111
	 *  
	 */
	
	static final int first 	= 1 << 0; // binary 0000 0000 0000 0001
	static final int second = 1 << 1; // binary 0000 0000 0000 0010
	static final int third 	= 1 << 2; // binary 0000 0000 0000 0100
	static final int four 	= 1 << 3; // binary 0000 0000 0000 1000
	
	public static void main(String[] args) {
		
		System.out.println(isBitSet(first, first)); 		// true
		System.out.println(isBitSet(0, first));				// false
		System.out.println(isBitSet(second, first));		// false
		System.out.println(isBitSet(second|first, first));	// true
		
		System.out.println("--");	

		int bits = first|second|third;
		System.out.println(isBitSet(bits, second));			// true
		bits = unsetBit(bits, second);	
		System.out.println(isBitSet(bits, second));			// false
		
		
	}
	
	/**
	 * Checks whether the bits in mask are set inside the bits input
	 * @param bits
	 * @param mask
	 * @return
	 */
	public static boolean isBitSet(int bits, int mask){
		return (bits & mask) == mask;
	}

	/**
	 * Takes the mask, flips the bits in mask
	 * @param bits - where to flip the bits
	 * @param mask - the mask which contains the bits to flip
	 * @return
	 */
	public static int unsetBit(int bits, int mask){
		int negatedMask = ~mask;
		return (bits & negatedMask);
	}

Java VM

Following parameters are possible

C:\java -X

    -Xmixed           mixed mode execution (default)
    -Xint             interpreted mode execution only
    -Xbootclasspath:<directories and zip/jar files separated by ;>
                      set search path for bootstrap classes and resources
    -Xbootclasspath/a:<directories and zip/jar files separated by ;>
                      append to end of bootstrap class path
    -Xbootclasspath/p:<directories and zip/jar files separated by ;>
                      prepend in front of bootstrap class path
    -Xnoclassgc       disable class garbage collection
    -Xincgc           enable incremental garbage collection
    -Xloggc:<file>    log GC status to a file with time stamps
    -Xbatch           disable background compilation
    -Xms<size>        set initial Java heap size
    -Xmx<size>        set maximum Java heap size
    -Xss<size>        set java thread stack size
    -Xprof            output cpu profiling data
    -Xfuture          enable strictest checks, anticipating future default
    -Xrs              reduce use of OS signals by Java/VM (see documentation)
    -Xcheck:jni       perform additional checks for JNI functions
    -Xshare:off       do not attempt to use shared class data
    -Xshare:auto      use shared class data if possible (default)
    -Xshare:on        require using shared class data, otherwise fail.

The -X options are non-standard and subject to change without notice.

System properties

There are infos about the PC environment which may be retrieved from java:

System.getProperty("user.dir")

Key Description of Associated Value 
java.version Java Runtime Environment version 
java.vendor Java Runtime Environment vendor 
java.vendor.url Java vendor URL 
java.home Java installation directory 
java.vm.specification.version Java Virtual Machine specification version 
java.vm.specification.vendor Java Virtual Machine specification vendor 
java.vm.specification.name Java Virtual Machine specification name 
java.vm.version Java Virtual Machine implementation version 
java.vm.vendor Java Virtual Machine implementation vendor 
java.vm.name Java Virtual Machine implementation name 
java.specification.version Java Runtime Environment specification version 
java.specification.vendor Java Runtime Environment specification vendor 
java.specification.name Java Runtime Environment specification name 
java.class.version Java class format version number 
java.class.path Java class path 
java.library.path List of paths to search when loading libraries 
java.io.tmpdir Default temp file path 
java.compiler Name of JIT compiler to use 
java.ext.dirs Path of extension directory or directories 
os.name Operating system name 
os.arch Operating system architecture 
os.version Operating system version 
file.separator File separator ("/" on UNIX) 
path.separator Path separator (":" on UNIX) 
line.separator Line separator ("\n" on UNIX) 
user.name User's account name 
user.home User's home directory 
user.dir User's current working directory 

Reflection

     public static void initAllFieldsWithDefaults(Object modelToInit, Map<Class<?>, Object> defaultValues) {

        int defaultInt = Integer.valueOf(defaultValues.get(Integer.class).toString());
        double defaultDouble = Double.valueOf(defaultValues.get(Double.class).toString());
        float defaultFloat = Float.valueOf(defaultValues.get(Float.class).toString());
        short defaultShort = Short.valueOf(defaultValues.get(Short.class).toString());
        String defaultString = defaultValues.get(String.class).toString();
        Date defaultDate = (Date) defaultValues.get(Date.class);

        for (Field f : getAllNonStaticFieldsInHierarchy(modelToInit.getClass())) {
            Class<?> type = f.getType();
            String name = f.getName();
            try {
                if (type == Integer.class) {
                    f.set(modelToInit, new Integer(defaultInt));

                } else if (type == int.class) {
                    f.setInt(modelToInit, defaultInt);

                } else if (type == Double.class) {
                    f.set(modelToInit, new Double(defaultDouble));

                } else if (type == double.class) {
                    f.setDouble(modelToInit, defaultDouble);

                } else if (type == Float.class) {
                    f.set(modelToInit, new Float(defaultFloat));

                } else if (type == float.class) {
                    f.setFloat(modelToInit, defaultFloat);

                } else if (type == Short.class) {
                    f.set(modelToInit, new Short(defaultShort));

                } else if (type == short.class) {
                    f.setShort(modelToInit, defaultShort);

                } else if (type == String.class) {
                    f.set(modelToInit, defaultString);

                } else if (type.isInstance(Date.class)) {
                    f.set(modelToInit, defaultDate);
                }
            } catch (Exception e) {
                LOG.error("Failed to initialize model's ({}) field '{}' with type '{}' ", f.getDeclaringClass()
                        .getSimpleName(), name, type);
            }
        }

    }

Generics

PeCs - Producer Extends - Consumer super


	// OK - can hold any Function
	private Collection<? extends Function> producerExtends1(){
		return new ArrayList<UnaryOperator>();
	}
	
	/* WRONG! - ArrayList<UnaryOperator> is not a legal replacement for Collection<Function>.
	 * It is legal to try putting NonUnaryOperator into Collection<Function>.
	 * It is NOT legal to put NonUnaryOperator  into Collection<UnaryOperator>.
	 * So you can not return Collection<UnaryOperator> here.
	 */
//	private Collection<Function> producerExtends2(){
//		return new ArrayList<UnaryOperator>();
//	}
	
	
	private void producerExtends3(Collection<? extends Function> collection){
		/* Indeed it is not possible to put something into the collection, 
		 * since you do not know what is ?,
		 * in the instance of Collection.
		 * May have been anything. UnaryOperator, NonUnaryOperator.
		 * 
		 * WRONG!
		 */
//		collection.add(new ArrayList<UnaryOperator>())
	}
	
	/* OK - can put any Function in here, 
	 * because you know - collection contains ONLY some superclasses of Function.
	 * So you can put any Function in here. 
	 */
	private void consumerSuper1(Collection<? super Function> collection){
		UnaryOperator u = null;
		collection.add(u);
	}
	
	private void consumerSuper2(Collection<? super Function> collection){
		/* WRONG!
		 * You do not know which superclasses of Function the collection contains.
		 */
//		Function func = collection.iterator().next();
	}

Debugging Tools

VisualVm

VisualVm is able to connect to a Java virtual mashine and to debug it.
It is Delivered together with JDK.
..\Java\jdk1.7.0_15\bin\jvisualvm.exe

Decompiler

Procyon - a nice decompiler Luyten - a GUI for the decompiler

Luyten v0.4.8 / Procyon v0.5.32

https://github.com/deathmarine/Luyten/releases/tag/v0.4.8

Remote debugging

To debug Ant you can enable let ant wait for the debugger to attach, then you may attach to the debugger from Eclipse IDE.

To make a java application wait for debugger to attach the following JVM params have to be passed to it

-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=1044

To attach with the debugger with Eclipse IDE use the Debug COnfiguration and set the Breaking Point, to stop on an uncatched Exception

suspend=y

makes the serer stop and wait for debugger to atach.

Install on Ubuntu and switch version

sudo apt-get update
sudo apt-get install openjdk-8-jdk
sudo apt-get install openjdk-11-jdk

Then switch the JDK

sudo update-alternatives --config java

Get File as String

    private Document getStringFromFile(String aspectJsonFile) throws IOException {
        Path workDirPath = Path.of(getProjectBasePath());
        Path subPath = Path.of("src", "test", "resources", aspectJsonFile);
        final Path absPath = workDirPath.resolve(subPath);

        return Files.readString(absPath);

    }

    // returns project base path
    private static String getProjectBasePath() {
        return new File("").getAbsolutePath();
    }

JUnit 5


Hamcrest

Has matches useful for unit tests.

Set the groovy dependencies

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
    testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.8.1'

    // import here
    testImplementation 'org.hamcrest:hamcrest:2.2'
}

Now you can import “org.hamcrest”

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

import org.junit.jupiter.api.Test;

public class MyTest {

    @Test
    void testExample() {
        String value = "Hello, world!";
        
        assertThat(value, containsString("Hello"));
        assertThat(value, endsWith("!"));
        assertThat(value, is(notNullValue()));
    }
}

Text processing

Regular Expressions (java.util.regex)

When using Regex - make sure you dont introduce too greedy patterns

https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html

Boundary matchers
^	The beginning of a line
$	The end of a line
\b	A word boundary
\B	A non-word boundary
\A	The beginning of the input
\G	The end of the previous match
\Z	The end of the input but for the final terminator, if any
\z	The end of the input

Tokenize strings

Break into single words.


        String[] result = "this is a test".split("\\s");
        for (int x=0; x<result.length; x++)
            System.out.println(result[x]);

/*      this
        is
        a
        test
*/

    @Test
    void patternMatch() {
        mymatch(".*(alice|bob).*", "bob and alice like to text each other" ); // 1 - because greedy match matches the whole string
        mymatch("\\b(alice|bob)\\b", "bob and alice like to text each other" ); // 2 - ACHTUNG: escape back slashes. \b marks word boundaries
    }

    public static long mymatch(String regex, String text) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(text);

        List<MatchResult> res =  matcher
                .results()
                .toList();

        System.out.printf("%s matches %s%n", regex, res.size());
        return res.size();
    }

ReplaceAll

    @Test
    void stringReplaceAll() {
        String s = "bob and alice like to text each other";
        String john = s.replaceAll("\\b(bob)\\b", "john");
        System.out.println(john);
    }

Records

First: Java 14

    // some interface
    interface MyBarkInterface{
        default void bark(){
            System.out.println("bark bark");
        }
    }

    record MyPoint(int x, int y) implements MyBarkInterface{};

    // Cant inherit from Record - its final
    //record MyPoint2(int x, int y) extends MyPoint{};


    @Test
    void recordTest1() {
        MyPoint p = new MyPoint(1,2);

        System.out.println(p); // MyPoint[x=1, y=2]
        System.out.println(p.x()); // can access vars via methods
        System.out.println(p.x()); // can access vars via methods
        
        p.bark(); // can access hiearchy
    }